diff options
Diffstat (limited to 'apps/tree.c')
-rw-r--r-- | apps/tree.c | 194 |
1 files changed, 84 insertions, 110 deletions
diff --git a/apps/tree.c b/apps/tree.c index 30548139ad..a7f871caa1 100644 --- a/apps/tree.c +++ b/apps/tree.c | |||
@@ -30,21 +30,23 @@ | |||
30 | #include "tree.h" | 30 | #include "tree.h" |
31 | #include "play.h" | 31 | #include "play.h" |
32 | #include "main_menu.h" | 32 | #include "main_menu.h" |
33 | #include "mpeg.h" | ||
34 | 33 | ||
35 | #ifdef HAVE_LCD_BITMAP | 34 | #ifdef HAVE_LCD_BITMAP |
36 | #include "icons.h" | 35 | #include "icons.h" |
37 | #endif | 36 | #endif |
38 | 37 | ||
38 | #define MAX_FILES_IN_DIR 200 | ||
39 | #define TREE_MAX_FILENAMELEN 128 | 39 | #define TREE_MAX_FILENAMELEN 128 |
40 | #define MAX_DIR_LEVELS 10 | 40 | #define MAX_DIR_LEVELS 10 |
41 | 41 | ||
42 | struct entry { | 42 | struct entry { |
43 | bool file; /* true if file, false if dir */ | 43 | bool file; /* true if file, false if dir */ |
44 | char name[TREE_MAX_FILENAMELEN]; | 44 | char name[TREE_MAX_FILENAMELEN]; |
45 | int namelen; | ||
46 | }; | 45 | }; |
47 | 46 | ||
47 | static struct entry buffer[MAX_FILES_IN_DIR]; | ||
48 | static int filesindir; | ||
49 | |||
48 | void browse_root(void) | 50 | void browse_root(void) |
49 | { | 51 | { |
50 | dirbrowse("/"); | 52 | dirbrowse("/"); |
@@ -63,6 +65,7 @@ void browse_root(void) | |||
63 | #define LINE_HEIGTH 8 /* pixels for each text line */ | 65 | #define LINE_HEIGTH 8 /* pixels for each text line */ |
64 | 66 | ||
65 | extern unsigned char bitmap_icons_6x8[LastIcon][6]; | 67 | extern unsigned char bitmap_icons_6x8[LastIcon][6]; |
68 | extern icons_6x8; | ||
66 | 69 | ||
67 | #else /* HAVE_LCD_BITMAP */ | 70 | #else /* HAVE_LCD_BITMAP */ |
68 | 71 | ||
@@ -73,88 +76,83 @@ extern unsigned char bitmap_icons_6x8[LastIcon][6]; | |||
73 | 76 | ||
74 | #endif /* HAVE_LCD_BITMAP */ | 77 | #endif /* HAVE_LCD_BITMAP */ |
75 | 78 | ||
76 | static int showdir(char *path, struct entry *buffer, int start, | 79 | static int showdir(char *path, int start) |
77 | int scrollpos, int* at_end) | ||
78 | { | 80 | { |
81 | static char lastdir[256] = {0}; | ||
82 | |||
79 | #ifdef HAVE_LCD_BITMAP | 83 | #ifdef HAVE_LCD_BITMAP |
80 | int icon_type = 0; | 84 | int icon_type = 0; |
81 | #endif | 85 | #endif |
82 | int i; | 86 | int i; |
83 | int j=0; | ||
84 | DIR *dir = opendir(path); | ||
85 | struct dirent *entry; | ||
86 | |||
87 | if(!dir) | ||
88 | return -1; /* not a directory */ | ||
89 | |||
90 | i=start; | ||
91 | *at_end=0; /* Have we displayed the last directory entry? */ | ||
92 | while((entry = readdir(dir))) { | ||
93 | int len; | ||
94 | |||
95 | if(entry->d_name[0] == '.') | ||
96 | /* skip names starting with a dot */ | ||
97 | continue; | ||
98 | 87 | ||
99 | if(j++ < scrollpos) | 88 | /* new dir? cache it */ |
100 | continue ; | 89 | if (strncmp(path,lastdir,sizeof(lastdir))) { |
90 | debugf("Caching dir %s\n",path); | ||
91 | DIR *dir = opendir(path); | ||
92 | if(!dir) | ||
93 | return -1; /* not a directory */ | ||
94 | for ( i=0; i<MAX_FILES_IN_DIR; i++ ) { | ||
95 | struct dirent *entry = readdir(dir); | ||
96 | if (!entry) | ||
97 | break; | ||
98 | if(entry->d_name[0] == '.') { | ||
99 | /* skip names starting with a dot */ | ||
100 | i--; | ||
101 | continue; | ||
102 | } | ||
103 | buffer[i].file = !(entry->attribute & ATTR_DIRECTORY); | ||
104 | strncpy(buffer[i].name,entry->d_name,TREE_MAX_FILENAMELEN); | ||
105 | buffer[i].name[TREE_MAX_FILENAMELEN-1]=0; | ||
106 | } | ||
107 | filesindir = i; | ||
108 | closedir(dir); | ||
109 | strncpy(lastdir,path,sizeof(lastdir)); | ||
110 | lastdir[sizeof(lastdir)-1] = 0; | ||
111 | } | ||
101 | 112 | ||
102 | len = strlen(entry->d_name); | 113 | lcd_clear_display(); |
103 | if(len < TREE_MAX_FILENAMELEN) | 114 | #ifdef HAVE_LCD_BITMAP |
104 | /* strncpy() is evil, we memcpy() instead, +1 includes the | 115 | lcd_putsxy(0,0, "[Browse]",0); |
105 | trailing zero */ | 116 | lcd_update(); |
106 | memcpy(buffer[i].name, entry->d_name, len+1); | 117 | #endif |
107 | else | ||
108 | memcpy(buffer[i].name, "too long", 9); | ||
109 | 118 | ||
110 | buffer[i].file = !(entry->attribute&ATTR_DIRECTORY); | 119 | for ( i=start; i < start+TREE_MAX_ON_SCREEN; i++ ) { |
120 | if ( i < filesindir ) { | ||
121 | int len = strlen(buffer[i].name); | ||
111 | 122 | ||
112 | #ifdef HAVE_LCD_BITMAP | 123 | #ifdef HAVE_LCD_BITMAP |
113 | if ( buffer[i].file ) | 124 | if ( buffer[i].file ) |
114 | icon_type=File; | 125 | icon_type=File; |
115 | else | 126 | else |
116 | icon_type=Folder; | 127 | icon_type=Folder; |
117 | lcd_bitmap(bitmap_icons_6x8[icon_type], 6, MARGIN_Y+i*LINE_HEIGTH, 6, | 128 | lcd_bitmap(bitmap_icons_6x8[icon_type], 6, MARGIN_Y+i*LINE_HEIGTH, 6, |
118 | 8, true); | 129 | 8, true); |
119 | #endif | 130 | #endif |
120 | 131 | ||
121 | if(len < TREE_MAX_LEN_DISPLAY) | 132 | if(len < TREE_MAX_LEN_DISPLAY) |
122 | lcd_puts(LINE_X, LINE_Y+i, buffer[i].name); | 133 | lcd_puts(LINE_X, LINE_Y+i-start, buffer[i].name); |
123 | else { | 134 | else { |
124 | char storage = buffer[i].name[TREE_MAX_LEN_DISPLAY]; | 135 | char storage = buffer[i].name[TREE_MAX_LEN_DISPLAY]; |
125 | buffer[i].name[TREE_MAX_LEN_DISPLAY]=0; | 136 | buffer[i].name[TREE_MAX_LEN_DISPLAY]=0; |
126 | lcd_puts(LINE_X, LINE_Y+i, buffer[i].name); | 137 | lcd_puts(LINE_X, LINE_Y+i-start, buffer[i].name); |
127 | buffer[i].name[TREE_MAX_LEN_DISPLAY]=storage; | 138 | buffer[i].name[TREE_MAX_LEN_DISPLAY]=storage; |
139 | } | ||
128 | } | 140 | } |
129 | 141 | else | |
130 | if(++i >= TREE_MAX_ON_SCREEN) | 142 | lcd_puts(LINE_X, LINE_Y+i-start," "); |
131 | break; | ||
132 | } | ||
133 | |||
134 | if (entry==0) { | ||
135 | *at_end=1; | ||
136 | } else { | ||
137 | *at_end=(readdir(dir)==0); | ||
138 | } | ||
139 | j = i ; | ||
140 | while (j++ < TREE_MAX_ON_SCREEN) { | ||
141 | lcd_puts(LINE_X, LINE_Y+j," "); | ||
142 | } | 143 | } |
143 | closedir(dir); | ||
144 | 144 | ||
145 | return i; | 145 | return filesindir; |
146 | } | 146 | } |
147 | 147 | ||
148 | bool dirbrowse(char *root) | 148 | bool dirbrowse(char *root) |
149 | { | 149 | { |
150 | struct entry buffer[TREE_MAX_ON_SCREEN]; | ||
151 | int numentries; | 150 | int numentries; |
152 | char buf[255]; | 151 | char buf[255]; |
153 | char currdir[255]; | 152 | char currdir[255]; |
154 | int dircursor=0; | 153 | int dircursor=0; |
155 | int i; | 154 | int i; |
156 | int start=0; | 155 | int start=0; |
157 | int at_end=0; | ||
158 | int dirpos[MAX_DIR_LEVELS]; | 156 | int dirpos[MAX_DIR_LEVELS]; |
159 | int dirlevel=0; | 157 | int dirlevel=0; |
160 | 158 | ||
@@ -167,7 +165,7 @@ bool dirbrowse(char *root) | |||
167 | #endif | 165 | #endif |
168 | memcpy(currdir,root,sizeof(currdir)); | 166 | memcpy(currdir,root,sizeof(currdir)); |
169 | 167 | ||
170 | numentries = showdir(root, buffer, 0, start, &at_end); | 168 | numentries = showdir(root, start); |
171 | 169 | ||
172 | if (numentries == -1) | 170 | if (numentries == -1) |
173 | return -1; /* root is not a directory */ | 171 | return -1; /* root is not a directory */ |
@@ -178,7 +176,13 @@ bool dirbrowse(char *root) | |||
178 | #endif | 176 | #endif |
179 | 177 | ||
180 | while(1) { | 178 | while(1) { |
181 | switch ( button_get(true) ) { | 179 | int key = button_get(); |
180 | |||
181 | if(!key) { | ||
182 | sleep(1); | ||
183 | continue; | ||
184 | } | ||
185 | switch(key) { | ||
182 | #if defined(SIMULATOR) && defined(HAVE_RECODER_KEYPAD) | 186 | #if defined(SIMULATOR) && defined(HAVE_RECODER_KEYPAD) |
183 | case BUTTON_OFF: | 187 | case BUTTON_OFF: |
184 | return false; | 188 | return false; |
@@ -199,28 +203,19 @@ bool dirbrowse(char *root) | |||
199 | else | 203 | else |
200 | currdir[i-1]=0; | 204 | currdir[i-1]=0; |
201 | 205 | ||
202 | lcd_clear_display(); | ||
203 | #ifdef HAVE_LCD_BITMAP | ||
204 | lcd_putsxy(0,0, "[Browse]",0); | ||
205 | #endif | ||
206 | dirlevel--; | 206 | dirlevel--; |
207 | if ( dirlevel < MAX_DIR_LEVELS ) | 207 | if ( dirlevel < MAX_DIR_LEVELS ) |
208 | start = dirpos[dirlevel]; | 208 | start = dirpos[dirlevel]; |
209 | else | 209 | else |
210 | start = 0; | 210 | start = 0; |
211 | numentries = showdir(currdir, buffer, 0, start, &at_end); | 211 | numentries = showdir(currdir, start); |
212 | dircursor=0; | 212 | dircursor=0; |
213 | while ( (dircursor < TREE_MAX_ON_SCREEN) && | 213 | while ( (dircursor < TREE_MAX_ON_SCREEN) && |
214 | (strcmp(buffer[dircursor].name,buf)!=0)) | 214 | (strcmp(buffer[dircursor+start].name,buf)!=0)) |
215 | dircursor++; | 215 | dircursor++; |
216 | if (dircursor==TREE_MAX_ON_SCREEN) | 216 | if (dircursor==TREE_MAX_ON_SCREEN) |
217 | dircursor=0; | 217 | dircursor=0; |
218 | lcd_puts(0, LINE_Y+dircursor, "-"); | 218 | lcd_puts(0, LINE_Y+dircursor, "-"); |
219 | lcd_update(); | ||
220 | } | ||
221 | else { | ||
222 | /* if in root, stop stops playback */ | ||
223 | mpeg_stop(); | ||
224 | } | 219 | } |
225 | 220 | ||
226 | break; | 221 | break; |
@@ -230,12 +225,12 @@ bool dirbrowse(char *root) | |||
230 | #endif | 225 | #endif |
231 | case BUTTON_PLAY: | 226 | case BUTTON_PLAY: |
232 | if ((currdir[0]=='/') && (currdir[1]==0)) { | 227 | if ((currdir[0]=='/') && (currdir[1]==0)) { |
233 | snprintf(buf,sizeof(buf),"%s%s",currdir,buffer[dircursor].name); | 228 | snprintf(buf,sizeof(buf),"%s%s",currdir,buffer[dircursor+start].name); |
234 | } else { | 229 | } else { |
235 | snprintf(buf,sizeof(buf),"%s/%s",currdir,buffer[dircursor].name); | 230 | snprintf(buf,sizeof(buf),"%s/%s",currdir,buffer[dircursor+start].name); |
236 | } | 231 | } |
237 | 232 | ||
238 | if (!buffer[dircursor].file) { | 233 | if (!buffer[dircursor+start].file) { |
239 | memcpy(currdir,buf,sizeof(currdir)); | 234 | memcpy(currdir,buf,sizeof(currdir)); |
240 | if ( dirlevel < MAX_DIR_LEVELS ) | 235 | if ( dirlevel < MAX_DIR_LEVELS ) |
241 | dirpos[dirlevel] = start+dircursor; | 236 | dirpos[dirlevel] = start+dircursor; |
@@ -243,20 +238,15 @@ bool dirbrowse(char *root) | |||
243 | dircursor=0; | 238 | dircursor=0; |
244 | start=0; | 239 | start=0; |
245 | } else { | 240 | } else { |
246 | playtune(currdir, buffer[dircursor].name); | 241 | playtune(currdir, buffer[dircursor+start].name); |
247 | #ifdef HAVE_LCD_BITMAP | 242 | #ifdef HAVE_LCD_BITMAP |
248 | lcd_setmargins(0, MARGIN_Y); | 243 | lcd_setmargins(0, MARGIN_Y); |
249 | lcd_setfont(0); | 244 | lcd_setfont(0); |
250 | #endif | 245 | #endif |
251 | } | 246 | } |
252 | 247 | ||
253 | lcd_clear_display(); | 248 | numentries = showdir(currdir, start); |
254 | numentries = showdir(currdir, buffer, 0, start, &at_end); | ||
255 | lcd_puts(0, LINE_Y+dircursor, "-"); | 249 | lcd_puts(0, LINE_Y+dircursor, "-"); |
256 | #ifdef HAVE_LCD_BITMAP | ||
257 | lcd_putsxy(0,0, "[Browse]",0); | ||
258 | lcd_update(); | ||
259 | #endif | ||
260 | break; | 250 | break; |
261 | 251 | ||
262 | #ifdef HAVE_RECORDER_KEYPAD | 252 | #ifdef HAVE_RECORDER_KEYPAD |
@@ -271,16 +261,10 @@ bool dirbrowse(char *root) | |||
271 | lcd_update(); | 261 | lcd_update(); |
272 | } | 262 | } |
273 | else { | 263 | else { |
274 | if (start) { | 264 | if (start) { |
275 | lcd_clear_display(); | ||
276 | start--; | 265 | start--; |
277 | numentries = showdir(currdir, buffer, 0, | 266 | numentries = showdir(currdir, start); |
278 | start, &at_end); | ||
279 | lcd_puts(0, LINE_Y+dircursor, "-"); | 267 | lcd_puts(0, LINE_Y+dircursor, "-"); |
280 | #ifdef HAVE_LCD_BITMAP | ||
281 | lcd_putsxy(0,0, "[Browse]",0); | ||
282 | lcd_update(); | ||
283 | #endif | ||
284 | } | 268 | } |
285 | } | 269 | } |
286 | break; | 270 | break; |
@@ -290,27 +274,17 @@ bool dirbrowse(char *root) | |||
290 | #else | 274 | #else |
291 | case BUTTON_RIGHT: | 275 | case BUTTON_RIGHT: |
292 | #endif | 276 | #endif |
293 | if(dircursor+1 < numentries) { | 277 | if(dircursor+1 < TREE_MAX_ON_SCREEN) { |
294 | lcd_puts(0, LINE_Y+dircursor, " "); | 278 | lcd_puts(0, LINE_Y+dircursor, " "); |
295 | dircursor++; | 279 | dircursor++; |
296 | lcd_puts(0, LINE_Y+dircursor, "-"); | 280 | lcd_puts(0, LINE_Y+dircursor, "-"); |
297 | #ifdef HAVE_LCD_BITMAP | 281 | } |
298 | lcd_update(); | 282 | else { |
299 | #endif | 283 | start++; |
300 | } else | 284 | numentries = showdir(currdir, start); |
301 | { | 285 | lcd_puts(0, LINE_Y+dircursor, "-"); |
302 | if (!at_end) { | ||
303 | lcd_clear_display(); | ||
304 | start++; | ||
305 | numentries = showdir(currdir, buffer, 0, | ||
306 | start, &at_end); | ||
307 | lcd_puts(0, LINE_Y+dircursor, "-"); | ||
308 | #ifdef HAVE_LCD_BITMAP | ||
309 | lcd_putsxy(0,0, "[Browse]",0); | ||
310 | lcd_update(); | ||
311 | #endif | ||
312 | } | ||
313 | } | 286 | } |
287 | debugf("s:%d d:%d\n",start,dircursor); | ||
314 | break; | 288 | break; |
315 | 289 | ||
316 | #ifdef HAVE_RECORDER_KEYPAD | 290 | #ifdef HAVE_RECORDER_KEYPAD |
@@ -330,18 +304,18 @@ bool dirbrowse(char *root) | |||
330 | lcd_setmargins(0,MARGIN_Y); | 304 | lcd_setmargins(0,MARGIN_Y); |
331 | lcd_setfont(0); | 305 | lcd_setfont(0); |
332 | #endif | 306 | #endif |
333 | numentries = showdir(currdir, buffer, 0, start, &at_end); | 307 | numentries = showdir(currdir, start); |
334 | dircursor=0; | 308 | dircursor=0; |
335 | while ( (dircursor < TREE_MAX_ON_SCREEN) && | 309 | while ( (dircursor < TREE_MAX_ON_SCREEN) && |
336 | (strcmp(buffer[dircursor].name,buf)!=0)) | 310 | (strcmp(buffer[dircursor+start].name,buf)!=0)) |
337 | dircursor++; | 311 | dircursor++; |
338 | if (dircursor==TREE_MAX_ON_SCREEN) | 312 | if (dircursor==TREE_MAX_ON_SCREEN) |
339 | dircursor=0; | 313 | dircursor=0; |
340 | lcd_puts(0, LINE_Y+dircursor, "-"); | 314 | lcd_puts(0, LINE_Y+dircursor, "-"); |
341 | lcd_update(); | ||
342 | 315 | ||
343 | break; | 316 | break; |
344 | } | 317 | } |
318 | lcd_update(); | ||
345 | } | 319 | } |
346 | 320 | ||
347 | return false; | 321 | return false; |