/* main loop, handles key events */ static int dirbrowse(void) { int numentries=0; char buf[MAX_PATH]; int button, oldbutton; bool reload_root = false; int lastfilter = *tc.dirfilter; bool lastsortcase = global_settings.sort_case; bool exit_func = false; char* currdir = tc.currdir; /* just a shortcut */ #ifdef HAVE_TAGCACHE bool id3db = *tc.dirfilter == SHOW_ID3DB; if (id3db) curr_context=CONTEXT_ID3DB; else #endif curr_context=CONTEXT_TREE; if (tc.selected_item < 0) tc.selected_item = 0; #ifdef HAVE_TAGCACHE tc.firstpos = 0; lasttable = -1; lastextra = -1; lastfirstpos = 0; #endif start_wps = false; numentries = update_dir(); reload_dir = false; if (numentries == -1) return GO_TO_PREVIOUS; /* currdir is not a directory */ if (*tc.dirfilter > NUM_FILTER_MODES && numentries==0) { splash(HZ*2, ID2P(LANG_NO_FILES)); return GO_TO_PREVIOUS; /* No files found for rockbox_browse() */ } gui_synclist_draw(&tree_lists); while(1) { struct entry *dircache = tc.dircache; bool restore = false; if (tc.dirlevel < 0) tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */ #ifdef BOOTFILE if (boot_changed) { static const char *lines[]={ID2P(LANG_BOOT_CHANGED), ID2P(LANG_REBOOT_NOW)}; static const struct text_message message={lines, 2}; if(gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES) rolo_load("/" BOOTFILE); restore = true; boot_changed = false; } #endif button = get_action(CONTEXT_TREE, list_do_action_timeout(&tree_lists, HZ/2)); oldbutton = button; gui_synclist_do_button(&tree_lists, &button,LIST_WRAP_UNLESS_HELD); tc.selected_item = gui_synclist_get_sel_pos(&tree_lists); switch ( button ) { case ACTION_STD_OK: /* nothing to do if no files to display */ if ( numentries == 0 ) break; if ((tc.browse->flags & BROWSE_SELECTONLY) && !(dircache[tc.selected_item].attr & ATTR_DIRECTORY)) { tc.browse->flags |= BROWSE_SELECTED; get_current_file(tc.browse->buf, tc.browse->bufsize); return GO_TO_PREVIOUS; } #ifdef HAVE_TAGCACHE switch (id3db?tagtree_enter(&tc):ft_enter(&tc)) #else switch (ft_enter(&tc)) #endif { case GO_TO_FILEBROWSER: reload_dir = true; break; case GO_TO_WPS: return GO_TO_WPS; #if CONFIG_TUNER case GO_TO_FM: return GO_TO_FM; #endif case GO_TO_ROOT: exit_func = true; break; default: break; } restore = true; break; case ACTION_STD_CANCEL: if (*tc.dirfilter > NUM_FILTER_MODES && tc.dirlevel < 1) { exit_func = true; break; } if ((*tc.dirfilter == SHOW_ID3DB && tc.dirlevel == 0) || ((*tc.dirfilter != SHOW_ID3DB && !strcmp(currdir,"/")))) { #ifdef HAVE_LCD_BITMAP /* charcell doesnt have ACTION_TREE_PGLEFT so this isnt needed */ if (oldbutton == ACTION_TREE_PGLEFT) break; else #endif return GO_TO_ROOT; } #ifdef HAVE_TAGCACHE if (id3db) tagtree_exit(&tc); else #endif if (ft_exit(&tc) == 3) exit_func = true; restore = true; break; case ACTION_TREE_STOP: if (list_stop_handler()) restore = true; break; case ACTION_STD_MENU: return GO_TO_ROOT; break; #ifdef HAVE_RECORDING case ACTION_STD_REC: return GO_TO_RECSCREEN; #endif case ACTION_TREE_WPS: return GO_TO_PREVIOUS_MUSIC; break; #ifdef HAVE_QUICKSCREEN case ACTION_STD_QUICKSCREEN: /* don't enter f2 from plugin browser */ if (*tc.dirfilter < NUM_FILTER_MODES) { if (quick_screen_quick(button)) reload_dir = true; restore = true; } break; #endif #ifdef BUTTON_F3 case ACTION_F3: /* don't enter f3 from plugin browser */ if (*tc.dirfilter < NUM_FILTER_MODES) { if (quick_screen_f3(ACTION_F3)) reload_dir = true; restore = true; } break; #endif #ifdef HAVE_HOTKEY case ACTION_TREE_HOTKEY: if (!global_settings.hotkey_tree) break; /* fall through */ #endif case ACTION_STD_CONTEXT: { bool hotkey = button == ACTION_TREE_HOTKEY; int onplay_result; int attr = 0; if (tc.browse->flags & BROWSE_NO_CONTEXT_MENU) break; if(!numentries) onplay_result = onplay(NULL, 0, curr_context, hotkey); else { #ifdef HAVE_TAGCACHE if (id3db) { if (tagtree_get_attr(&tc) == FILE_ATTR_AUDIO) { attr = FILE_ATTR_AUDIO; tagtree_get_filename(&tc, buf, sizeof(buf)); } else attr = ATTR_DIRECTORY; } else #endif { attr = dircache[tc.selected_item].attr; if (currdir[1]) /* Not in / */ snprintf(buf, sizeof buf, "%s/%s", currdir, dircache[tc.selected_item].name); else /* In / */ snprintf(buf, sizeof buf, "/%s", dircache[tc.selected_item].name); } onplay_result = onplay(buf, attr, curr_context, hotkey); } switch (onplay_result) { case ONPLAY_MAINMENU: return GO_TO_ROOT; case ONPLAY_OK: restore = true; break; case ONPLAY_RELOAD_DIR: reload_dir = true; break; case ONPLAY_START_PLAY: return GO_TO_WPS; break; } break; } #ifdef HAVE_HOTSWAP case SYS_FS_CHANGED: #ifdef HAVE_TAGCACHE if (!id3db) #endif reload_dir = true; /* The 'dir no longer valid' situation will be caught later * by checking the showdir() result. */ break; #endif default: if (default_event_handler(button) == SYS_USB_CONNECTED) { if(*tc.dirfilter > NUM_FILTER_MODES) /* leave sub-browsers after usb, doing otherwise might be confusing to the user */ exit_func = true; else reload_dir = true; } break; } if (start_wps) return GO_TO_WPS; if (button && !IS_SYSEVENT(button)) { storage_spin(); } check_rescan: /* do we need to rescan dir? */ if (reload_dir || reload_root || lastfilter != *tc.dirfilter || lastsortcase != global_settings.sort_case) { if (reload_root) { strcpy(currdir, "/"); tc.dirlevel = 0; #ifdef HAVE_TAGCACHE tc.currtable = 0; tc.currextra = 0; lasttable = -1; lastextra = -1; #endif reload_root = false; } if (!reload_dir) { gui_synclist_select_item(&tree_lists, 0); gui_synclist_draw(&tree_lists); tc.selected_item = 0; lastdir[0] = 0; } lastfilter = *tc.dirfilter; lastsortcase = global_settings.sort_case; restore = true; } if (exit_func) return GO_TO_PREVIOUS; if (restore || reload_dir) { /* restore display */ numentries = update_dir(); reload_dir = false; if (currdir[1] && (numentries < 0)) { /* not in root and reload failed */ reload_root = true; /* try root */ goto check_rescan; } } } return true; }
void main(void) { int rc; power_init(); system_init(); kernel_init(); lcd_init(); show_logo(); enable_irq(); adc_init(); usb_init(); button_init(); powermgmt_init(); #if CONFIG_CHARGING && (CONFIG_CPU == SH7034) if (charger_inserted() #ifdef ATA_POWER_PLAYERSTYLE && !ide_powered() /* relies on probing result from bootloader */ #endif ) { charging_screen(); /* display a "charging" screen */ show_logo(); /* again, to provide better visual feedback */ } #endif rc = storage_init(); if(rc) { #ifdef HAVE_LCD_BITMAP char str[32]; lcd_clear_display(); snprintf(str, 31, "ATA error: %d", rc); lcd_puts(0, 1, str); lcd_update(); while(!(button_get(true) & BUTTON_REL)); #endif panicf("storage: %d", rc); } usb_start_monitoring(); while (usb_detect() == USB_INSERTED) { /* enter USB mode early, before trying to mount */ if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED) { usb_screen(); } } rc = disk_mount_all(); if (rc<=0) { prompt_usb("No partition", "found."); } { // rolo the firmware static const char filename[] = "/" BOOTFILE; rolo_load((char*)filename); /* won't return if started */ prompt_usb("No firmware", filename); } }
int ft_enter(struct tree_context* c) { int rc = GO_TO_PREVIOUS; char buf[MAX_PATH]; struct entry* file = tree_get_entry_at(c, c->selected_item); int file_attr = file->attr; if (c->currdir[1]) snprintf(buf,sizeof(buf),"%s/%s",c->currdir, file->name); else snprintf(buf,sizeof(buf),"/%s",file->name); if (file_attr & ATTR_DIRECTORY) { memcpy(c->currdir, buf, sizeof(c->currdir)); if ( c->dirlevel < MAX_DIR_LEVELS ) c->selected_item_history[c->dirlevel] = c->selected_item; c->dirlevel++; c->selected_item=0; } else { int seed = current_tick; bool play = false; int start_index=0; switch ( file_attr & FILE_ATTR_MASK ) { case FILE_ATTR_M3U: if (!bookmark_autoload(buf)) playlist_viewer_ex(buf); break; case FILE_ATTR_AUDIO: if (bookmark_autoload(c->currdir)) break; splash(0, ID2P(LANG_WAIT)); /* about to create a new current playlist... allow user to cancel the operation */ if (!warn_on_pl_erase()) break; if (global_settings.party_mode && audio_status()) { playlist_insert_track(NULL, buf, PLAYLIST_INSERT_LAST, true, true); splash(HZ, ID2P(LANG_QUEUE_LAST)); } else if (playlist_create(c->currdir, NULL) != -1) { start_index = ft_build_playlist(c, c->selected_item); if (global_settings.playlist_shuffle) { start_index = playlist_shuffle(seed, start_index); /* when shuffling dir.: play all files even if the file selected by user is not the first one */ if (!global_settings.play_selected) start_index = 0; } playlist_start(start_index, 0); play = true; } break; #if CONFIG_TUNER /* fmr preset file */ case FILE_ATTR_FMR: splash(0, ID2P(LANG_WAIT)); /* Preset inside the default folder. */ if(!strncasecmp(FMPRESET_PATH, buf, strlen(FMPRESET_PATH))) { set_file(buf, global_settings.fmr_file, MAX_FILENAME); radio_load_presets(global_settings.fmr_file); } /* * Preset outside default folder, we can choose such only * if we are out of the radio screen, so the check for the * radio status isn't neccessary */ else { radio_load_presets(buf); } rc = GO_TO_FM; break; case FILE_ATTR_FMS: splash(0, ID2P(LANG_WAIT)); set_file(buf, (char *)global_settings.fms_file, MAX_FILENAME); settings_apply_skins(); break; #ifdef HAVE_REMOTE_LCD case FILE_ATTR_RFMS: splash(0, ID2P(LANG_WAIT)); set_file(buf, (char *)global_settings.rfms_file, MAX_FILENAME); settings_apply_skins(); break; #endif #endif #ifdef HAVE_LCD_BITMAP case FILE_ATTR_SBS: splash(0, ID2P(LANG_WAIT)); set_file(buf, (char *)global_settings.sbs_file, MAX_FILENAME); settings_apply_skins(); break; #endif #ifdef HAVE_REMOTE_LCD case FILE_ATTR_RSBS: splash(0, ID2P(LANG_WAIT)); set_file(buf, (char *)global_settings.rsbs_file, MAX_FILENAME); settings_apply_skins(); break; #endif /* wps config file */ case FILE_ATTR_WPS: splash(0, ID2P(LANG_WAIT)); set_file(buf, (char *)global_settings.wps_file, MAX_FILENAME); settings_apply_skins(); break; #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) /* remote-wps config file */ case FILE_ATTR_RWPS: splash(0, ID2P(LANG_WAIT)); set_file(buf, (char *)global_settings.rwps_file, MAX_FILENAME); settings_apply_skins(); break; #endif case FILE_ATTR_CFG: splash(0, ID2P(LANG_WAIT)); if (!settings_load_config(buf,true)) break; splash(HZ, ID2P(LANG_SETTINGS_LOADED)); break; case FILE_ATTR_BMARK: splash(0, ID2P(LANG_WAIT)); bookmark_load(buf, false); rc = GO_TO_FILEBROWSER; break; case FILE_ATTR_LNG: splash(0, ID2P(LANG_WAIT)); if (lang_core_load(buf)) { splash(HZ, ID2P(LANG_FAILED)); break; } set_file(buf, (char *)global_settings.lang_file, MAX_FILENAME); talk_init(); /* use voice of same language */ viewportmanager_theme_changed(THEME_LANGUAGE); settings_apply_skins(); splash(HZ, ID2P(LANG_LANGUAGE_LOADED)); break; #ifdef HAVE_LCD_BITMAP case FILE_ATTR_FONT: ft_load_font(buf); break; case FILE_ATTR_KBD: splash(0, ID2P(LANG_WAIT)); if (!load_kbd(buf)) splash(HZ, ID2P(LANG_KEYBOARD_LOADED)); set_file(buf, (char *)global_settings.kbd_file, MAX_FILENAME); break; #endif #if (CONFIG_PLATFORM & PLATFORM_NATIVE) /* firmware file */ case FILE_ATTR_MOD: splash(0, ID2P(LANG_WAIT)); audio_hard_stop(); rolo_load(buf); break; #endif /* plugin file */ case FILE_ATTR_ROCK: case FILE_ATTR_LUA: { char *plugin = buf, *argument = NULL, lua_path[MAX_PATH]; int ret; if ((file_attr & FILE_ATTR_MASK) == FILE_ATTR_LUA) { snprintf(lua_path, sizeof(lua_path)-1, "%s/lua.rock", VIEWERS_DIR); /* Use a #define here ? */ plugin = lua_path; argument = buf; } if (global_settings.party_mode && audio_status()) { splash(HZ, ID2P(LANG_PARTY_MODE)); break; } ret = plugin_load(plugin, argument); switch (ret) { case PLUGIN_GOTO_WPS: play = true; break; case PLUGIN_USB_CONNECTED: if(*c->dirfilter > NUM_FILTER_MODES) /* leave sub-browsers after usb, doing otherwise might be confusing to the user */ rc = GO_TO_ROOT; else rc = GO_TO_FILEBROWSER; break; /* case PLUGIN_ERROR: case PLUGIN_OK: */ default: break; } break; } case FILE_ATTR_CUE: display_cuesheet_content(buf); break; default: { const char* plugin; if (global_settings.party_mode && audio_status()) { splash(HZ, ID2P(LANG_PARTY_MODE)); break; } struct entry* file = tree_get_entry_at(c, c->selected_item); plugin = filetype_get_plugin(file); if (plugin) { switch (plugin_load(plugin,buf)) { case PLUGIN_USB_CONNECTED: rc = GO_TO_FILEBROWSER; break; case PLUGIN_GOTO_WPS: rc = GO_TO_WPS; break; /* case PLUGIN_OK: case PLUGIN_ERROR: */ default: break; } } break; } } if ( play ) { /* the resume_index must always be the index in the shuffled list in case shuffle is enabled */ global_status.resume_index = start_index; global_status.resume_offset = 0; status_save(); rc = GO_TO_WPS; } else { if (*c->dirfilter > NUM_FILTER_MODES && *c->dirfilter != SHOW_CFG && *c->dirfilter != SHOW_FONT && *c->dirfilter != SHOW_PLUGINS) { rc = GO_TO_ROOT; } } } return rc; }