Пример #1
0
static int tree_get_filecolor(int selected_item, void * data)
{
    if (*tc.dirfilter == SHOW_ID3DB)
        return -1;
    struct tree_context * local_tc=(struct tree_context *)data;
    struct entry* e = tree_get_entry_at(local_tc, selected_item);
    return filetype_get_color(e->name, e->attr);
}
Пример #2
0
static const char* tree_get_filename(int selected_item, void *data,
                                     char *buffer, size_t buffer_len)
{
    struct tree_context * local_tc=(struct tree_context *)data;
    char *name;
    int attr=0;
    bool stripit = false;
#ifdef HAVE_TAGCACHE
    bool id3db = *(local_tc->dirfilter) == SHOW_ID3DB;

    if (id3db)
    {
        return tagtree_get_entry_name(&tc, selected_item, buffer, buffer_len);
    }
    else 
#endif
    {
        struct entry* e = tree_get_entry_at(local_tc, selected_item);
        name = e->name;
        attr = e->attr;
    }
    
    if(!(attr & ATTR_DIRECTORY))
    {
        switch(global_settings.show_filename_ext)
        {
            case 0:
                /* show file extension: off */
                stripit = true;
                break;
            case 1:
                /* show file extension: on */
                break;
            case 2:
                /* show file extension: only unknown types */
                stripit = filetype_supported(attr);
                break;
            case 3:
            default:
                /* show file extension: only when viewing all */
                stripit = (*(local_tc->dirfilter) != SHOW_ID3DB) &&
                          (*(local_tc->dirfilter) != SHOW_ALL);
                break;
        }
    }

    if(stripit)
    {
        return(strip_extension(buffer, buffer_len, name));
    }
    return(name);
}
Пример #3
0
/*
 * Returns the position of a given file in the current directory
 * returns -1 if not found
 */
