/* 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) { bool restore = false; if (tc.dirlevel < 0) tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */ 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; short attr = tree_get_entry_at(&tc, tc.selected_item)->attr; if ((tc.browse->flags & BROWSE_SELECTONLY) && !(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 { struct entry *entry = tree_get_entry_at(&tc, tc.selected_item); attr = entry->attr; if (currdir[1]) /* Not in / */ snprintf(buf, sizeof buf, "%s/%s", currdir, entry->name); else /* In / */ snprintf(buf, sizeof buf, "/%s", entry->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) { unsigned char* loadbuffer; int buffer_size; int rc; int(*kernel_entry)(void); /* Make sure interrupts are disabled */ set_irq_level(IRQ_DISABLED); set_fiq_status(FIQ_DISABLED); system_init(); kernel_init(); /* Now enable interrupts */ set_irq_level(IRQ_ENABLED); set_fiq_status(FIQ_ENABLED); lcd_init(); backlight_init(); font_init(); button_init(); usb_init(); power_init(); // enable_irq(); // enable_fiq(); adc_init(); lcd_setfont(FONT_SYSFIXED); /* Show debug messages if button is pressed */ // if(button_read_device()) verbose = true; printf("Rockbox boot loader"); printf("Version %s", rbversion); /* Enter USB mode without USB thread */ if(usb_detect() == USB_INSERTED) { const char msg[] = "Bootloader USB mode"; reset_screen(); lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2, (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); lcd_update(); ide_power_enable(true); storage_enable(false); sleep(HZ/20); usb_enable(true); while (usb_detect() == USB_INSERTED) { storage_spin(); /* Prevent the drive from spinning down */ sleep(HZ); } usb_enable(false); reset_screen(); lcd_update(); } sleep(50); printf("ATA"); rc = storage_init(); if(rc) { reset_screen(); error(EATA, rc, true); } printf("filesystem"); filesystem_init(); printf("mount"); rc = disk_mount_all(); if (rc<=0) { error(EDISK,rc, true); } printf("Loading firmware"); loadbuffer = (unsigned char*) 0x00900000; buffer_size = (unsigned char*)0x01900000 - loadbuffer; rc = load_firmware(loadbuffer, BOOTFILE, buffer_size); if(rc <= EFILE_EMPTY) error(EBOOTFILE, rc, true); kernel_entry = (void*) loadbuffer; rc = kernel_entry(); /* Should not get here! */ return rc; }