summaryrefslogtreecommitdiff
path: root/apps/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/tree.c')
-rw-r--r--apps/tree.c92
1 files changed, 50 insertions, 42 deletions
diff --git a/apps/tree.c b/apps/tree.c
index 8b98f2b940..2230f17aa9 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -22,6 +22,7 @@
22#include <stdlib.h> 22#include <stdlib.h>
23#include <stdbool.h> 23#include <stdbool.h>
24 24
25#include "applimits.h"
25#include "dir.h" 26#include "dir.h"
26#include "file.h" 27#include "file.h"
27#include "lcd.h" 28#include "lcd.h"
@@ -47,17 +48,16 @@
47#include "ajf.h" 48#include "ajf.h"
48#endif 49#endif
49 50
50#define MAX_FILES_IN_DIR 200 51#define NAME_BUFFER_SIZE (AVERAGE_FILENAME_LENGTH * MAX_FILES_IN_DIR)
51#define TREE_MAX_FILENAMELEN MAX_PATH
52#define MAX_DIR_LEVELS 10
53 52
53char name_buffer[NAME_BUFFER_SIZE];
54int name_buffer_length;
54struct entry { 55struct entry {
55 char attr; /* FAT attributes */ 56 short attr; /* FAT attributes */
56 char name[TREE_MAX_FILENAMELEN]; 57 char *name;
57}; 58};
58 59
59static struct entry dircache[MAX_FILES_IN_DIR]; 60static struct entry dircache[MAX_FILES_IN_DIR];
60static struct entry* dircacheptr[MAX_FILES_IN_DIR];
61static int filesindir; 61static int filesindir;
62static char lastdir[MAX_PATH] = {0}; 62static char lastdir[MAX_PATH] = {0};
63 63
@@ -122,10 +122,10 @@ static int build_playlist(int start_index)
122 122
123 for(i = 0;i < filesindir;i++) 123 for(i = 0;i < filesindir;i++)
124 { 124 {
125 if(dircacheptr[i]->attr & TREE_ATTR_MP3) 125 if(dircache[i].attr & TREE_ATTR_MP3)
126 { 126 {
127 DEBUGF("Adding %s\n", dircacheptr[i]->name); 127 DEBUGF("Adding %s\n", dircache[i].name);
128 playlist_add(dircacheptr[i]->name); 128 playlist_add(dircache[i].name);
129 } 129 }
130 else 130 else
131 { 131 {
@@ -140,14 +140,14 @@ static int build_playlist(int start_index)
140 140
141static int compare(const void* p1, const void* p2) 141static int compare(const void* p1, const void* p2)
142{ 142{
143 struct entry* e1 = *(struct entry**)p1; 143 struct entry* e1 = (struct entry*)p1;
144 struct entry* e2 = *(struct entry**)p2; 144 struct entry* e2 = (struct entry*)p2;
145 145
146 if (( e1->attr & ATTR_DIRECTORY ) == ( e2->attr & ATTR_DIRECTORY )) 146 if (( e1->attr & ATTR_DIRECTORY ) == ( e2->attr & ATTR_DIRECTORY ))
147 if (global_settings.sort_case) 147 if (global_settings.sort_case)
148 return strncmp(e1->name, e2->name, TREE_MAX_FILENAMELEN); 148 return strncmp(e1->name, e2->name, MAX_PATH);
149 else 149 else
150 return strncasecmp(e1->name, e2->name, TREE_MAX_FILENAMELEN); 150 return strncasecmp(e1->name, e2->name, MAX_PATH);
151 else 151 else
152 return ( e2->attr & ATTR_DIRECTORY ) - ( e1->attr & ATTR_DIRECTORY ); 152 return ( e2->attr & ATTR_DIRECTORY ) - ( e1->attr & ATTR_DIRECTORY );
153} 153}
@@ -160,6 +160,7 @@ static int showdir(char *path, int start)
160#endif 160#endif
161 int i; 161 int i;
162 int tree_max_on_screen; 162 int tree_max_on_screen;
163 bool dir_buffer_full;
163#ifdef LOADABLE_FONTS 164#ifdef LOADABLE_FONTS
164 int fh; 165 int fh;
165 unsigned char *font = lcd_getcurrentldfont(); 166 unsigned char *font = lcd_getcurrentldfont();
@@ -177,7 +178,9 @@ static int showdir(char *path, int start)
177 if(!dir) 178 if(!dir)
178 return -1; /* not a directory */ 179 return -1; /* not a directory */
179 180
180 memset(dircacheptr,0,sizeof(dircacheptr)); 181 name_buffer_length = 0;
182 dir_buffer_full = false;
183
181 for ( i=0; i<MAX_FILES_IN_DIR; i++ ) { 184 for ( i=0; i<MAX_FILES_IN_DIR; i++ ) {
182 int len; 185 int len;
183 struct dirent *entry = readdir(dir); 186 struct dirent *entry = readdir(dir);
@@ -212,23 +215,28 @@ static int showdir(char *path, int start)
212 continue; 215 continue;
213 } 216 }
214 217
215 strncpy(dptr->name,entry->d_name,TREE_MAX_FILENAMELEN); 218 if(len > NAME_BUFFER_SIZE - name_buffer_length - 1) {
216 dptr->name[TREE_MAX_FILENAMELEN-1]=0; 219 /* Tell the world that we ran out of buffer space */
217 dircacheptr[i] = dptr; 220 dir_buffer_full = true;
221 break;
222 }
223 dptr->name = &name_buffer[name_buffer_length];
224 strcpy(dptr->name,entry->d_name);
225 name_buffer_length += len + 1;
218 } 226 }
219 filesindir = i; 227 filesindir = i;
220 closedir(dir); 228 closedir(dir);
221 strncpy(lastdir,path,sizeof(lastdir)); 229 strncpy(lastdir,path,sizeof(lastdir));
222 lastdir[sizeof(lastdir)-1] = 0; 230 lastdir[sizeof(lastdir)-1] = 0;
223 qsort(dircacheptr,filesindir,sizeof(struct entry*),compare); 231 qsort(dircache,filesindir,sizeof(struct entry),compare);
224 232
225 if ( filesindir == MAX_FILES_IN_DIR ) { 233 if ( dir_buffer_full || filesindir == MAX_FILES_IN_DIR ) {
226#ifdef HAVE_NEW_CHARCELL_LCD 234#ifdef HAVE_NEW_CHARCELL_LCD
227 lcd_double_height(false); 235 lcd_double_height(false);
228#endif 236#endif
229 lcd_clear_display(); 237 lcd_clear_display();
230 lcd_puts(0,0,"200 file"); 238 lcd_puts(0,0,"Dir buffer");
231 lcd_puts(0,1,"limit reached"); 239 lcd_puts(0,1,"is full!");
232 lcd_update(); 240 lcd_update();
233 sleep(HZ*2); 241 sleep(HZ*2);
234 lcd_clear_display(); 242 lcd_clear_display();
@@ -251,13 +259,13 @@ static int showdir(char *path, int start)
251 if ( i >= filesindir ) 259 if ( i >= filesindir )
252 break; 260 break;
253 261
254 len = strlen(dircacheptr[i]->name); 262 len = strlen(dircache[i].name);
255 263
256#ifdef HAVE_LCD_BITMAP 264#ifdef HAVE_LCD_BITMAP
257 if ( dircacheptr[i]->attr & ATTR_DIRECTORY ) 265 if ( dircache[i].attr & ATTR_DIRECTORY )
258 icon_type = Folder; 266 icon_type = Folder;
259 else { 267 else {
260 if ( dircacheptr[i]->attr & TREE_ATTR_M3U ) 268 if ( dircache[i].attr & TREE_ATTR_M3U )
261 icon_type = Playlist; 269 icon_type = Playlist;
262 else 270 else
263 icon_type = File; 271 icon_type = File;
@@ -269,15 +277,15 @@ static int showdir(char *path, int start)
269 277
270 /* if MP3 filter is on, cut off the extension */ 278 /* if MP3 filter is on, cut off the extension */
271 if (global_settings.mp3filter && 279 if (global_settings.mp3filter &&
272 (dircacheptr[i]->attr & (TREE_ATTR_M3U|TREE_ATTR_MP3))) 280 (dircache[i].attr & (TREE_ATTR_M3U|TREE_ATTR_MP3)))
273 { 281 {
274 char temp = dircacheptr[i]->name[len-4]; 282 char temp = dircache[i].name[len-4];
275 dircacheptr[i]->name[len-4] = 0; 283 dircache[i].name[len-4] = 0;
276 lcd_puts(LINE_X, LINE_Y+i-start, dircacheptr[i]->name); 284 lcd_puts(LINE_X, LINE_Y+i-start, dircache[i].name);
277 dircacheptr[i]->name[len-4] = temp; 285 dircache[i].name[len-4] = temp;
278 } 286 }
279 else 287 else
280 lcd_puts(LINE_X, LINE_Y+i-start, dircacheptr[i]->name); 288 lcd_puts(LINE_X, LINE_Y+i-start, dircache[i].name);
281 } 289 }
282 290
283 status_draw(); 291 status_draw();
@@ -359,13 +367,13 @@ bool dirbrowse(char *root)
359 break; 367 break;
360 if ((currdir[0]=='/') && (currdir[1]==0)) { 368 if ((currdir[0]=='/') && (currdir[1]==0)) {
361 snprintf(buf,sizeof(buf),"%s%s",currdir, 369 snprintf(buf,sizeof(buf),"%s%s",currdir,
362 dircacheptr[dircursor+start]->name); 370 dircache[dircursor+start].name);
363 } else { 371 } else {
364 snprintf(buf,sizeof(buf),"%s/%s",currdir, 372 snprintf(buf,sizeof(buf),"%s/%s",currdir,
365 dircacheptr[dircursor+start]->name); 373 dircache[dircursor+start].name);
366 } 374 }
367 375
368 if (dircacheptr[dircursor+start]->attr & ATTR_DIRECTORY) { 376 if (dircache[dircursor+start].attr & ATTR_DIRECTORY) {
369 memcpy(currdir,buf,sizeof(currdir)); 377 memcpy(currdir,buf,sizeof(currdir));
370 if ( dirlevel < MAX_DIR_LEVELS ) { 378 if ( dirlevel < MAX_DIR_LEVELS ) {
371 dirpos[dirlevel] = start; 379 dirpos[dirlevel] = start;
@@ -376,10 +384,10 @@ bool dirbrowse(char *root)
376 start=0; 384 start=0;
377 } else { 385 } else {
378 lcd_stop_scroll(); 386 lcd_stop_scroll();
379 if(dircacheptr[dircursor+start]->attr & TREE_ATTR_M3U ) 387 if(dircache[dircursor+start].attr & TREE_ATTR_M3U )
380 { 388 {
381 play_list(currdir, 389 play_list(currdir,
382 dircacheptr[dircursor+start]->name, 0); 390 dircache[dircursor+start].name, 0);
383 } 391 }
384 else { 392 else {
385 start_index = build_playlist(dircursor+start); 393 start_index = build_playlist(dircursor+start);
@@ -568,19 +576,19 @@ bool dirbrowse(char *root)
568 lasti=i; 576 lasti=i;
569 lcd_stop_scroll(); 577 lcd_stop_scroll();
570 if (global_settings.mp3filter && 578 if (global_settings.mp3filter &&
571 (dircacheptr[i]->attr & 579 (dircache[i].attr &
572 (TREE_ATTR_M3U|TREE_ATTR_MP3))) 580 (TREE_ATTR_M3U|TREE_ATTR_MP3)))
573 { 581 {
574 int len = strlen(dircacheptr[i]->name); 582 int len = strlen(dircache[i].name);
575 char temp = dircacheptr[i]->name[len-4]; 583 char temp = dircache[i].name[len-4];
576 dircacheptr[i]->name[len-4] = 0; 584 dircache[i].name[len-4] = 0;
577 lcd_puts_scroll(LINE_X, LINE_Y+dircursor, 585 lcd_puts_scroll(LINE_X, LINE_Y+dircursor,
578 dircacheptr[i]->name); 586 dircache[i].name);
579 dircacheptr[i]->name[len-4] = temp; 587 dircache[i].name[len-4] = temp;
580 } 588 }
581 else 589 else
582 lcd_puts_scroll(LINE_X, LINE_Y+dircursor, 590 lcd_puts_scroll(LINE_X, LINE_Y+dircursor,
583 dircacheptr[i]->name); 591 dircache[i].name);
584 } 592 }
585 } 593 }
586 status_draw(); 594 status_draw();