static int tree_get_file_position(char * filename)
{
    int i;
    struct entry* e;

    /* use lastfile to determine the selected item (default=0) */
    for (i=0; i < tc.filesindir; i++)
    {
        e = tree_get_entry_at(&tc, i);
        if (!strcasecmp(e->name, filename))
            return(i);
    }
    return(-1);/* no file can match, returns undefined */
}
Пример #4
0
static enum themable_icons tree_get_fileicon(int selected_item, void * data)
{
    struct tree_context * local_tc=(struct tree_context *)data;
#ifdef HAVE_TAGCACHE
    bool id3db = *(local_tc->dirfilter) == SHOW_ID3DB;
    if (id3db) {
        return tagtree_get_icon(&tc);
    }
    else
#endif
    {
        struct entry* e = tree_get_entry_at(local_tc, selected_item);
        return filetype_get_icon(e->attr);
    }
}
Пример #5
0
char* get_current_file(char* buffer, size_t buffer_len)
{
#ifdef HAVE_TAGCACHE
    /* in ID3DB mode it is a bad idea to call this function */
    /* (only happens with `follow playlist') */
    if( *tc.dirfilter == SHOW_ID3DB )
        return NULL;
#endif

    struct entry* e = tree_get_entry_at(&tc, tc.selected_item);
    if (getcwd(buffer, buffer_len))
    {
        if (tc.dirlength)
        {
            if (buffer[strlen(buffer)-1] != '/')
                strlcat(buffer, "/", buffer_len);
            if (strlcat(buffer, e->name, buffer_len) >= buffer_len)
                return NULL;
        }
        return buffer;
    }
    return NULL;
}
Пример #6
0
/* 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;
}
Пример #7
0
static int tree_voice_cb(int selected_item, void * data)
{
    struct tree_context * local_tc=(struct tree_context *)data;
    char *name;
    int attr=0;
#ifdef HAVE_TAGCACHE
    bool id3db = *(local_tc->dirfilter) == SHOW_ID3DB;
    char buf[AVERAGE_FILENAME_LENGTH*2];

    if (id3db)
    {
        attr = tagtree_get_attr(local_tc);
        name = tagtree_get_entry_name(local_tc, selected_item, buf, sizeof(buf));
    }
    else
#endif
    {
        struct entry* e = tree_get_entry_at(local_tc, selected_item);
        name = e->name;
        attr = e->attr;
    }
    bool is_dir = (attr & ATTR_DIRECTORY);
    bool did_clip = false;
    /* First the .talk clip case */
    if(is_dir)
    {
        if(global_settings.talk_dir_clip)
        {
            did_clip = true;
            if(ft_play_dirname(name) <0)
                /* failed, not existing */
                did_clip = false;
        }
    } else { /* it's a file */
        if (global_settings.talk_file_clip && (attr & FILE_ATTR_THUMBNAIL))
        {
            did_clip = true;
            ft_play_filename(local_tc->currdir, name);
        }
    }
    if(!did_clip)
    {
        /* say the number or spell if required or as a fallback */
        switch (is_dir ? global_settings.talk_dir : global_settings.talk_file)
        {
        case 1: /* as numbers */
            talk_id(is_dir ? VOICE_DIR : VOICE_FILE, false);
            talk_number(selected_item+1        - (is_dir ? 0 : local_tc->dirsindir),
                        true);
            if(global_settings.talk_filetype
               && !is_dir && *local_tc->dirfilter < NUM_FILTER_MODES)
                say_filetype(attr);
            break;
        case 2: /* spelled */
            talk_shutup();
            if(global_settings.talk_filetype)
            {
                if(is_dir)
                    talk_id(VOICE_DIR, true);
                else if(*local_tc->dirfilter < NUM_FILTER_MODES)
                    say_filetype(attr);
            }
            talk_spell(name, true);
            break;
        }
    }
    return 0;
}
Пример #8
0
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;
}
Пример #9
0
/* load and sort directory into the tree's cache. returns NULL on failure. */
int ft_load(struct tree_context* c, const char* tempdir)
{
    int files_in_dir = 0;
    int name_buffer_used = 0;
    struct dirent *entry;
    bool (*callback_show_item)(char *, int, struct tree_context *) = NULL;
    DIR *dir;

    if (tempdir)
        dir = opendir(tempdir);
    else
    {
        dir = opendir(c->currdir);
        callback_show_item = c->browse? c->browse->callback_show_item: NULL;
    }
    if(!dir)
        return -1; /* not a directory */

    c->dirsindir = 0;
    c->dirfull = false;

    tree_lock_cache(c);
    while ((entry = readdir(dir))) {
        int len;
        struct dirinfo info;
        struct entry* dptr = tree_get_entry_at(c, files_in_dir);
        if (!entry)
            break;

        info = dir_get_info(dir, entry);
        len = strlen((char *)entry->d_name);

        /* skip directories . and .. */
        if ((info.attribute & ATTR_DIRECTORY) &&
            (((len == 1) && (!strncmp((char *)entry->d_name, ".", 1))) ||
             ((len == 2) && (!strncmp((char *)entry->d_name, "..", 2))))) {
            continue;
        }

        /* Skip FAT volume ID */
        if (info.attribute & ATTR_VOLUME_ID) {
            continue;
        }

        /* filter out dotfiles and hidden files */
        if (*c->dirfilter != SHOW_ALL &&
            ((entry->d_name[0]=='.') ||
            (info.attribute & ATTR_HIDDEN))) {
            continue;
        }

        dptr->attr = info.attribute;

        /* check for known file types */
        if ( !(dptr->attr & ATTR_DIRECTORY) )
            dptr->attr |= filetype_get_attr((char *)entry->d_name);

        /* filter out non-visible files */
        if ((!(dptr->attr & ATTR_DIRECTORY) && (
            (*c->dirfilter == SHOW_PLAYLIST &&
             (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_M3U) ||
            ((*c->dirfilter == SHOW_MUSIC &&
             (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) &&
             (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_M3U) ||
            (*c->dirfilter == SHOW_SUPPORTED && !filetype_supported(dptr->attr)))) ||
            (*c->dirfilter == SHOW_WPS && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_WPS) ||
#ifdef HAVE_LCD_BITMAP
            (*c->dirfilter == SHOW_FONT && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_FONT) ||
            (*c->dirfilter == SHOW_SBS  && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_SBS) ||
#if CONFIG_TUNER
            (*c->dirfilter == SHOW_FMS  && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_FMS) ||
#endif
#endif
#ifdef HAVE_REMOTE_LCD
            (*c->dirfilter == SHOW_RWPS && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_RWPS) ||
            (*c->dirfilter == SHOW_RSBS && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_RSBS) ||
#if CONFIG_TUNER
            (*c->dirfilter == SHOW_RFMS  && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_RFMS) ||
#endif
#endif
#if CONFIG_TUNER
            (*c->dirfilter == SHOW_FMR && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_FMR) ||
#endif
            (*c->dirfilter == SHOW_M3U && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_M3U) ||
            (*c->dirfilter == SHOW_CFG && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_CFG) ||
            (*c->dirfilter == SHOW_LNG && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_LNG) ||
            (*c->dirfilter == SHOW_MOD && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_MOD) ||
            (*c->dirfilter == SHOW_PLUGINS && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_ROCK &&
                                              (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_LUA) ||
            (callback_show_item && !callback_show_item(entry->d_name, dptr->attr, c)))
        {
            continue;
        }

        if ((len > c->cache.name_buffer_size - name_buffer_used - 1) ||
            (files_in_dir >= c->cache.max_entries)) {
            /* Tell the world that we ran out of buffer space */
            c->dirfull = true;
            break;
        }

        ++files_in_dir;

        dptr->name = core_get_data(c->cache.name_buffer_handle)+name_buffer_used;
        dptr->time_write =
            (long)info.wrtdate<<16 |
            (long)info.wrttime; /* in one # */
        strcpy(dptr->name, (char *)entry->d_name);
        name_buffer_used += len + 1;

        if (dptr->attr & ATTR_DIRECTORY) /* count the remaining dirs */
            c->dirsindir++;
    }
    c->filesindir = files_in_dir;
    c->dirlength = files_in_dir;
    closedir(dir);

    compare_sort_dir = c->sort_dir;
    qsort(tree_get_entries(c), files_in_dir, sizeof(struct entry), compare);

    /* If thumbnail talking is enabled, make an extra run to mark files with
       associated thumbnails, so we don't do unsuccessful spinups later. */
    if (global_settings.talk_file_clip)
        check_file_thumbnails(c); /* map .talk to ours */

    tree_unlock_cache(c);
    return 0;
}