blob: 584328bd4b45485fdce7d04a5610669c8ca8987a [file] [log] [blame]
Jonathan Gordon91cb68a2007-03-01 11:14:46 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
Peter D'Hoye4d28b2f2007-03-29 22:51:03 +00008 * $Id$
Jonathan Gordon91cb68a2007-03-01 11:14:46 +00009 *
10 * Copyright (C) 2007 Jonathan Gordon
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000022#include <stdlib.h>
23#include <stdbool.h>
Thomas Martitz50a6ca32010-05-06 21:04:40 +000024#include "string-extra.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000025#include "config.h"
Jonathan Gordonb84fe022009-01-11 04:03:17 +000026#include "appevents.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000027#include "menu.h"
28#include "root_menu.h"
29#include "lang.h"
30#include "settings.h"
Jens Arnold178c5652007-04-09 13:39:37 +000031#include "screens.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000032#include "kernel.h"
33#include "debug.h"
34#include "misc.h"
35#include "rolo.h"
Jonathan Gordon5462a912007-03-01 12:35:24 +000036#include "powermgmt.h"
Jens Arnold178c5652007-04-09 13:39:37 +000037#include "power.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000038#include "talk.h"
39#include "audio.h"
Jonathan Gordon101693f2011-11-15 13:22:02 +000040#include "shortcuts.h"
Nicolas Pennequin1cf2ec32007-04-25 22:08:00 +000041
Thomas Martitz1ecb7532009-11-26 00:37:27 +000042#ifdef HAVE_HOTSWAP
43#include "storage.h"
Thomas Martitz706e6b72014-02-18 07:11:11 +010044#include "mv.h"
Thomas Martitz1ecb7532009-11-26 00:37:27 +000045#endif
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000046/* gui api */
47#include "list.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000048#include "splash.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000049#include "action.h"
50#include "yesno.h"
Jonathan Gordone385ee12008-12-31 05:59:26 +000051#include "viewport.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000052
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000053#include "tree.h"
Jonathan Gordon08575f02007-03-01 12:18:30 +000054#if CONFIG_TUNER
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000055#include "radio.h"
Jonathan Gordon08575f02007-03-01 12:18:30 +000056#endif
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000057#ifdef HAVE_RECORDING
58#include "recording.h"
59#endif
Jonathan Gordon3e7444f2009-08-03 04:43:34 +000060#include "wps.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000061#include "bookmark.h"
Dave Chapman78d29f52008-03-26 23:35:34 +000062#include "playlist.h"
Thomas Martitzc19e5362010-02-20 19:06:39 +000063#include "playlist_viewer.h"
Jonathan Gordon97a4c1e2011-07-20 14:11:15 +000064#include "playlist_catalog.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000065#include "menus/exported_menus.h"
Dan Evertonc423e872007-03-01 11:46:26 +000066#ifdef HAVE_RTC_ALARM
67#include "rtc.h"
68#endif
Steve Bavin81374892007-03-07 19:56:15 +000069#ifdef HAVE_TAGCACHE
70#include "tagcache.h"
71#endif
Tomer Shalevd7cdd082009-10-08 22:40:38 +000072#include "language.h"
Jonathan Gordond871ff82010-06-09 04:25:41 +000073#include "plugin.h"
Amaury Pouly193753a2013-11-20 16:39:42 +000074#include "disk.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000075
76struct root_items {
77 int (*function)(void* param);
78 void* param;
Jonathan Gordonf9fb4922007-04-12 15:28:51 +000079 const struct menu_item_ex *context_menu;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000080};
Thomas Martitza3f0a452009-10-16 19:14:46 +000081static int next_screen = GO_TO_ROOT; /* holding info about the upcoming screen
82 * which is the current screen for the
83 * rest of the code after load_screen
84 * is called */
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000085static int last_screen = GO_TO_ROOT; /* unfortunatly needed so we can resume
86 or goto current track based on previous
87 screen */
Jonathan Gordon3ac7af92012-12-16 14:26:03 +110088
Thomas Martitz35b4ba82014-04-15 09:34:22 +020089static int previous_music = GO_TO_WPS; /* Toggles behavior of the return-to
90 * playback-button depending
91 * on FM radio */
92
93#if (CONFIG_TUNER)
94static void rootmenu_start_playback_callback(unsigned short id, void *param)
95{
96 (void) id; (void) param;
97 /* Cancel FM radio selection as previous music. For cases where we start
98 playback without going to the WPS, such as playlist insert or
99 playlist catalog. */
100 previous_music = GO_TO_WPS;
101}
102#endif
Thomas Martitz9072a452009-10-16 19:14:33 +0000103
Jonathan Gordonb84fe022009-01-11 04:03:17 +0000104static char current_track_path[MAX_PATH];
Thomas Martitz470989b2014-03-14 23:15:16 +0100105static void rootmenu_track_changed_callback(unsigned short id, void* param)
Jonathan Gordonb84fe022009-01-11 04:03:17 +0000106{
Thomas Martitz470989b2014-03-14 23:15:16 +0100107 (void)id;
Michael Sevakis023f6b62013-07-12 12:06:38 -0400108 struct mp3entry *id3 = ((struct track_event *)param)->id3;
Nils Wallménius3d4701a2009-07-14 13:57:45 +0000109 strlcpy(current_track_path, id3->path, MAX_PATH);
Jonathan Gordonb84fe022009-01-11 04:03:17 +0000110}
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000111static int browser(void* param)
112{
113 int ret_val;
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000114#ifdef HAVE_TAGCACHE
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000115 struct tree_context* tc = tree_get_context();
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000116#endif
Teruaki Kawashima08af5d82010-12-14 13:37:58 +0000117 struct browse_context browse;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000118 int filter = SHOW_SUPPORTED;
119 char folder[MAX_PATH] = "/";
120 /* stuff needed to remember position in file browser */
121 static char last_folder[MAX_PATH] = "/";
122 /* and stuff for the database browser */
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000123#ifdef HAVE_TAGCACHE
Jonathan Gordonfd30be52007-03-10 12:51:08 +0000124 static int last_db_dirlevel = 0, last_db_selection = 0;
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000125#endif
Teruaki Kawashima08af5d82010-12-14 13:37:58 +0000126
Jonathan Gordon08575f02007-03-01 12:18:30 +0000127 switch ((intptr_t)param)
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000128 {
129 case GO_TO_FILEBROWSER:
130 filter = global_settings.dirfilter;
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100131 if (global_settings.browse_current &&
Steve Bavin6cc38952008-02-09 15:20:15 +0000132 last_screen == GO_TO_WPS &&
Jonathan Gordonb84fe022009-01-11 04:03:17 +0000133 current_track_path[0])
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000134 {
Jonathan Gordonb84fe022009-01-11 04:03:17 +0000135 strcpy(folder, current_track_path);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000136 }
Jonathan Gordonefbcece2010-10-04 10:34:38 +0000137 else if (!strcmp(last_folder, "/"))
138 {
139 strcpy(folder, global_settings.start_directory);
140 }
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000141 else
Thomas Martitz1ecb7532009-11-26 00:37:27 +0000142 {
143#ifdef HAVE_HOTSWAP
144 bool in_hotswap = false;
145 /* handle entering an ejected drive */
146 int i;
147 for (i = 0; i < NUM_VOLUMES; i++)
148 {
Michael Sevakis7d1a47c2013-08-05 22:02:45 -0400149 char vol_string[VOL_MAX_LEN + 1];
Amaury Pouly193753a2013-11-20 16:39:42 +0000150 if (!volume_removable(i))
Thomas Martitz1ecb7532009-11-26 00:37:27 +0000151 continue;
Michael Sevakis7d1a47c2013-08-05 22:02:45 -0400152 get_volume_name(i, vol_string);
Thomas Martitz1ecb7532009-11-26 00:37:27 +0000153 /* test whether we would browse the external card */
Amaury Pouly193753a2013-11-20 16:39:42 +0000154 if (!volume_present(i) &&
Thomas Martitz1ecb7532009-11-26 00:37:27 +0000155 (strstr(last_folder, vol_string)
156#ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
157 || (i == 0)
158#endif
159 ))
160 { /* leave folder as "/" to avoid crash when trying
161 * to access an ejected drive */
162 strcpy(folder, "/");
163 in_hotswap = true;
164 break;
165 }
166 }
Jonathan Gordonefbcece2010-10-04 10:34:38 +0000167 if (!in_hotswap)
Thomas Martitz1ecb7532009-11-26 00:37:27 +0000168#endif
Jonathan Gordonefbcece2010-10-04 10:34:38 +0000169 strcpy(folder, last_folder);
Thomas Martitz1ecb7532009-11-26 00:37:27 +0000170 }
Jonathan Gordonb58d3652011-06-01 14:41:49 +0000171 push_current_activity(ACTIVITY_FILEBROWSER);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000172 break;
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000173#ifdef HAVE_TAGCACHE
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000174 case GO_TO_DBBROWSER:
Steve Bavin81374892007-03-07 19:56:15 +0000175 if (!tagcache_is_usable())
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000176 {
Steve Bavin149bc032007-03-08 08:20:30 +0000177 bool reinit_attempted = false;
Steve Bavin81374892007-03-07 19:56:15 +0000178
179 /* Now display progress until it's ready or the user exits */
180 while(!tagcache_is_usable())
181 {
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100182 struct tagcache_stat *stat = tagcache_get_stat();
183
Steve Bavin149bc032007-03-08 08:20:30 +0000184 /* Allow user to exit */
185 if (action_userabort(HZ/2))
186 break;
Steve Bavin81374892007-03-07 19:56:15 +0000187
188 /* Maybe just needs to reboot due to delayed commit */
189 if (stat->commit_delayed)
190 {
Nils Wallménius01729e72008-08-15 08:27:39 +0000191 splash(HZ*2, ID2P(LANG_PLEASE_REBOOT));
Steve Bavin81374892007-03-07 19:56:15 +0000192 break;
193 }
194
Steve Bavin149bc032007-03-08 08:20:30 +0000195 /* Check if ready status is known */
196 if (!stat->readyvalid)
197 {
Solomon Peachyc46147c2019-08-07 12:45:34 -0400198 splash(0, ID2P(LANG_TAGCACHE_BUSY));
Steve Bavin149bc032007-03-08 08:20:30 +0000199 continue;
200 }
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100201
Steve Bavin149bc032007-03-08 08:20:30 +0000202 /* Re-init if required */
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100203 if (!reinit_attempted && !stat->ready &&
Steve Bavin149bc032007-03-08 08:20:30 +0000204 stat->processed_entries == 0 && stat->commit_step == 0)
205 {
206 /* Prompt the user */
207 reinit_attempted = true;
Nils Wallménius33c44462008-04-26 09:30:24 +0000208 static const char *lines[]={
209 ID2P(LANG_TAGCACHE_BUSY), ID2P(LANG_TAGCACHE_FORCE_UPDATE)};
210 static const struct text_message message={lines, 2};
Steve Bavin149bc032007-03-08 08:20:30 +0000211 if(gui_syncyesno_run(&message, NULL, NULL) == YESNO_NO)
212 break;
Steve Bavin149bc032007-03-08 08:20:30 +0000213 FOR_NB_SCREENS(i)
214 screens[i].clear_display();
215
216 /* Start initialisation */
217 tagcache_rebuild();
218 }
219
Steve Bavin81374892007-03-07 19:56:15 +0000220 /* Display building progress */
Nils Wallménius5b769362007-08-06 13:08:36 +0000221 static long talked_tick = 0;
Steve Bavin32a95752007-10-19 15:31:42 +0000222 if(global_settings.talk_menu &&
Nils Wallménius5b769362007-08-06 13:08:36 +0000223 (talked_tick == 0
224 || TIME_AFTER(current_tick, talked_tick+7*HZ)))
225 {
226 talked_tick = current_tick;
227 if (stat->commit_step > 0)
228 {
229 talk_id(LANG_TAGCACHE_INIT, false);
230 talk_number(stat->commit_step, true);
231 talk_id(VOICE_OF, true);
232 talk_number(tagcache_get_max_commit_step(), true);
233 } else if(stat->processed_entries)
234 {
235 talk_number(stat->processed_entries, false);
236 talk_id(LANG_BUILDING_DATABASE, true);
237 }
238 }
Steve Bavin81374892007-03-07 19:56:15 +0000239 if (stat->commit_step > 0)
240 {
Tomer Shalevd7cdd082009-10-08 22:40:38 +0000241 if (lang_is_rtl())
242 {
243 splashf(0, "[%d/%d] %s", stat->commit_step,
244 tagcache_get_max_commit_step(),
245 str(LANG_TAGCACHE_INIT));
246 }
247 else
248 {
249 splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT),
250 stat->commit_step,
251 tagcache_get_max_commit_step());
252 }
Steve Bavin81374892007-03-07 19:56:15 +0000253 }
254 else
255 {
Nils Wallménius01729e72008-08-15 08:27:39 +0000256 splashf(0, str(LANG_BUILDING_DATABASE),
257 stat->processed_entries);
Steve Bavin81374892007-03-07 19:56:15 +0000258 }
Steve Bavin81374892007-03-07 19:56:15 +0000259 }
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000260 }
Steve Bavin81374892007-03-07 19:56:15 +0000261 if (!tagcache_is_usable())
262 return GO_TO_PREVIOUS;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000263 filter = SHOW_ID3DB;
264 tc->dirlevel = last_db_dirlevel;
Jonathan Gordonfd30be52007-03-10 12:51:08 +0000265 tc->selected_item = last_db_selection;
Jonathan Gordonb58d3652011-06-01 14:41:49 +0000266 push_current_activity(ACTIVITY_DATABASEBROWSER);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000267 break;
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000268#endif
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000269 }
Teruaki Kawashima08af5d82010-12-14 13:37:58 +0000270
271 browse_context_init(&browse, filter, 0, NULL, NOICON, folder, NULL);
272 ret_val = rockbox_browse(&browse);
Jonathan Gordonb58d3652011-06-01 14:41:49 +0000273 pop_current_activity();
Jonathan Gordon08575f02007-03-01 12:18:30 +0000274 switch ((intptr_t)param)
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000275 {
276 case GO_TO_FILEBROWSER:
Jonathan Gordonefbcece2010-10-04 10:34:38 +0000277 if (!get_current_file(last_folder, MAX_PATH) ||
Teruaki Kawashima36cd7202010-10-25 13:55:34 +0000278 (!strchr(&last_folder[1], '/') &&
279 global_settings.start_directory[1] != '\0'))
Thomas Martitz79798ff2010-08-27 10:33:09 +0000280 {
281 last_folder[0] = '/';
282 last_folder[1] = '\0';
283 }
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000284 break;
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000285#ifdef HAVE_TAGCACHE
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000286 case GO_TO_DBBROWSER:
287 last_db_dirlevel = tc->dirlevel;
Jonathan Gordonfd30be52007-03-10 12:51:08 +0000288 last_db_selection = tc->selected_item;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000289 break;
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000290#endif
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000291 }
292 return ret_val;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000293}
Thomas Martitz89a4cf22011-01-29 01:01:12 +0000294
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000295#ifdef HAVE_RECORDING
296static int recscrn(void* param)
297{
298 (void)param;
299 recording_screen(false);
300 return GO_TO_ROOT;
301}
302#endif
303static int wpsscrn(void* param)
304{
305 int ret_val = GO_TO_PREVIOUS;
306 (void)param;
Jonathan Gordonb58d3652011-06-01 14:41:49 +0000307 push_current_activity(ACTIVITY_WPS);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000308 if (audio_status())
309 {
Steve Bavin32a95752007-10-19 15:31:42 +0000310 talk_shutup();
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000311 ret_val = gui_wps_show();
312 }
313 else if ( global_status.resume_index != -1 )
314 {
Richard Quirk212e7802012-12-09 21:04:17 +0100315 DEBUGF("Resume index %X crc32 %lX offset %lX\n",
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000316 global_status.resume_index,
Richard Quirk212e7802012-12-09 21:04:17 +0100317 (unsigned long)global_status.resume_crc32,
Jens Arnoldbd5c0ad2007-03-17 10:50:58 +0000318 (unsigned long)global_status.resume_offset);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000319 if (playlist_resume() != -1)
320 {
Richard Quirk212e7802012-12-09 21:04:17 +0100321 playlist_resume_track(global_status.resume_index,
322 global_status.resume_crc32,
Michael Sevakis31b71222013-07-14 07:59:39 -0400323 global_status.resume_elapsed,
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000324 global_status.resume_offset);
325 ret_val = gui_wps_show();
326 }
327 }
Jens Arnoldf68362a2007-03-17 09:54:28 +0000328 else
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000329 {
Nils Wallménius01729e72008-08-15 08:27:39 +0000330 splash(HZ*2, ID2P(LANG_NOTHING_TO_RESUME));
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000331 }
Jonathan Gordonb58d3652011-06-01 14:41:49 +0000332 pop_current_activity();
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000333 return ret_val;
334}
335#if CONFIG_TUNER
336static int radio(void* param)
337{
338 (void)param;
339 radio_screen();
340 return GO_TO_ROOT;
341}
342#endif
343
Thomas Martitz89a4cf22011-01-29 01:01:12 +0000344static int miscscrn(void * param)
345{
346 const struct menu_item_ex *menu = (const struct menu_item_ex*)param;
Thomas Martitzf7da3332011-01-29 11:50:38 +0000347 int result = do_menu(menu, NULL, NULL, false);
348 switch (result)
Thomas Martitz89a4cf22011-01-29 01:01:12 +0000349 {
350 case GO_TO_PLAYLIST_VIEWER:
Thomas Martitzcbb68d42011-02-28 14:38:18 +0000351 case GO_TO_WPS:
352 return result;
Thomas Martitz89a4cf22011-01-29 01:01:12 +0000353 default:
354 return GO_TO_ROOT;
355 }
356}
Jonathan Gordon97a4c1e2011-07-20 14:11:15 +0000357
358
359static int playlist_view_catalog(void * param)
360{
361 /* kludge untill catalog_view_playlists() returns something useful */
362 int old_playstatus = audio_status();
363 (void)param;
364 push_current_activity(ACTIVITY_PLAYLISTBROWSER);
365 catalog_view_playlists();
366 pop_current_activity();
367 if (!old_playstatus && audio_status())
368 return GO_TO_WPS;
369 return GO_TO_PREVIOUS;
370}
371
Thomas Martitzc19e5362010-02-20 19:06:39 +0000372static int playlist_view(void * param)
373{
374 (void)param;
Jonathan Gordon038fc8a2011-06-13 07:33:20 +0000375 int val;
376
377 push_current_activity(ACTIVITY_PLAYLISTVIEWER);
378 val = playlist_viewer();
379 pop_current_activity();
380 switch (val)
Thomas Martitzc19e5362010-02-20 19:06:39 +0000381 {
382 case PLAYLIST_VIEWER_MAINMENU:
383 case PLAYLIST_VIEWER_USB:
384 return GO_TO_ROOT;
385 case PLAYLIST_VIEWER_OK:
386 return GO_TO_PREVIOUS;
387 }
388 return GO_TO_PREVIOUS;
389}
390
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000391static int load_bmarks(void* param)
392{
393 (void)param;
Stéphane Doyon84ed3fd2007-10-12 04:10:08 +0000394 if(bookmark_mrb_load())
395 return GO_TO_WPS;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000396 return GO_TO_PREVIOUS;
397}
Teruaki Kawashima08af5d82010-12-14 13:37:58 +0000398
Jonathan Gordonf9fb4922007-04-12 15:28:51 +0000399/* These are all static const'd from apps/menus/ *.c
400 so little hack so we can use them */
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100401extern struct menu_item_ex
402 file_menu,
Brandon Lowb44b6602007-04-18 19:46:34 +0000403#ifdef HAVE_TAGCACHE
Jonathan Gordonf9fb4922007-04-12 15:28:51 +0000404 tagcache_menu,
Brandon Lowb44b6602007-04-18 19:46:34 +0000405#endif
Thomas Martitz89a4cf22011-01-29 01:01:12 +0000406 main_menu_,
Jonathan Gordonf9fb4922007-04-12 15:28:51 +0000407 manage_settings,
Thomas Martitzf7da3332011-01-29 11:50:38 +0000408 plugin_menu,
Thomas Martitz89a4cf22011-01-29 01:01:12 +0000409 playlist_options,
410 info_menu,
Jonathan Gordonf9fb4922007-04-12 15:28:51 +0000411 system_menu;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000412static const struct root_items items[] = {
Jonathan Gordonf9fb4922007-04-12 15:28:51 +0000413 [GO_TO_FILEBROWSER] = { browser, (void*)GO_TO_FILEBROWSER, &file_menu},
Brandon Lowb44b6602007-04-18 19:46:34 +0000414#ifdef HAVE_TAGCACHE
Jonathan Gordonf9fb4922007-04-12 15:28:51 +0000415 [GO_TO_DBBROWSER] = { browser, (void*)GO_TO_DBBROWSER, &tagcache_menu },
Brandon Lowb44b6602007-04-18 19:46:34 +0000416#endif
Steve Bavin5f8bd632008-05-22 08:02:48 +0000417 [GO_TO_WPS] = { wpsscrn, NULL, &playback_settings },
Thomas Martitz89a4cf22011-01-29 01:01:12 +0000418 [GO_TO_MAINMENU] = { miscscrn, (struct menu_item_ex*)&main_menu_,
419 &manage_settings },
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100420
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000421#ifdef HAVE_RECORDING
Peter D'Hoye9337efd2007-07-03 18:31:13 +0000422 [GO_TO_RECSCREEN] = { recscrn, NULL, &recording_settings_menu },
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000423#endif
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100424
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000425#if CONFIG_TUNER
Peter D'Hoye9337efd2007-07-03 18:31:13 +0000426 [GO_TO_FM] = { radio, NULL, &radio_settings_menu },
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000427#endif
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100428
429 [GO_TO_RECENTBMARKS] = { load_bmarks, NULL, &bookmark_settings_menu },
Thomas Martitzf7da3332011-01-29 11:50:38 +0000430 [GO_TO_BROWSEPLUGINS] = { miscscrn, &plugin_menu, NULL },
Jonathan Gordon97a4c1e2011-07-20 14:11:15 +0000431 [GO_TO_PLAYLISTS_SCREEN] = { playlist_view_catalog, NULL,
432 &playlist_options },
433 [GO_TO_PLAYLIST_VIEWER] = { playlist_view, NULL, &playlist_options },
Thomas Martitz89a4cf22011-01-29 01:01:12 +0000434 [GO_TO_SYSTEM_SCREEN] = { miscscrn, &info_menu, &system_menu },
Jonathan Gordon101693f2011-11-15 13:22:02 +0000435 [GO_TO_SHORTCUTMENU] = { do_shortcut_menu, NULL, NULL },
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100436
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000437};
438static const int nb_items = sizeof(items)/sizeof(*items);
439
Bertrik Sikkendff382c2008-07-16 12:10:49 +0000440static int item_callback(int action, const struct menu_item_ex *this_item) ;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000441
Jonathan Gordon101693f2011-11-15 13:22:02 +0000442MENUITEM_RETURNVALUE(shortcut_menu, ID2P(LANG_SHORTCUTS), GO_TO_SHORTCUTMENU,
443 NULL, Icon_Bookmark);
444
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000445MENUITEM_RETURNVALUE(file_browser, ID2P(LANG_DIR_BROWSER), GO_TO_FILEBROWSER,
Jonathan Gordon02a87172007-03-03 13:52:14 +0000446 NULL, Icon_file_view_menu);
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000447#ifdef HAVE_TAGCACHE
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100448MENUITEM_RETURNVALUE(db_browser, ID2P(LANG_TAGCACHE), GO_TO_DBBROWSER,
Jonathan Gordon02a87172007-03-03 13:52:14 +0000449 NULL, Icon_Audio);
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000450#endif
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100451MENUITEM_RETURNVALUE(rocks_browser, ID2P(LANG_PLUGINS), GO_TO_BROWSEPLUGINS,
Jonathan Gordon02a87172007-03-03 13:52:14 +0000452 NULL, Icon_Plugin);
Jonathan Gordon97a4c1e2011-07-20 14:11:15 +0000453
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100454MENUITEM_RETURNVALUE(playlist_browser, ID2P(LANG_CATALOG), GO_TO_PLAYLIST_VIEWER,
Jonathan Gordon97a4c1e2011-07-20 14:11:15 +0000455 NULL, Icon_Playlist);
456
William Wilgus10e5e562019-09-20 03:07:29 -0500457static char *get_wps_item_name(int selected_item, void * data,
458 char *buffer, size_t buffer_len)
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000459{
William Wilgus10e5e562019-09-20 03:07:29 -0500460 (void)selected_item; (void)data; (void)buffer; (void)buffer_len;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000461 if (audio_status())
Linus Nielsen Feltzing298c2bb2007-03-05 00:32:33 +0000462 return ID2P(LANG_NOW_PLAYING);
463 return ID2P(LANG_RESUME_PLAYBACK);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000464}
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100465MENUITEM_RETURNVALUE_DYNTEXT(wps_item, GO_TO_WPS, NULL, get_wps_item_name,
Stéphane Doyon5acf0912007-10-09 03:48:56 +0000466 NULL, NULL, Icon_Playback_menu);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000467#ifdef HAVE_RECORDING
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100468MENUITEM_RETURNVALUE(rec, ID2P(LANG_RECORDING), GO_TO_RECSCREEN,
Jonathan Gordon02a87172007-03-03 13:52:14 +0000469 NULL, Icon_Recording);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000470#endif
471#if CONFIG_TUNER
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100472MENUITEM_RETURNVALUE(fm, ID2P(LANG_FM_RADIO), GO_TO_FM,
Jonathan Gordon02a87172007-03-03 13:52:14 +0000473 item_callback, Icon_Radio_screen);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000474#endif
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100475MENUITEM_RETURNVALUE(menu_, ID2P(LANG_SETTINGS), GO_TO_MAINMENU,
Jonathan Gordon02a87172007-03-03 13:52:14 +0000476 NULL, Icon_Submenu_Entered);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000477MENUITEM_RETURNVALUE(bookmarks, ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS),
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100478 GO_TO_RECENTBMARKS, item_callback,
Jonathan Gordon02a87172007-03-03 13:52:14 +0000479 Icon_Bookmark);
Jonathan Gordon97a4c1e2011-07-20 14:11:15 +0000480MENUITEM_RETURNVALUE(playlists, ID2P(LANG_CATALOG), GO_TO_PLAYLISTS_SCREEN,
Thomas Martitz89a4cf22011-01-29 01:01:12 +0000481 NULL, Icon_Playlist);
482MENUITEM_RETURNVALUE(system_menu_, ID2P(LANG_SYSTEM), GO_TO_SYSTEM_SCREEN,
483 NULL, Icon_System_menu);
484
Dave Chapman224c8262011-02-28 12:14:34 +0000485#if CONFIG_KEYPAD == PLAYER_PAD
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000486static int do_shutdown(void)
487{
Jens Arnold5764ff52007-04-09 13:54:38 +0000488#if CONFIG_CHARGING
Jens Arnold178c5652007-04-09 13:39:37 +0000489 if (charger_inserted())
490 charging_splash();
491 else
Jens Arnold5764ff52007-04-09 13:54:38 +0000492#endif
Jens Arnold178c5652007-04-09 13:39:37 +0000493 sys_poweroff();
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000494 return 0;
495}
Jonathan Gordondaf66942007-03-17 12:33:34 +0000496MENUITEM_FUNCTION(do_shutdown_item, 0, ID2P(LANG_SHUTDOWN),
Jonathan Gordon458648b2007-03-18 07:25:01 +0000497 do_shutdown, NULL, NULL, Icon_NOICON);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000498#endif
Jonathan Gordon13412f62012-02-09 21:21:40 +1100499
500struct menu_item_ex root_menu_;
501static struct menu_callback_with_desc root_menu_desc = {
502 item_callback, ID2P(LANG_ROCKBOX_TITLE), Icon_Rockbox };
Jonathan Gordon6dbfd442014-02-13 22:01:13 +1100503
Jonathan Gordon13412f62012-02-09 21:21:40 +1100504static struct menu_table menu_table[] = {
505 /* Order here represents the default ordering */
506 { "bookmarks", &bookmarks },
507 { "files", &file_browser },
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000508#ifdef HAVE_TAGCACHE
Jonathan Gordon13412f62012-02-09 21:21:40 +1100509 { "database", &db_browser },
Jonathan Gordon798ddf22007-03-07 04:36:02 +0000510#endif
Jonathan Gordon13412f62012-02-09 21:21:40 +1100511 { "wps", &wps_item },
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100512 { "settings", &menu_ },
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000513#ifdef HAVE_RECORDING
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100514 { "recording", &rec },
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000515#endif
516#if CONFIG_TUNER
Jonathan Gordon13412f62012-02-09 21:21:40 +1100517 { "radio", &fm },
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000518#endif
Jonathan Gordon13412f62012-02-09 21:21:40 +1100519 { "playlists", &playlists },
520 { "plugins", &rocks_browser },
521 { "system_menu", &system_menu_ },
Dave Chapman0269b272011-02-28 18:21:00 +0000522#if CONFIG_KEYPAD == PLAYER_PAD
Jonathan Gordon13412f62012-02-09 21:21:40 +1100523 { "shutdown", &do_shutdown_item },
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000524#endif
Jonathan Gordon13412f62012-02-09 21:21:40 +1100525 { "shortcuts", &shortcut_menu },
526};
527#define MAX_MENU_ITEMS (sizeof(menu_table) / sizeof(struct menu_table))
528static struct menu_item_ex *root_menu__[MAX_MENU_ITEMS];
529
Jonathan Gordon6dbfd442014-02-13 22:01:13 +1100530struct menu_table *root_menu_get_options(int *nb_options)
531{
532 *nb_options = MAX_MENU_ITEMS;
533
534 return menu_table;
535}
536
Jonathan Gordon13412f62012-02-09 21:21:40 +1100537void root_menu_load_from_cfg(void* setting, char *value)
538{
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100539 char *next = value, *start, *end;
Jonathan Gordon13412f62012-02-09 21:21:40 +1100540 unsigned int menu_item_count = 0, i;
541 bool main_menu_added = false;
542
Jonathan Gordon9f48f5f2012-02-27 09:34:37 +1100543 if (*value == '-')
544 {
545 root_menu_set_default(setting, NULL);
546 return;
547 }
Jonathan Gordon13412f62012-02-09 21:21:40 +1100548 root_menu_.flags = MENU_HAS_DESC | MT_MENU;
549 root_menu_.submenus = (const struct menu_item_ex **)&root_menu__;
550 root_menu_.callback_and_desc = &root_menu_desc;
551
552 while (next && menu_item_count < MAX_MENU_ITEMS)
553 {
554 start = next;
555 next = strchr(next, ',');
556 if (next)
557 {
558 *next = '\0';
559 next++;
560 }
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100561 start = skip_whitespace(start);
562 if ((end = strchr(start, ' ')))
563 *end = '\0';
Jonathan Gordon13412f62012-02-09 21:21:40 +1100564 for (i=0; i<MAX_MENU_ITEMS; i++)
565 {
566 if (*start && !strcmp(start, menu_table[i].string))
567 {
568 root_menu__[menu_item_count++] = (struct menu_item_ex *)menu_table[i].item;
569 if (menu_table[i].item == &menu_)
570 main_menu_added = true;
571 break;
572 }
573 }
574 }
575 if (!main_menu_added)
576 root_menu__[menu_item_count++] = (struct menu_item_ex *)&menu_;
577 root_menu_.flags |= MENU_ITEM_COUNT(menu_item_count);
Alexander Levin7676dae2012-03-02 20:33:13 +0100578 *(bool*)setting = true;
Jonathan Gordon13412f62012-02-09 21:21:40 +1100579}
580
581char* root_menu_write_to_cfg(void* setting, char*buf, int buf_len)
582{
583 (void)setting;
584 unsigned i, written, j;
585 for (i = 0; i < MENU_GET_COUNT(root_menu_.flags); i++)
586 {
587 for (j=0; j<MAX_MENU_ITEMS; j++)
588 {
589 if (menu_table[j].item == root_menu__[i])
590 {
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100591 written = snprintf(buf, buf_len, "%s, ", menu_table[j].string);
Jonathan Gordon13412f62012-02-09 21:21:40 +1100592 buf_len -= written;
593 buf += written;
594 break;
595 }
596 }
597 }
598 return buf;
599}
600
601void root_menu_set_default(void* setting, void* defaultval)
602{
603 unsigned i;
604 (void)defaultval;
605
606 root_menu_.flags = MENU_HAS_DESC | MT_MENU;
607 root_menu_.submenus = (const struct menu_item_ex **)&root_menu__;
608 root_menu_.callback_and_desc = &root_menu_desc;
609
610 for (i=0; i<MAX_MENU_ITEMS; i++)
611 {
612 root_menu__[i] = (struct menu_item_ex *)menu_table[i].item;
613 }
614 root_menu_.flags |= MENU_ITEM_COUNT(MAX_MENU_ITEMS);
Alexander Levin7676dae2012-03-02 20:33:13 +0100615 *(bool*)setting = false;
Jonathan Gordon13412f62012-02-09 21:21:40 +1100616}
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100617
Jonathan Gordon13412f62012-02-09 21:21:40 +1100618bool root_menu_is_changed(void* setting, void* defaultval)
619{
620 (void)defaultval;
Alexander Levin7676dae2012-03-02 20:33:13 +0100621 return *(bool*)setting;
Jonathan Gordon13412f62012-02-09 21:21:40 +1100622}
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000623
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100624static int item_callback(int action, const struct menu_item_ex *this_item)
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000625{
626 switch (action)
627 {
Jonathan Gordon411f3e22007-07-11 02:22:03 +0000628 case ACTION_TREE_STOP:
629 return ACTION_REDRAW;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000630 case ACTION_REQUEST_MENUITEM:
631#if CONFIG_TUNER
632 if (this_item == &fm)
633 {
634 if (radio_hardware_present() == 0)
635 return ACTION_EXIT_MENUITEM;
636 }
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100637 else
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000638#endif
639 if (this_item == &bookmarks)
640 {
641 if (global_settings.usemrb == 0)
642 return ACTION_EXIT_MENUITEM;
643 }
644 break;
645 }
646 return action;
647}
Jonathan Gordon6bb473d2007-03-05 13:36:00 +0000648static int get_selection(int last_screen)
649{
Thomas Martitz16a64532009-08-03 01:42:08 +0000650 int i;
651 int len = ARRAYLEN(root_menu__);
652 for(i=0; i < len; i++)
Jonathan Gordon6bb473d2007-03-05 13:36:00 +0000653 {
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100654 if (((root_menu__[i]->flags&MENU_TYPE_MASK) == MT_RETURN_VALUE) &&
Jonathan Gordon6bb473d2007-03-05 13:36:00 +0000655 (root_menu__[i]->value == last_screen))
656 {
657 return i;
658 }
659 }
660 return 0;
661}
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000662
Jonathan Gordon678705c2007-03-29 14:19:28 +0000663static inline int load_screen(int screen)
664{
665 /* set the global_status.last_screen before entering,
666 if we dont we will always return to the wrong screen on boot */
667 int old_previous = last_screen;
668 int ret_val;
Jonathan Gordonb58d3652011-06-01 14:41:49 +0000669 enum current_activity activity = ACTIVITY_UNKNOWN;
Jonathan Gordon678705c2007-03-29 14:19:28 +0000670 if (screen <= GO_TO_ROOT)
671 return screen;
672 if (screen == old_previous)
673 old_previous = GO_TO_ROOT;
674 global_status.last_screen = (char)screen;
675 status_save();
Jonathan Gordonb58d3652011-06-01 14:41:49 +0000676
677 if (screen == GO_TO_BROWSEPLUGINS)
678 activity = ACTIVITY_PLUGINBROWSER;
679 else if (screen == GO_TO_MAINMENU)
680 activity = ACTIVITY_SETTINGS;
Jonathan Gordon835683b2011-08-07 08:39:56 +0000681 else if (screen == GO_TO_SYSTEM_SCREEN)
682 activity = ACTIVITY_SYSTEMSCREEN;
Jonathan Gordonb58d3652011-06-01 14:41:49 +0000683
684 if (activity != ACTIVITY_UNKNOWN)
685 push_current_activity(activity);
686
Jonathan Gordon678705c2007-03-29 14:19:28 +0000687 ret_val = items[screen].function(items[screen].param);
Jonathan Gordonb58d3652011-06-01 14:41:49 +0000688
689 if (activity != ACTIVITY_UNKNOWN)
690 pop_current_activity();
691
Robert Kukla1f337352007-03-31 21:59:57 +0000692 last_screen = screen;
Jonathan Gordon678705c2007-03-29 14:19:28 +0000693 if (ret_val == GO_TO_PREVIOUS)
694 last_screen = old_previous;
695 return ret_val;
696}
Jonathan Gordonf9fb4922007-04-12 15:28:51 +0000697static int load_context_screen(int selection)
698{
699 const struct menu_item_ex *context_menu = NULL;
Jonathan Gordon835683b2011-08-07 08:39:56 +0000700 int retval = GO_TO_PREVIOUS;
701 push_current_activity(ACTIVITY_CONTEXTMENU);
Jonathan Gordon680acbf2007-04-25 10:41:17 +0000702 if ((root_menu__[selection]->flags&MENU_TYPE_MASK) == MT_RETURN_VALUE)
Jonathan Gordonf9fb4922007-04-12 15:28:51 +0000703 {
704 int item = root_menu__[selection]->value;
705 context_menu = items[item].context_menu;
706 }
707 /* special cases */
708 else if (root_menu__[selection] == &info_menu)
709 {
710 context_menu = &system_menu;
711 }
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100712
Jonathan Gordonf9fb4922007-04-12 15:28:51 +0000713 if (context_menu)
Jonathan Gordon835683b2011-08-07 08:39:56 +0000714 retval = do_menu(context_menu, NULL, NULL, false);
715 pop_current_activity();
716 return retval;
Jonathan Gordonf9fb4922007-04-12 15:28:51 +0000717}
Stéphane Doyon6d081162007-10-12 04:20:20 +0000718
Jonathan Gordon10e24d22010-06-09 08:51:29 +0000719#ifdef HAVE_PICTUREFLOW_INTEGRATION
Jonathan Gordond871ff82010-06-09 04:25:41 +0000720static int load_plugin_screen(char *plug_path)
721{
722 int ret_val;
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100723 int old_previous = last_screen;
Jonathan Gordond871ff82010-06-09 04:25:41 +0000724 last_screen = next_screen;
725 global_status.last_screen = (char)next_screen;
726 status_save();
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100727
Rafaël Carré21c7b9d2010-09-01 14:12:14 +0000728 switch (plugin_load(plug_path, NULL))
729 {
730 case PLUGIN_GOTO_WPS:
731 ret_val = GO_TO_WPS;
732 break;
733 case PLUGIN_OK:
Jonathan Gordonc92b2cc2010-06-09 09:41:16 +0000734 ret_val = audio_status() ? GO_TO_PREVIOUS : GO_TO_ROOT;
Rafaël Carré21c7b9d2010-09-01 14:12:14 +0000735 break;
736 default:
737 ret_val = GO_TO_PREVIOUS;
738 break;
739 }
740
Jonathan Gordond871ff82010-06-09 04:25:41 +0000741 if (ret_val == GO_TO_PREVIOUS)
742 last_screen = (old_previous == next_screen) ? GO_TO_ROOT : old_previous;
743 return ret_val;
744}
Solomon Peachyc46147c2019-08-07 12:45:34 -0400745
746static bool check_database(void)
747{
748 bool needwarn = true;
749 while ( !tagcache_is_usable() )
750 {
751 if (needwarn)
752 splash(0, ID2P(LANG_TAGCACHE_BUSY));
753 if ( action_userabort(HZ/5) )
754 return false;
755 needwarn = false;
756 }
757 return true;
758}
Jonathan Gordond871ff82010-06-09 04:25:41 +0000759#endif
760
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000761void root_menu(void)
762{
763 int previous_browser = GO_TO_FILEBROWSER;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000764 int selected = 0;
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100765
Jonathan Gordonb58d3652011-06-01 14:41:49 +0000766 push_current_activity(ACTIVITY_MAINMENU);
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000767
768 if (global_settings.start_in_screen == 0)
Jonathan Gordon678705c2007-03-29 14:19:28 +0000769 next_screen = (int)global_status.last_screen;
770 else next_screen = global_settings.start_in_screen - 2;
Thomas Martitz35b4ba82014-04-15 09:34:22 +0200771#if CONFIG_TUNER
772 add_event(PLAYBACK_EVENT_START_PLAYBACK, rootmenu_start_playback_callback);
773#endif
Thomas Martitz470989b2014-03-14 23:15:16 +0100774 add_event(PLAYBACK_EVENT_TRACK_CHANGE, rootmenu_track_changed_callback);
Jonathan Gordon9e554a82007-03-07 01:16:25 +0000775#ifdef HAVE_RTC_ALARM
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100776 if ( rtc_check_alarm_started(true) )
Jonathan Gordon9e554a82007-03-07 01:16:25 +0000777 {
778 rtc_enable_alarm(false);
Jonathan Gordon678705c2007-03-29 14:19:28 +0000779 next_screen = GO_TO_WPS;
Jonathan Gordon9e554a82007-03-07 01:16:25 +0000780#if CONFIG_TUNER
781 if (global_settings.alarm_wake_up_screen == ALARM_START_FM)
Jonathan Gordon678705c2007-03-29 14:19:28 +0000782 next_screen = GO_TO_FM;
Jonathan Gordon9e554a82007-03-07 01:16:25 +0000783#endif
784#ifdef HAVE_RECORDING
785 if (global_settings.alarm_wake_up_screen == ALARM_START_REC)
Jonathan Gordone900a902007-03-07 01:59:29 +0000786 {
787 recording_start_automatic = true;
Jonathan Gordon678705c2007-03-29 14:19:28 +0000788 next_screen = GO_TO_RECSCREEN;
Jonathan Gordone900a902007-03-07 01:59:29 +0000789 }
Jonathan Gordon9e554a82007-03-07 01:16:25 +0000790#endif
791 }
792#endif /* HAVE_RTC_ALARM */
793
Jonathan Gordon7ce492e2007-03-08 00:37:58 +0000794#ifdef HAVE_HEADPHONE_DETECTION
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100795 if (next_screen == GO_TO_WPS &&
Jonathan Gordon7ce492e2007-03-08 00:37:58 +0000796 (global_settings.unplug_autoresume && !headphones_inserted() ))
Jonathan Gordon678705c2007-03-29 14:19:28 +0000797 next_screen = GO_TO_ROOT;
Jonathan Gordon7ce492e2007-03-08 00:37:58 +0000798#endif
799
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000800 while (true)
801 {
Jonathan Gordon678705c2007-03-29 14:19:28 +0000802 switch (next_screen)
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000803 {
Jonathan Gordon91e726a2007-03-27 06:38:11 +0000804 case MENU_ATTACHED_USB:
805 case MENU_SELECTED_EXIT:
Jonathan Gordon91e726a2007-03-27 06:38:11 +0000806 /* fall through */
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000807 case GO_TO_ROOT:
Jonathan Gordon43b2d092007-03-07 10:13:07 +0000808 if (last_screen != GO_TO_ROOT)
809 selected = get_selection(last_screen);
Udo Schläpferdbabd0d2015-02-02 21:44:29 +0100810#if (CONFIG_PLATFORM&PLATFORM_ANDROID)
Jonathan Gordona41041a2010-11-03 14:34:57 +0000811 /* When we are in the main menu we want the hardware BACK
812 * button to be handled by Android instead of rockbox */
813 android_ignore_back_button(true);
814#endif
Jonathan Gordon5ca15392008-03-26 03:35:24 +0000815 next_screen = do_menu(&root_menu_, &selected, NULL, false);
Udo Schläpferdbabd0d2015-02-02 21:44:29 +0100816#if (CONFIG_PLATFORM&PLATFORM_ANDROID)
Jonathan Gordona41041a2010-11-03 14:34:57 +0000817 android_ignore_back_button(false);
818#endif
Jonathan Gordon678705c2007-03-29 14:19:28 +0000819 if (next_screen != GO_TO_PREVIOUS)
820 last_screen = GO_TO_ROOT;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000821 break;
Jonathan Gordona74eefe2007-03-06 13:35:15 +0000822
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000823 case GO_TO_PREVIOUS:
Jonathan Gordon678705c2007-03-29 14:19:28 +0000824 next_screen = last_screen;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000825 break;
Jonathan Gordona74eefe2007-03-06 13:35:15 +0000826
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000827 case GO_TO_PREVIOUS_BROWSER:
Jonathan Gordon678705c2007-03-29 14:19:28 +0000828 next_screen = previous_browser;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000829 break;
Jonathan Gordona74eefe2007-03-06 13:35:15 +0000830
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000831 case GO_TO_PREVIOUS_MUSIC:
Jonathan Gordon678705c2007-03-29 14:19:28 +0000832 next_screen = previous_music;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000833 break;
Jonathan Gordonf9fb4922007-04-12 15:28:51 +0000834 case GO_TO_ROOTITEM_CONTEXT:
835 next_screen = load_context_screen(selected);
836 break;
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100837#ifdef HAVE_PICTUREFLOW_INTEGRATION
Jonathan Gordond871ff82010-06-09 04:25:41 +0000838 case GO_TO_PICTUREFLOW:
Solomon Peachyc46147c2019-08-07 12:45:34 -0400839 if (check_database())
Thomas Martitz9c0b2472010-08-01 16:15:27 +0000840 {
841 char pf_path[MAX_PATH];
842 snprintf(pf_path, sizeof(pf_path),
843 "%s/pictureflow.rock",
844 PLUGIN_DEMOS_DIR);
845 next_screen = load_plugin_screen(pf_path);
Solomon Peachyc46147c2019-08-07 12:45:34 -0400846 previous_browser = (next_screen != GO_TO_WPS) ? GO_TO_FILEBROWSER : GO_TO_PICTUREFLOW;
Thomas Martitz9c0b2472010-08-01 16:15:27 +0000847 }
Solomon Peachyc46147c2019-08-07 12:45:34 -0400848 else
849 next_screen = GO_TO_PREVIOUS;
Jonathan Gordond871ff82010-06-09 04:25:41 +0000850 break;
Jonathan Gordon3ac7af92012-12-16 14:26:03 +1100851#endif
Jonathan Gordon678705c2007-03-29 14:19:28 +0000852 default:
Steve Bavin888890a2007-03-09 16:54:35 +0000853#ifdef HAVE_TAGCACHE
Thomas Martitz35b4ba82014-04-15 09:34:22 +0200854/* With !HAVE_TAGCACHE previous_browser is always GO_TO_FILEBROWSER */
855 if (next_screen == GO_TO_FILEBROWSER || next_screen == GO_TO_DBBROWSER)
Jonathan Gordon678705c2007-03-29 14:19:28 +0000856 previous_browser = next_screen;
Steve Bavin888890a2007-03-09 16:54:35 +0000857#endif
Thomas Martitz35b4ba82014-04-15 09:34:22 +0200858#if CONFIG_TUNER
859/* With !CONFIG_TUNER previous_music is always GO_TO_WPS */
860 if (next_screen == GO_TO_WPS || next_screen == GO_TO_FM)
Jonathan Gordon678705c2007-03-29 14:19:28 +0000861 previous_music = next_screen;
Thomas Martitz35b4ba82014-04-15 09:34:22 +0200862#endif
Jonathan Gordon678705c2007-03-29 14:19:28 +0000863 next_screen = load_screen(next_screen);
864 break;
865 } /* switch() */
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000866 }
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000867}