blob: 01aabf7d82c5373e120cc3a69f07d5df416a9763 [file] [log] [blame]
Björn Stenberg82182852002-05-16 12:53:40 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Daniel Stenberg
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
Björn Stenberg244688e2002-05-16 14:48:40 +000020#include <stdio.h>
Björn Stenberg82182852002-05-16 12:53:40 +000021#include <string.h>
22#include <stdlib.h>
23#include <stdbool.h>
24
Linus Nielsen Feltzing5917e812002-08-15 12:28:52 +000025#include "applimits.h"
Björn Stenberg82182852002-05-16 12:53:40 +000026#include "dir.h"
27#include "file.h"
28#include "lcd.h"
Daniel Stenberg93b231c2002-09-12 13:33:59 +000029#include "font.h"
Justin Heinerb5025a82002-08-31 04:58:35 +000030#include "backlight.h"
Björn Stenberg82182852002-05-16 12:53:40 +000031#include "button.h"
32#include "kernel.h"
Linus Nielsen Feltzinge0b23fe2002-06-30 13:23:58 +000033#include "usb.h"
Björn Stenberg82182852002-05-16 12:53:40 +000034#include "tree.h"
Björn Stenberg3ed28742002-05-24 15:51:39 +000035#include "main_menu.h"
Felix Arendsebbbe4b2002-05-29 16:38:19 +000036#include "sprintf.h"
Björn Stenbergf88f9112002-05-30 13:23:03 +000037#include "mpeg.h"
Daniel Stenberg7bd65ab2002-06-07 14:23:32 +000038#include "playlist.h"
Daniel Stenberg91f743f2002-06-14 10:39:11 +000039#include "menu.h"
Björn Stenbergbb9aaf52002-06-25 13:26:04 +000040#include "wps.h"
Björn Stenberg1a682be2002-09-02 12:46:32 +000041#include "wps-display.h"
Björn Stenberg24fdde02002-06-27 09:12:29 +000042#include "settings.h"
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +000043#include "status.h"
Linus Nielsen Feltzinge0b23fe2002-06-30 13:23:58 +000044#include "debug.h"
Björn Stenberg457b8a02002-08-26 13:21:14 +000045#include "ata.h"
Björn Stenbergc521ed12002-09-03 09:44:08 +000046#include "rolo.h"
Linus Nielsen Feltzing10452d22002-09-03 07:53:51 +000047#include "icons.h"
Björn Stenberg505eca72002-09-18 14:08:05 +000048#include "lang.h"
Daniel Stenberga007ebf2002-09-24 12:40:52 +000049#include "language.h"
Björn Stenbergb1b8bd42002-09-24 17:22:12 +000050#include "screens.h"
Björn Stenbergcaebdd42003-01-15 14:52:53 +000051#include "keyboard.h"
Björn Stenberga108ec22004-01-14 00:13:04 +000052#include "bookmark.h"
Björn Stenbergd7a55e12003-03-12 20:21:30 +000053#include "onplay.h"
Linus Nielsen Feltzing20d031f2003-05-09 16:01:21 +000054#include "buffer.h"
Björn Stenbergba371fb2003-06-29 16:33:04 +000055#include "plugin.h"
Björn Stenberg461d6e32003-12-04 00:08:25 +000056#include "power.h"
Linus Nielsen Feltzing10b92c42004-03-12 10:20:33 +000057#include "action.h"
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +000058#include "talk.h"
Björn Stenberg82182852002-05-16 12:53:40 +000059
60#ifdef HAVE_LCD_BITMAP
Markus Braun000c2db2002-08-30 13:49:32 +000061#include "widgets.h"
Björn Stenbergba5dfbd2003-06-29 22:39:35 +000062#define BOOTFILE "ajbrec.ajz"
63#else
64#define BOOTFILE "archos.mod"
Björn Stenberg82182852002-05-16 12:53:40 +000065#endif
66
Jörg Hohensohn8b813d02003-12-07 16:57:43 +000067/* a table for the know file types */
68static struct
69{
70 char* extension; /* extension for which the file type is recognized */
71 int tree_attr; /* which identifier */
72 int icon; /* the icon which shall be used for it, -1 if unknown */
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +000073 int voiceclip; /* spoken extension */
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +000074 /* To have it extendable, there could be more useful stuff in here,
Jörg Hohensohn8b813d02003-12-07 16:57:43 +000075 like handler functions, plugin name, etc. */
76} filetypes[] = {
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +000077 { ".mp3", TREE_ATTR_MPA, File, VOICE_EXT_MPA },
78 { ".mp2", TREE_ATTR_MPA, File, VOICE_EXT_MPA },
79 { ".mpa", TREE_ATTR_MPA, File, VOICE_EXT_MPA },
80 { ".m3u", TREE_ATTR_M3U, Playlist, LANG_PLAYINDICES_PLAYLIST },
81 { ".cfg", TREE_ATTR_CFG, Config, VOICE_EXT_CFG },
82 { ".wps", TREE_ATTR_WPS, Wps, VOICE_EXT_WPS },
83 { ".txt", TREE_ATTR_TXT, Text, VOICE_EXT_TXT },
84 { ".lng", TREE_ATTR_LNG, Language, LANG_LANGUAGE },
85 { ".rock",TREE_ATTR_ROCK,Plugin, VOICE_EXT_ROCK },
Jörg Hohensohn8b813d02003-12-07 16:57:43 +000086#ifdef HAVE_LCD_BITMAP
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +000087 { ".fnt", TREE_ATTR_FONT,Font, VOICE_EXT_FONT },
88 { ".ch8", TREE_ATTR_CH8, Chip8, -1 },
89 { ".rvf", TREE_ATTR_RVF, Video, -1 },
90 { ".bmark",TREE_ATTR_BMARK, Bookmark, VOICE_EXT_BMARK },
Björn Stenberga108ec22004-01-14 00:13:04 +000091#else
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +000092 { ".bmark", TREE_ATTR_BMARK, -1, VOICE_EXT_BMARK },
Jörg Hohensohn8b813d02003-12-07 16:57:43 +000093#endif
94#ifndef SIMULATOR
Hardeep Sidhu162bf392003-12-11 18:26:32 +000095#ifdef HAVE_LCD_BITMAP
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +000096 { ".ucl", TREE_ATTR_UCL, Flashfile, VOICE_EXT_UCL },
97 { ".ajz", TREE_ATTR_MOD, Mod_Ajz, VOICE_EXT_AJZ },
Jörg Hohensohn8b813d02003-12-07 16:57:43 +000098#else
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +000099 { ".mod", TREE_ATTR_MOD, Mod_Ajz, VOICE_EXT_AJZ },
Jörg Hohensohn8b813d02003-12-07 16:57:43 +0000100#endif
101#endif /* #ifndef SIMULATOR */
102};
103
Björn Stenbergd1a6fa12003-06-05 09:38:26 +0000104/* Boot value of global_settings.max_files_in_dir */
105static int max_files_in_dir;
Björn Stenberg82182852002-05-16 12:53:40 +0000106
Linus Nielsen Feltzing20d031f2003-05-09 16:01:21 +0000107static char *name_buffer;
108static int name_buffer_size; /* Size of allocated buffer */
109static int name_buffer_length; /* Currently used amount */
Björn Stenberg82182852002-05-16 12:53:40 +0000110
Linus Nielsen Feltzing20d031f2003-05-09 16:01:21 +0000111static struct entry *dircache;
112
Eric Linenbergecca1232002-09-09 14:25:39 +0000113static int dircursor;
114static int dirstart;
115static int dirlevel;
Björn Stenberg361aaf62002-05-28 16:26:12 +0000116static int filesindir;
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +0000117static int dirsindir; /* how many of the dircache entries are directories */
Eric Linenbergecca1232002-09-09 14:25:39 +0000118static int dirpos[MAX_DIR_LEVELS];
119static int cursorpos[MAX_DIR_LEVELS];
120static char lastdir[MAX_PATH];
121static char lastfile[MAX_PATH];
122static char currdir[MAX_PATH];
Björn Stenbergde5477c2003-09-29 21:26:53 +0000123static char currdir_save[MAX_PATH];
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000124static bool reload_dir = false;
Björn Stenbergba5dfbd2003-06-29 22:39:35 +0000125static int boot_size = 0;
126static int boot_cluster;
127static bool boot_changed = false;
Björn Stenberg361aaf62002-05-28 16:26:12 +0000128
Björn Stenberga108ec22004-01-14 00:13:04 +0000129static bool start_wps = false;
Björn Stenbergde5477c2003-09-29 21:26:53 +0000130static bool dirbrowse(char *root, int *dirfilter);
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000131
Björn Stenberg82182852002-05-16 12:53:40 +0000132void browse_root(void)
133{
Mats Lidell816bc8c2003-01-31 08:43:12 +0000134#ifndef SIMULATOR
Björn Stenbergde5477c2003-09-29 21:26:53 +0000135 dirbrowse("/", &global_settings.dirfilter);
Mats Lidell816bc8c2003-01-31 08:43:12 +0000136#else
Björn Stenbergde5477c2003-09-29 21:26:53 +0000137 if (!dirbrowse("/", &global_settings.dirfilter)) {
Mats Lidell816bc8c2003-01-31 08:43:12 +0000138 DEBUGF("No filesystem found. Have you forgotten to create it?\n");
139 }
140#endif
Björn Stenberg82182852002-05-16 12:53:40 +0000141}
142
143
144#ifdef HAVE_LCD_BITMAP
145
Björn Stenberg8fb73122002-09-24 19:41:23 +0000146/* pixel margins */
147#define MARGIN_X (global_settings.scrollbar && \
148 filesindir > tree_max_on_screen ? SCROLLBAR_WIDTH : 0) + \
Björn Stenbergd1a6fa12003-06-05 09:38:26 +0000149 CURSOR_WIDTH + (global_settings.show_icons && ICON_WIDTH > 0 ? ICON_WIDTH :0)
Björn Stenberg8fb73122002-09-24 19:41:23 +0000150#define MARGIN_Y (global_settings.statusbar ? STATUSBAR_HEIGHT : 0)
Markus Braun000c2db2002-08-30 13:49:32 +0000151
Björn Stenberg8fb73122002-09-24 19:41:23 +0000152/* position the entry-list starts at */
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000153#define LINE_X 0
Björn Stenberg8fb73122002-09-24 19:41:23 +0000154#define LINE_Y (global_settings.statusbar ? 1 : 0)
Daniel Stenbergbf603f92002-06-14 08:47:44 +0000155
Björn Stenberg8fb73122002-09-24 19:41:23 +0000156#define CURSOR_X (global_settings.scrollbar && \
157 filesindir > tree_max_on_screen ? 1 : 0)
158#define CURSOR_Y 0 /* the cursor is not positioned in regard to
159 the margins, so this is the amount of lines
160 we add to the cursor Y position to position
161 it on a line */
Linus Nielsen Feltzinge43b78a2003-04-16 00:12:31 +0000162#define CURSOR_WIDTH (global_settings.invert_cursor ? 0 : 4)
Markus Braun000c2db2002-08-30 13:49:32 +0000163
164#define ICON_WIDTH 6
165
166#define SCROLLBAR_X 0
167#define SCROLLBAR_Y lcd_getymargin()
168#define SCROLLBAR_WIDTH 6
Björn Stenberg82182852002-05-16 12:53:40 +0000169
170extern unsigned char bitmap_icons_6x8[LastIcon][6];
Björn Stenberg82182852002-05-16 12:53:40 +0000171
172#else /* HAVE_LCD_BITMAP */
173
174#define TREE_MAX_ON_SCREEN 2
175#define TREE_MAX_LEN_DISPLAY 11 /* max length that fits on screen */
Linus Nielsen Feltzing10452d22002-09-03 07:53:51 +0000176#define LINE_X 2 /* X position the entry-list starts at */
Markus Braun000c2db2002-08-30 13:49:32 +0000177#define LINE_Y 0 /* Y position the entry-list starts at */
Björn Stenberg82182852002-05-16 12:53:40 +0000178
Markus Braun000c2db2002-08-30 13:49:32 +0000179#define CURSOR_X 0
Daniel Stenbergbf603f92002-06-14 08:47:44 +0000180#define CURSOR_Y 0 /* not really used for players */
Björn Stenberg9314a682002-05-31 09:04:51 +0000181
Björn Stenberg82182852002-05-16 12:53:40 +0000182#endif /* HAVE_LCD_BITMAP */
183
Björn Stenbergcf55acf2002-06-12 08:59:48 +0000184#ifdef HAVE_RECORDER_KEYPAD
185#define TREE_NEXT BUTTON_DOWN
186#define TREE_PREV BUTTON_UP
187#define TREE_EXIT BUTTON_LEFT
188#define TREE_ENTER BUTTON_RIGHT
189#define TREE_MENU BUTTON_F1
190#else
191#define TREE_NEXT BUTTON_RIGHT
192#define TREE_PREV BUTTON_LEFT
193#define TREE_EXIT BUTTON_STOP
194#define TREE_ENTER BUTTON_PLAY
195#define TREE_MENU BUTTON_MENU
196#endif /* HAVE_RECORDER_KEYPAD */
197
Jörg Hohensohn6e86b662004-03-28 10:21:58 +0000198/* talkbox hovering delay, to avoid immediate disk activity */
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +0000199#define HOVER_DELAY (HZ/2)
Jörg Hohensohn6e86b662004-03-28 10:21:58 +0000200
Linus Nielsen Feltzing1e02e982002-08-08 06:42:02 +0000201static int build_playlist(int start_index)
Linus Nielsen Feltzing4a4f17f2002-08-06 13:10:51 +0000202{
203 int i;
Björn Stenbergc9603302002-08-08 19:03:14 +0000204 int start=start_index;
Linus Nielsen Feltzing4a4f17f2002-08-06 13:10:51 +0000205
Linus Nielsen Feltzing8abcf1b2002-08-07 06:04:24 +0000206 for(i = 0;i < filesindir;i++)
Linus Nielsen Feltzing4a4f17f2002-08-06 13:10:51 +0000207 {
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +0000208 if((dircache[i].attr & TREE_ATTR_MASK) == TREE_ATTR_MPA
209 && (strcmp(dircache[i].name, dir_thumbnail_name) != 0))
Linus Nielsen Feltzing4a4f17f2002-08-06 13:10:51 +0000210 {
Linus Nielsen Feltzing5917e812002-08-15 12:28:52 +0000211 DEBUGF("Adding %s\n", dircache[i].name);
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000212 if (playlist_add(dircache[i].name) < 0)
213 break;
Linus Nielsen Feltzing4a4f17f2002-08-06 13:10:51 +0000214 }
Linus Nielsen Feltzing1e02e982002-08-08 06:42:02 +0000215 else
216 {
217 /* Adjust the start index when se skip non-MP3 entries */
Björn Stenbergc9603302002-08-08 19:03:14 +0000218 if(i < start)
Linus Nielsen Feltzing1e02e982002-08-08 06:42:02 +0000219 start_index--;
220 }
Linus Nielsen Feltzing4a4f17f2002-08-06 13:10:51 +0000221 }
Linus Nielsen Feltzing1e02e982002-08-08 06:42:02 +0000222
223 return start_index;
Linus Nielsen Feltzing4a4f17f2002-08-06 13:10:51 +0000224}
225
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +0000226
Jörg Hohensohn6e86b662004-03-28 10:21:58 +0000227static int play_dirname(int start_index)
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +0000228{
229 int fd;
230 char dirname_mp3_filename[MAX_PATH+1];
231
232 if (mpeg_status() & MPEG_STATUS_PLAY)
233 return 0;
234
235 snprintf(dirname_mp3_filename, sizeof(dirname_mp3_filename), "%s/%s/%s",
236 currdir, dircache[start_index].name, dir_thumbnail_name);
237
238 DEBUGF("Checking for %s\n", dirname_mp3_filename);
239
240 fd = open(dirname_mp3_filename, O_RDONLY);
241 if (fd < 0)
242 {
243 DEBUGF("Failed to find: %s\n", dirname_mp3_filename);
244 return -1;
245 }
246
247 close(fd);
248
249 DEBUGF("Found: %s\n", dirname_mp3_filename);
250
Jörg Hohensohn6e86b662004-03-28 10:21:58 +0000251 talk_file(dirname_mp3_filename, false);
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +0000252 return 1;
253}
254
255
Björn Stenbergbd44e602002-07-17 11:25:04 +0000256static int compare(const void* p1, const void* p2)
Björn Stenberg1fc4fee2002-05-30 14:01:36 +0000257{
Linus Nielsen Feltzing5917e812002-08-15 12:28:52 +0000258 struct entry* e1 = (struct entry*)p1;
259 struct entry* e2 = (struct entry*)p2;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000260
Björn Stenbergbd44e602002-07-17 11:25:04 +0000261 if (( e1->attr & ATTR_DIRECTORY ) == ( e2->attr & ATTR_DIRECTORY ))
Linus Nielsen Feltzingc132c482002-07-22 16:39:17 +0000262 if (global_settings.sort_case)
Linus Nielsen Feltzing5917e812002-08-15 12:28:52 +0000263 return strncmp(e1->name, e2->name, MAX_PATH);
Linus Nielsen Feltzingc132c482002-07-22 16:39:17 +0000264 else
Linus Nielsen Feltzing5917e812002-08-15 12:28:52 +0000265 return strncasecmp(e1->name, e2->name, MAX_PATH);
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000266 else
Björn Stenbergbd44e602002-07-17 11:25:04 +0000267 return ( e2->attr & ATTR_DIRECTORY ) - ( e1->attr & ATTR_DIRECTORY );
Björn Stenberg1fc4fee2002-05-30 14:01:36 +0000268}
269
Björn Stenbergde5477c2003-09-29 21:26:53 +0000270static void showfileline(int line, int direntry, bool scroll, int *dirfilter)
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +0000271{
Björn Stenbergd1a6fa12003-06-05 09:38:26 +0000272 char* name = dircache[direntry].name;
273 int xpos = LINE_X;
Linus Nielsen Feltzing8e204152004-03-17 14:46:06 +0000274 char* dotpos = NULL;
Björn Stenbergd1a6fa12003-06-05 09:38:26 +0000275
276#ifdef HAVE_LCD_CHARCELLS
277 if (!global_settings.show_icons)
278 xpos--;
279#endif
280
Björn Stenberg118316b2003-03-10 14:31:43 +0000281 /* if any file filter is on, strip the extension */
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000282 if (*dirfilter != SHOW_ALL &&
Björn Stenberg118316b2003-03-10 14:31:43 +0000283 !(dircache[direntry].attr & ATTR_DIRECTORY))
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +0000284 {
Linus Nielsen Feltzing8e204152004-03-17 14:46:06 +0000285 dotpos = strrchr(name, '.');
Björn Stenberg118316b2003-03-10 14:31:43 +0000286 if (dotpos) {
Björn Stenberg118316b2003-03-10 14:31:43 +0000287 *dotpos = 0;
288 }
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +0000289 }
Linus Nielsen Feltzing8e204152004-03-17 14:46:06 +0000290
291 if(scroll) {
Linus Nielsen Feltzinge43b78a2003-04-16 00:12:31 +0000292#ifdef HAVE_LCD_BITMAP
Linus Nielsen Feltzing8e204152004-03-17 14:46:06 +0000293 lcd_setfont(FONT_UI);
294 if (global_settings.invert_cursor)
295 lcd_puts_scroll_style(xpos, line, name, STYLE_INVERT);
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +0000296 else
Linus Nielsen Feltzing8e204152004-03-17 14:46:06 +0000297#endif
298 lcd_puts_scroll(xpos, line, name);
299 } else
300 lcd_puts(xpos, line, name);
301
302 /* Restore the dot before the extension if it was removed */
303 if (dotpos)
304 *dotpos = '.';
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +0000305}
306
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000307/* load sorted directory into dircache. returns NULL on failure. */
Björn Stenbergde5477c2003-09-29 21:26:53 +0000308struct entry* load_and_sort_directory(char *dirname, int *dirfilter,
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000309 int *num_files, bool *buffer_full)
310{
311 int i;
312
313 DIR *dir = opendir(dirname);
314 if(!dir)
315 return NULL; /* not a directory */
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000316
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000317 name_buffer_length = 0;
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +0000318 dirsindir = 0;
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000319 *buffer_full = false;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000320
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000321 for ( i=0; i < max_files_in_dir; i++ ) {
322 int len;
323 struct dirent *entry = readdir(dir);
324 struct entry* dptr = &dircache[i];
325 if (!entry)
326 break;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000327
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000328 len = strlen(entry->d_name);
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000329
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000330 /* skip directories . and .. */
331 if ((entry->attribute & ATTR_DIRECTORY) &&
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000332 (((len == 1) &&
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000333 (!strncmp(entry->d_name, ".", 1))) ||
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000334 ((len == 2) &&
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000335 (!strncmp(entry->d_name, "..", 2))))) {
336 i--;
337 continue;
338 }
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000339
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000340 /* Skip FAT volume ID */
341 if (entry->attribute & ATTR_VOLUME_ID) {
342 i--;
343 continue;
344 }
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000345
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000346 /* filter out dotfiles and hidden files */
Björn Stenbergde5477c2003-09-29 21:26:53 +0000347 if (*dirfilter != SHOW_ALL &&
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000348 ((entry->d_name[0]=='.') ||
349 (entry->attribute & ATTR_HIDDEN))) {
350 i--;
351 continue;
352 }
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000353
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000354 dptr->attr = entry->attribute;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000355
Jörg Hohensohn8b813d02003-12-07 16:57:43 +0000356 /* check for known file types */
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000357 if ( !(dptr->attr & ATTR_DIRECTORY) && (len > 4) )
Jörg Hohensohn8b813d02003-12-07 16:57:43 +0000358 {
359 unsigned j;
360 for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++)
361 {
362 if (!strcasecmp(
363 &entry->d_name[len-strlen(filetypes[j].extension)],
364 filetypes[j].extension))
365 {
366 dptr->attr |= filetypes[j].tree_attr;
367 break;
368 }
369 }
Jörg Hohensohn16948472003-10-30 23:48:36 +0000370 }
371
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000372 /* memorize/compare details about the boot file */
Björn Stenbergf11ffc02003-11-24 14:22:13 +0000373 if ((currdir[1] == 0) && !strcasecmp(entry->d_name, BOOTFILE)) {
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000374 if (boot_size) {
375 if ((entry->size != boot_size) ||
376 (entry->startcluster != boot_cluster))
377 boot_changed = true;
378 }
379 boot_size = entry->size;
380 boot_cluster = entry->startcluster;
381 }
382
Björn Stenbergde5477c2003-09-29 21:26:53 +0000383 /* filter out non-visible files */
Jörg Hohensohn8b813d02003-12-07 16:57:43 +0000384 if (!(dptr->attr & ATTR_DIRECTORY) && (
385 (*dirfilter == SHOW_PLAYLIST &&
386 (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_M3U) ||
387 ((*dirfilter == SHOW_MUSIC &&
388 (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_MPA) &&
389 (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_M3U) ||
Björn Stenbergde5477c2003-09-29 21:26:53 +0000390 (*dirfilter == SHOW_SUPPORTED && !(dptr->attr & TREE_ATTR_MASK)) ||
Jörg Hohensohn8b813d02003-12-07 16:57:43 +0000391 (*dirfilter == SHOW_WPS && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_WPS) ||
392 (*dirfilter == SHOW_CFG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_CFG) ||
393 (*dirfilter == SHOW_LNG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_LNG) ||
394 (*dirfilter == SHOW_MOD && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_MOD) ||
395 (*dirfilter == SHOW_FONT && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_FONT) ||
396 (*dirfilter == SHOW_PLUGINS && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_ROCK)))
Björn Stenbergde5477c2003-09-29 21:26:53 +0000397 {
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000398 i--;
399 continue;
400 }
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000401
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000402 if (len > name_buffer_size - name_buffer_length - 1) {
403 /* Tell the world that we ran out of buffer space */
404 *buffer_full = true;
405 break;
406 }
407 dptr->name = &name_buffer[name_buffer_length];
408 strcpy(dptr->name,entry->d_name);
409 name_buffer_length += len + 1;
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +0000410
411 if (dptr->attr & ATTR_DIRECTORY) /* count the remaining dirs */
412 dirsindir++;
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000413 }
414 *num_files = i;
415 closedir(dir);
416 strncpy(lastdir,dirname,sizeof(lastdir));
417 lastdir[sizeof(lastdir)-1] = 0;
418 qsort(dircache,i,sizeof(struct entry),compare);
419
420 return dircache;
421}
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +0000422
Linus Nielsen Feltzing77936e62004-03-16 13:44:56 +0000423#ifdef HAVE_LCD_BITMAP
424static int recalc_screen_height(void)
425{
426 int fw, fh;
427 int height = LCD_HEIGHT;
428
429 lcd_setfont(FONT_UI);
430 lcd_getstringsize("A", &fw, &fh);
431 if(global_settings.statusbar)
432 height -= STATUSBAR_HEIGHT;
433
434 if(global_settings.buttonbar)
435 height -= BUTTONBAR_HEIGHT;
436
437 return height / fh;
438}
439#endif
440
Björn Stenbergde5477c2003-09-29 21:26:53 +0000441static int showdir(char *path, int start, int *dirfilter)
Björn Stenberg82182852002-05-16 12:53:40 +0000442{
Björn Stenberg82182852002-05-16 12:53:40 +0000443 int icon_type = 0;
Björn Stenberg82182852002-05-16 12:53:40 +0000444 int i;
Björn Stenbergcd225732002-08-11 09:17:47 +0000445 int tree_max_on_screen;
Linus Nielsen Feltzing5917e812002-08-15 12:28:52 +0000446 bool dir_buffer_full;
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000447
448#ifdef HAVE_LCD_BITMAP
Björn Stenberg8fb73122002-09-24 19:41:23 +0000449 int line_height;
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000450 int fw, fh;
Björn Stenberga4c3b032002-09-24 18:04:15 +0000451 lcd_setfont(FONT_UI);
452 lcd_getstringsize("A", &fw, &fh);
Linus Nielsen Feltzing77936e62004-03-16 13:44:56 +0000453 tree_max_on_screen = recalc_screen_height();
Björn Stenbergcd225732002-08-11 09:17:47 +0000454 line_height = fh;
455#else
456 tree_max_on_screen = TREE_MAX_ON_SCREEN;
457#endif
458
Björn Stenberg361aaf62002-05-28 16:26:12 +0000459 /* new dir? cache it */
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000460 if (strncmp(path,lastdir,sizeof(lastdir)) || reload_dir) {
Björn Stenbergde5477c2003-09-29 21:26:53 +0000461 if (!load_and_sort_directory(path, dirfilter,
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000462 &filesindir, &dir_buffer_full))
463 return -1;
Björn Stenberge33d66a2002-08-12 22:52:19 +0000464
Linus Nielsen Feltzing20d031f2003-05-09 16:01:21 +0000465 if ( dir_buffer_full || filesindir == max_files_in_dir ) {
Linus Nielsen Feltzing0a4b2472002-10-15 12:25:57 +0000466#ifdef HAVE_LCD_CHARCELLS
Björn Stenberge33d66a2002-08-12 22:52:19 +0000467 lcd_double_height(false);
468#endif
469 lcd_clear_display();
Björn Stenberg505eca72002-09-18 14:08:05 +0000470 lcd_puts(0,0,str(LANG_SHOWDIR_ERROR_BUFFER));
471 lcd_puts(0,1,str(LANG_SHOWDIR_ERROR_FULL));
Björn Stenberge33d66a2002-08-12 22:52:19 +0000472 lcd_update();
473 sleep(HZ*2);
474 lcd_clear_display();
475 }
Björn Stenberg361aaf62002-05-28 16:26:12 +0000476 }
Björn Stenberg1d322652002-05-31 12:11:22 +0000477
Eric Linenbergecca1232002-09-09 14:25:39 +0000478 if (start == -1)
479 {
Hardeep Sidhuddfa4cb2002-09-09 17:32:15 +0000480 int diff_files;
481
Eric Linenbergecca1232002-09-09 14:25:39 +0000482 /* use lastfile to determine start (default=0) */
Hardeep Sidhuddfa4cb2002-09-09 17:32:15 +0000483 start = 0;
484
Eric Linenbergecca1232002-09-09 14:25:39 +0000485 for (i=0; i<filesindir; i++)
486 {
487 if (!strcasecmp(dircache[i].name, lastfile))
488 {
Hardeep Sidhuddfa4cb2002-09-09 17:32:15 +0000489 start = i;
Eric Linenbergecca1232002-09-09 14:25:39 +0000490 break;
491 }
492 }
Hardeep Sidhuddfa4cb2002-09-09 17:32:15 +0000493
494 diff_files = filesindir - start;
495 if (diff_files < tree_max_on_screen)
496 {
497 int oldstart = start;
498
499 start -= (tree_max_on_screen - diff_files);
500 if (start < 0)
501 start = 0;
502
503 dircursor = oldstart - start;
504 }
505
506 dirstart = start;
Eric Linenbergecca1232002-09-09 14:25:39 +0000507 }
508
Linus Nielsen Feltzing57e928f2003-04-14 07:53:58 +0000509 /* The cursor might point to an invalid line, for example if someone
510 deleted the last file in the dir */
511 if(filesindir)
512 {
513 while(start + dircursor >= filesindir)
514 {
515 if(start)
516 start--;
517 else
518 if(dircursor)
519 dircursor--;
520 }
521 dirstart = start;
522 }
523
Linus Nielsen Feltzing0a4b2472002-10-15 12:25:57 +0000524#ifdef HAVE_LCD_CHARCELLS
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +0000525 lcd_stop_scroll();
Björn Stenberg39526922002-05-31 11:16:25 +0000526 lcd_double_height(false);
527#endif
Björn Stenberg361aaf62002-05-28 16:26:12 +0000528 lcd_clear_display();
Björn Stenberg82182852002-05-16 12:53:40 +0000529#ifdef HAVE_LCD_BITMAP
Björn Stenbergf385e362002-08-13 20:55:08 +0000530 lcd_setmargins(MARGIN_X,MARGIN_Y); /* leave room for cursor and icon */
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000531 lcd_setfont(FONT_UI);
Björn Stenberg82182852002-05-16 12:53:40 +0000532#endif
533
Björn Stenbergcd225732002-08-11 09:17:47 +0000534 for ( i=start; i < start+tree_max_on_screen; i++ ) {
Björn Stenbergf03d6912002-05-29 08:18:46 +0000535 int len;
Jörg Hohensohn8b813d02003-12-07 16:57:43 +0000536 unsigned j;
Björn Stenbergf03d6912002-05-29 08:18:46 +0000537
538 if ( i >= filesindir )
539 break;
540
Linus Nielsen Feltzing5917e812002-08-15 12:28:52 +0000541 len = strlen(dircache[i].name);
Björn Stenberg361aaf62002-05-28 16:26:12 +0000542
Jörg Hohensohn8b813d02003-12-07 16:57:43 +0000543 if (dircache[i].attr & ATTR_DIRECTORY)
544 {
545 icon_type = Folder;
546 }
547 else
548 {
549 /* search which icon to use */
550 icon_type = -1; /* default to none */
551 for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++)
552 {
553 if ((dircache[i].attr & TREE_ATTR_MASK) == filetypes[j].tree_attr)
554 {
555 icon_type = filetypes[j].icon;
556 break;
557 }
558 }
Björn Stenbergf1bf9e72002-08-23 22:15:51 +0000559
Jörg Hohensohn8b813d02003-12-07 16:57:43 +0000560 if (icon_type == -1)
561 {
Kjell Ericsonc11b90f2003-01-10 09:55:50 +0000562#ifdef HAVE_LCD_BITMAP
Björn Stenbergc521ed12002-09-03 09:44:08 +0000563 icon_type = 0;
Kjell Ericsonc11b90f2003-01-10 09:55:50 +0000564#else
565 icon_type = Unknown;
566#endif
Jörg Hohensohn8b813d02003-12-07 16:57:43 +0000567 }
Björn Stenbergc521ed12002-09-03 09:44:08 +0000568 }
Björn Stenberg0ad20102002-09-03 20:47:23 +0000569
Björn Stenbergd1a6fa12003-06-05 09:38:26 +0000570 if (icon_type && global_settings.show_icons) {
Linus Nielsen Feltzing10452d22002-09-03 07:53:51 +0000571#ifdef HAVE_LCD_BITMAP
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000572 int offset=0;
573 if ( line_height > 8 )
574 offset = (line_height - 8) / 2;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000575 lcd_bitmap(bitmap_icons_6x8[icon_type],
576 CURSOR_X * 6 + CURSOR_WIDTH,
Björn Stenbergbed3d3f2002-09-20 08:07:51 +0000577 MARGIN_Y+(i-start)*line_height + offset,
578 6, 8, true);
Linus Nielsen Feltzing10452d22002-09-03 07:53:51 +0000579#else
Kjell Ericsonc11b90f2003-01-10 09:55:50 +0000580 lcd_putc(LINE_X-1, i-start, icon_type);
Björn Stenberg361aaf62002-05-28 16:26:12 +0000581#endif
Björn Stenberg0ad20102002-09-03 20:47:23 +0000582 }
Björn Stenberg361aaf62002-05-28 16:26:12 +0000583
Björn Stenbergde5477c2003-09-29 21:26:53 +0000584 showfileline(i-start, i, false, dirfilter); /* no scroll */
Björn Stenberg82182852002-05-16 12:53:40 +0000585 }
586
Markus Braun000c2db2002-08-30 13:49:32 +0000587#ifdef HAVE_LCD_BITMAP
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000588 if (global_settings.scrollbar && (filesindir > tree_max_on_screen))
Markus Braun000c2db2002-08-30 13:49:32 +0000589 scrollbar(SCROLLBAR_X, SCROLLBAR_Y, SCROLLBAR_WIDTH - 1,
Linus Nielsen Feltzing77936e62004-03-16 13:44:56 +0000590 tree_max_on_screen * line_height, filesindir, start,
Markus Braun000c2db2002-08-30 13:49:32 +0000591 start + tree_max_on_screen, VERTICAL);
Linus Nielsen Feltzing77936e62004-03-16 13:44:56 +0000592
593 if(global_settings.buttonbar) {
594 buttonbar_set(str(LANG_DIRBROWSE_F1),
595 str(LANG_DIRBROWSE_F2),
596 str(LANG_DIRBROWSE_F3));
597 buttonbar_draw();
598 }
Markus Braun000c2db2002-08-30 13:49:32 +0000599#endif
Björn Stenberg6cafc142003-04-23 14:38:25 +0000600 status_draw(true);
Linus Nielsen Feltzing77936e62004-03-16 13:44:56 +0000601
Björn Stenberg361aaf62002-05-28 16:26:12 +0000602 return filesindir;
Björn Stenberg82182852002-05-16 12:53:40 +0000603}
604
Linus Nielsen Feltzing6e49e782003-07-08 09:19:12 +0000605static bool ask_resume(bool ask_once)
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000606{
Björn Stenberg7f677172003-08-06 17:30:40 +0000607 bool stop = false;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000608
Linus Nielsen Feltzing0a4b2472002-10-15 12:25:57 +0000609#ifdef HAVE_LCD_CHARCELLS
Björn Stenberg1b057522002-08-20 20:27:36 +0000610 lcd_double_height(false);
611#endif
612
Björn Stenberg98912302004-01-20 22:39:32 +0000613 if (usb_detect()) {
614 usb_screen();
615 return false;
616 }
617
Björn Stenbergf2106062002-08-19 10:57:55 +0000618 /* always resume? */
619 if ( global_settings.resume == RESUME_ON )
620 return true;
621
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000622 lcd_clear_display();
Björn Stenberg505eca72002-09-18 14:08:05 +0000623 lcd_puts(0,0,str(LANG_RESUME_ASK));
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000624#ifdef HAVE_LCD_CHARCELLS
Björn Stenberg942bc942003-04-23 11:26:25 +0000625 status_draw(false);
Björn Stenberg505eca72002-09-18 14:08:05 +0000626 lcd_puts(0,1,str(LANG_RESUME_CONFIRM_PLAYER));
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000627#else
Robert Hakb88f2bc2003-06-25 08:25:29 +0000628 lcd_puts(0,1,str(LANG_CONFIRM_WITH_PLAY_RECORDER));
629 lcd_puts(0,2,str(LANG_CANCEL_WITH_ANY_RECORDER));
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000630#endif
631 lcd_update();
Robert Hakc88751f2002-10-16 07:25:33 +0000632
Björn Stenberg7f677172003-08-06 17:30:40 +0000633 while (!stop) {
634 switch (button_get(true)) {
635 case BUTTON_PLAY:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000636#ifdef BUTTON_RC_PLAY
Björn Stenberg7f677172003-08-06 17:30:40 +0000637 case BUTTON_RC_PLAY:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000638#endif
Björn Stenberg7f677172003-08-06 17:30:40 +0000639 return true;
Björn Stenbergbb3685e2003-01-28 16:08:10 +0000640
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000641#ifdef BUTTON_ON
Björn Stenberg7f677172003-08-06 17:30:40 +0000642 /* ignore the ON button, since it might
643 still be pressed since booting */
644 case BUTTON_ON:
645 case BUTTON_ON | BUTTON_REL:
Björn Stenbergc9184052003-11-14 16:10:38 +0000646 case BUTTON_ON | BUTTON_REPEAT:
Björn Stenberg7f677172003-08-06 17:30:40 +0000647 break;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000648#endif
649
Björn Stenberg7f677172003-08-06 17:30:40 +0000650 case SYS_USB_CONNECTED:
651 usb_screen();
652 stop = true;
653 break;
654
655 default:
656 stop = true;
657 break;
658 }
Björn Stenbergbb3685e2003-01-28 16:08:10 +0000659 }
Hardeep Sidhu86a44992003-01-15 22:46:49 +0000660
Linus Nielsen Feltzing6e49e782003-07-08 09:19:12 +0000661 if ( global_settings.resume == RESUME_ASK_ONCE && ask_once) {
Hardeep Sidhu86a44992003-01-15 22:46:49 +0000662 global_settings.resume_index = -1;
663 settings_save();
664 }
665
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000666 return false;
667}
668
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000669/* load tracks from specified directory to resume play */
670void resume_directory(char *dir)
671{
672 bool buffer_full;
673
Björn Stenbergde5477c2003-09-29 21:26:53 +0000674 if (!load_and_sort_directory(dir, &global_settings.dirfilter, &filesindir,
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000675 &buffer_full))
676 return;
677 lastdir[0] = 0;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000678
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000679 build_playlist(0);
680}
681
682/* Returns the current working directory and also writes cwd to buf if
683 non-NULL. In case of error, returns NULL. */
684char *getcwd(char *buf, int size)
685{
686 if (!buf)
687 return currdir;
688 else if (size > 0)
689 {
690 strncpy(buf, currdir, size);
691 return buf;
692 }
693 else
694 return NULL;
695}
696
697/* Force a reload of the directory next time directory browser is called */
698void reload_directory(void)
699{
700 reload_dir = true;
701}
702
Linus Nielsen Feltzing6e49e782003-07-08 09:19:12 +0000703static void start_resume(bool ask_once)
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000704{
705 if ( global_settings.resume &&
706 global_settings.resume_index != -1 ) {
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000707 DEBUGF("Resume index %X offset %X\n",
708 global_settings.resume_index,
709 global_settings.resume_offset);
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000710
Linus Nielsen Feltzing6e49e782003-07-08 09:19:12 +0000711 if (!ask_resume(ask_once))
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000712 return;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000713
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000714 if (playlist_resume() != -1)
715 {
716 playlist_start(global_settings.resume_index,
717 global_settings.resume_offset);
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000718
Björn Stenberga108ec22004-01-14 00:13:04 +0000719 start_wps = true;
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000720 }
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000721 else
722 return;
Björn Stenberg6224cdb2002-08-16 14:41:47 +0000723 }
724}
725
Eric Linenbergecca1232002-09-09 14:25:39 +0000726void set_current_file(char *path)
727{
728 char *name;
729 unsigned int i;
730
731 /* separate directory from filename */
Hardeep Sidhuc2c8d1c2002-09-17 07:42:21 +0000732 name = strrchr(path+1,'/');
Eric Linenbergecca1232002-09-09 14:25:39 +0000733 if (name)
734 {
735 *name = 0;
736 strcpy(currdir, path);
737 *name = '/';
738 name++;
739 }
740 else
741 {
742 strcpy(currdir, "/");
743 name = path+1;
744 }
745
746 strcpy(lastfile, name);
747
748 dircursor = 0;
749 dirstart = -1;
750
751 if (strncmp(currdir,lastdir,sizeof(lastdir)))
752 {
753 dirlevel = 0;
754 dirpos[dirlevel] = -1;
755 cursorpos[dirlevel] = 0;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000756
Eric Linenbergecca1232002-09-09 14:25:39 +0000757 /* use '/' to calculate dirlevel */
758 for (i=1; i<strlen(path)+1; i++)
759 {
760 if (path[i] == '/')
761 {
762 dirlevel++;
763 dirpos[dirlevel] = -1;
764 cursorpos[dirlevel] = 0;
765 }
766 }
767 }
768}
769
Daniel Stenberg14c54cc2003-12-15 11:48:36 +0000770#ifdef BUTTON_ON
Björn Stenbergde5477c2003-09-29 21:26:53 +0000771static bool handle_on(int *ds, int *dc, int numentries, int tree_max_on_screen, int *dirfilter)
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000772{
773 bool exit = false;
774 bool used = false;
775
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +0000776 int dirstart = *ds;
777 int dircursor = *dc;
Björn Stenbergd7a55e12003-03-12 20:21:30 +0000778 char buf[MAX_PATH];
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +0000779
Linus Nielsen Feltzinge43b78a2003-04-16 00:12:31 +0000780#ifdef HAVE_LCD_BITMAP
781 int fw, fh;
782 lcd_getstringsize("A", &fw, &fh);
783#endif
784
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +0000785 while (!exit) {
786 switch (button_get(true)) {
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000787 case TREE_PREV:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000788#ifdef BUTTON_RC_LEFT
Björn Stenberg28cce682003-04-23 09:21:37 +0000789 case BUTTON_RC_LEFT:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000790#endif
791#ifdef BUTTON_ON
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000792 case BUTTON_ON | TREE_PREV:
793 case BUTTON_ON | TREE_PREV | BUTTON_REPEAT:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000794#endif
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +0000795 used = true;
796 if ( dirstart ) {
797 dirstart -= tree_max_on_screen;
798 if ( dirstart < 0 )
799 dirstart = 0;
800 }
801 else
802 dircursor = 0;
803 break;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000804
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000805 case TREE_NEXT:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000806#ifdef BUTTON_RC_RIGHT
Björn Stenberg28cce682003-04-23 09:21:37 +0000807 case BUTTON_RC_RIGHT:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000808#endif
809#ifdef BUTTON_ON
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000810 case BUTTON_ON | TREE_NEXT:
811 case BUTTON_ON | TREE_NEXT | BUTTON_REPEAT:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000812#endif
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +0000813 used = true;
814 if ( dirstart < numentries - tree_max_on_screen ) {
815 dirstart += tree_max_on_screen;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000816 if ( dirstart >
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +0000817 numentries - tree_max_on_screen )
818 dirstart = numentries - tree_max_on_screen;
819 }
820 else
821 dircursor = numentries - dirstart - 1;
822 break;
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000823
824
825 case BUTTON_PLAY:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000826#ifdef BUTTON_RC_PLAY
Björn Stenberg28cce682003-04-23 09:21:37 +0000827 case BUTTON_RC_PLAY:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000828#endif
829#ifdef BUTTON_ON
830 case BUTTON_ON | BUTTON_PLAY:
831#endif
832 {
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000833 int onplay_result;
834
Linus Nielsen Feltzingef7293f2004-01-21 14:58:40 +0000835 if(!numentries)
Linus Nielsen Feltzing642cce22004-03-11 10:43:53 +0000836 onplay_result = onplay(NULL, 0);
837 else {
838 if (currdir[1])
839 snprintf(buf, sizeof buf, "%s/%s",
840 currdir, dircache[dircursor+dirstart].name);
841 else
842 snprintf(buf, sizeof buf, "/%s",
843 dircache[dircursor+dirstart].name);
844 onplay_result = onplay(buf,
845 dircache[dircursor+dirstart].attr);
846 }
Linus Nielsen Feltzingef7293f2004-01-21 14:58:40 +0000847
Hardeep Sidhu9e426202003-07-01 21:05:43 +0000848 switch (onplay_result)
849 {
850 case ONPLAY_OK:
851 used = true;
852 break;
853 case ONPLAY_RELOAD_DIR:
854 reload_dir = 1;
855 used = true;
856 break;
857 case ONPLAY_START_PLAY:
858 used = false; /* this will enable the wps */
859 break;
860 }
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000861 exit = true;
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000862 break;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000863 }
864#ifdef BUTTON_ON
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +0000865 case BUTTON_ON | BUTTON_REL:
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000866 case BUTTON_ON | TREE_PREV | BUTTON_REL:
867 case BUTTON_ON | TREE_NEXT | BUTTON_REL:
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +0000868 exit = true;
869 break;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000870#endif
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +0000871 }
Björn Stenbergcaebdd42003-01-15 14:52:53 +0000872 if ( used && !exit ) {
Linus Nielsen Feltzinge43b78a2003-04-16 00:12:31 +0000873#ifdef HAVE_LCD_BITMAP
874 int xpos,ypos;
875#endif
Björn Stenbergde5477c2003-09-29 21:26:53 +0000876 showdir(currdir, dirstart, dirfilter);
Linus Nielsen Feltzinge43b78a2003-04-16 00:12:31 +0000877#ifdef HAVE_LCD_BITMAP
878 if (global_settings.invert_cursor) {
879 xpos = lcd_getxmargin();
880 ypos = (CURSOR_Y + dircursor) * fh + lcd_getymargin();
881 lcd_invertrect(xpos, ypos, LCD_WIDTH-xpos, fh);
882 }
883 else
884#endif
885 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true);
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +0000886 lcd_update();
887 }
888 }
889 *ds = dirstart;
890 *dc = dircursor;
891
892 return used;
893}
Daniel Stenberg14c54cc2003-12-15 11:48:36 +0000894#endif
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +0000895
Björn Stenbergde5477c2003-09-29 21:26:53 +0000896static bool dirbrowse(char *root, int *dirfilter)
Björn Stenberg82182852002-05-16 12:53:40 +0000897{
Björn Stenberg079b2d12002-08-08 12:06:38 +0000898 int numentries=0;
Linus Nielsen Feltzing8c57ad92002-07-15 22:46:38 +0000899 char buf[MAX_PATH];
Björn Stenberg82182852002-05-16 12:53:40 +0000900 int i;
Markus Braunde8fbf02002-08-07 10:35:26 +0000901 int lasti=-1;
Linus Nielsen Feltzingb3d0b6e2002-07-27 19:41:58 +0000902 int button;
Björn Stenbergcd225732002-08-11 09:17:47 +0000903 int tree_max_on_screen;
Björn Stenberg0ad20102002-09-03 20:47:23 +0000904 bool reload_root = false;
Björn Stenbergde5477c2003-09-29 21:26:53 +0000905 int lastfilter = *dirfilter;
Björn Stenberg0ad20102002-09-03 20:47:23 +0000906 bool lastsortcase = global_settings.sort_case;
Kjell Ericson767d6042003-01-23 14:28:16 +0000907 int lastdircursor=-1;
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +0000908 bool need_update = true;
Björn Stenbergde5477c2003-09-29 21:26:53 +0000909 bool exit_func = false;
Jörg Hohensohn6e86b662004-03-28 10:21:58 +0000910 bool enqueue_next = false;
911 long thumbnail_time = -1; /* for delaying a thumbnail */
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +0000912 bool update_all = false; /* set this to true when the whole file list
913 has been refreshed on screen */
914
Daniel Stenberg93b231c2002-09-12 13:33:59 +0000915#ifdef HAVE_LCD_BITMAP
Linus Nielsen Feltzing77936e62004-03-16 13:44:56 +0000916 tree_max_on_screen = recalc_screen_height();
Björn Stenbergcd225732002-08-11 09:17:47 +0000917#else
918 tree_max_on_screen = TREE_MAX_ON_SCREEN;
919#endif
Björn Stenberg82182852002-05-16 12:53:40 +0000920
Eric Linenbergecca1232002-09-09 14:25:39 +0000921 dircursor=0;
922 dirstart=0;
923 dirlevel=0;
924
Björn Stenberg82182852002-05-16 12:53:40 +0000925 memcpy(currdir,root,sizeof(currdir));
Hardeep Sidhuddfa4cb2002-09-09 17:32:15 +0000926
Björn Stenbergde5477c2003-09-29 21:26:53 +0000927 if (*dirfilter < NUM_FILTER_MODES)
Linus Nielsen Feltzingf97756e2003-11-04 16:47:05 +0000928 start_resume(true);
Hardeep Sidhuddfa4cb2002-09-09 17:32:15 +0000929
Björn Stenbergde5477c2003-09-29 21:26:53 +0000930 numentries = showdir(currdir, dirstart, dirfilter);
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000931 if (numentries == -1)
Mats Lidell816bc8c2003-01-31 08:43:12 +0000932 return false; /* currdir is not a directory */
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000933
Linus Nielsen Feltzingf97756e2003-11-04 16:47:05 +0000934 if (*dirfilter > NUM_FILTER_MODES && numentries==0)
935 {
Daniel Stenberg1afa3952004-01-08 09:58:58 +0000936 splash(HZ*2, true, str(LANG_NO_FILES));
Linus Nielsen Feltzingf97756e2003-11-04 16:47:05 +0000937 return false; /* No files found for rockbox_browser() */
938 }
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000939
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +0000940 update_all = true;
Björn Stenberg82182852002-05-16 12:53:40 +0000941
Markus Braun000c2db2002-08-30 13:49:32 +0000942 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true);
Björn Stenberg82182852002-05-16 12:53:40 +0000943
944 while(1) {
Eric Linenbergecca1232002-09-09 14:25:39 +0000945 struct entry* file = &dircache[dircursor+dirstart];
Björn Stenberg1a682be2002-09-02 12:46:32 +0000946
Björn Stenbergbb9aaf52002-06-25 13:26:04 +0000947 bool restore = false;
Daniel Stenberg1a17d352002-06-18 11:22:48 +0000948
Markus Braunde8fbf02002-08-07 10:35:26 +0000949 button = button_get_w_tmo(HZ/5);
Björn Stenbergba5dfbd2003-06-29 22:39:35 +0000950
951#ifndef SIMULATOR
952 if (boot_changed) {
Henrik Backebe21ab82004-03-21 18:56:06 +0000953 bool stop = false;
954
Björn Stenbergba5dfbd2003-06-29 22:39:35 +0000955 lcd_clear_display();
956 lcd_puts(0,0,str(LANG_BOOT_CHANGED));
957 lcd_puts(0,1,str(LANG_REBOOT_NOW));
958#ifdef HAVE_LCD_BITMAP
959 lcd_puts(0,3,str(LANG_CONFIRM_WITH_PLAY_RECORDER));
960 lcd_puts(0,4,str(LANG_CANCEL_WITH_ANY_RECORDER));
961 lcd_update();
962#endif
Henrik Backebe21ab82004-03-21 18:56:06 +0000963 while (!stop) {
964 switch (button_get(true)) {
965 case BUTTON_PLAY:
966 rolo_load("/" BOOTFILE);
967 stop = true;
968 break;
969
970 case SYS_USB_CONNECTED:
971 usb_screen();
972 stop = true;
973 break;
974
975 default:
976 stop = true;
977 break;
978 }
979 }
980
Björn Stenbergba5dfbd2003-06-29 22:39:35 +0000981 restore = true;
982 boot_changed = false;
983 }
984#endif
985
Linus Nielsen Feltzingf140b202002-07-27 20:55:39 +0000986 switch ( button ) {
Björn Stenbergcf55acf2002-06-12 08:59:48 +0000987 case TREE_EXIT:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000988#ifdef BUTTON_RC_STOP
Björn Stenberg28cce682003-04-23 09:21:37 +0000989 case BUTTON_RC_STOP:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +0000990#endif
Björn Stenberg461d6e32003-12-04 00:08:25 +0000991#ifdef HAVE_RECORDER_KEYPAD
992 case BUTTON_LEFT | BUTTON_REPEAT:
993#endif
Björn Stenberg82182852002-05-16 12:53:40 +0000994 i=strlen(currdir);
Björn Stenberge493efd2002-05-21 14:30:54 +0000995 if (i>1) {
Björn Stenberg82182852002-05-16 12:53:40 +0000996 while (currdir[i-1]!='/')
997 i--;
998 strcpy(buf,&currdir[i]);
999 if (i==1)
1000 currdir[i]=0;
1001 else
1002 currdir[i-1]=0;
1003
Björn Stenberg82182852002-05-16 12:53:40 +00001004 dirlevel--;
Björn Stenberg2b203ca2002-05-31 07:19:38 +00001005 if ( dirlevel < MAX_DIR_LEVELS ) {
Eric Linenbergecca1232002-09-09 14:25:39 +00001006 dirstart = dirpos[dirlevel];
Björn Stenberg2b203ca2002-05-31 07:19:38 +00001007 dircursor = cursorpos[dirlevel];
1008 }
Björn Stenberg82182852002-05-16 12:53:40 +00001009 else
Eric Linenbergecca1232002-09-09 14:25:39 +00001010 dirstart = dircursor = 0;
1011
1012 if (dirstart == -1)
1013 strcpy(lastfile, buf);
1014
Björn Stenbergbb9aaf52002-06-25 13:26:04 +00001015 restore = true;
Björn Stenberga10d9fa2002-05-27 14:55:40 +00001016 }
Björn Stenbergde5477c2003-09-29 21:26:53 +00001017 if (*dirfilter > NUM_FILTER_MODES)
1018 exit_func = true;
Björn Stenberg82182852002-05-16 12:53:40 +00001019 break;
Björn Stenberg6224cdb2002-08-16 14:41:47 +00001020
Daniel Stenberg82a1cad2002-08-06 09:25:45 +00001021#ifdef HAVE_RECORDER_KEYPAD
1022 case BUTTON_OFF:
Björn Stenberga108ec22004-01-14 00:13:04 +00001023 bookmark_autobookmark();
Daniel Stenberg82a1cad2002-08-06 09:25:45 +00001024 mpeg_stop();
Daniel Stenberg82a1cad2002-08-06 09:25:45 +00001025 status_set_playmode(STATUS_STOP);
Björn Stenberg942bc942003-04-23 11:26:25 +00001026 status_draw(false);
Markus Braunde8fbf02002-08-07 10:35:26 +00001027 restore = true;
Daniel Stenberg82a1cad2002-08-06 09:25:45 +00001028 break;
Björn Stenberg6224cdb2002-08-16 14:41:47 +00001029
1030 case BUTTON_OFF | BUTTON_REL:
1031#else
1032 case BUTTON_STOP | BUTTON_REL:
Daniel Stenberg82a1cad2002-08-06 09:25:45 +00001033#endif
Björn Stenberg6224cdb2002-08-16 14:41:47 +00001034 settings_save();
1035 break;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001036
Björn Stenberg461d6e32003-12-04 00:08:25 +00001037#ifdef HAVE_RECORDER_KEYPAD
1038 case BUTTON_OFF | BUTTON_REPEAT:
1039#else
1040 case BUTTON_STOP | BUTTON_REPEAT:
1041#endif
1042 if (charger_inserted()) {
1043 charging_splash();
1044 restore = true;
1045 }
1046 break;
Björn Stenberg82182852002-05-16 12:53:40 +00001047
Björn Stenbergcaebdd42003-01-15 14:52:53 +00001048 case TREE_ENTER:
Björn Stenberg407bfb02002-09-01 14:49:56 +00001049 case TREE_ENTER | BUTTON_REPEAT:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001050#ifdef BUTTON_RC_PLAY
Björn Stenberg28cce682003-04-23 09:21:37 +00001051 case BUTTON_RC_PLAY:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001052#endif
Björn Stenbergc00557a2002-06-25 11:10:24 +00001053#ifdef HAVE_RECORDER_KEYPAD
Björn Stenbergcaebdd42003-01-15 14:52:53 +00001054 case BUTTON_PLAY:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001055 case BUTTON_PLAY | BUTTON_REPEAT:
Björn Stenbergc00557a2002-06-25 11:10:24 +00001056#endif
Björn Stenberg8b1aba82002-06-19 20:10:58 +00001057 if ( !numentries )
1058 break;
Björn Stenberg10abfec2003-03-11 09:57:46 +00001059 if (currdir[1])
Björn Stenberg1a682be2002-09-02 12:46:32 +00001060 snprintf(buf,sizeof(buf),"%s/%s",currdir, file->name);
Björn Stenberg10abfec2003-03-11 09:57:46 +00001061 else
1062 snprintf(buf,sizeof(buf),"/%s",file->name);
Björn Stenberg82182852002-05-16 12:53:40 +00001063
Björn Stenberg1a682be2002-09-02 12:46:32 +00001064 if (file->attr & ATTR_DIRECTORY) {
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +00001065 if (global_settings.talk_dir == 3) /* enter */
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +00001066 {
1067 /* play_dirname */
1068 DEBUGF("Playing directory thumbnail: %s", currdir);
Jörg Hohensohn6e86b662004-03-28 10:21:58 +00001069 play_dirname(dircursor+dirstart);
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +00001070 /* avoid reading getting cut by next filename */
1071 enqueue_next = true;
1072 }
Björn Stenberg82182852002-05-16 12:53:40 +00001073 memcpy(currdir,buf,sizeof(currdir));
Björn Stenberg2b203ca2002-05-31 07:19:38 +00001074 if ( dirlevel < MAX_DIR_LEVELS ) {
Eric Linenbergecca1232002-09-09 14:25:39 +00001075 dirpos[dirlevel] = dirstart;
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001076 cursorpos[dirlevel] = dircursor;
Björn Stenberg2b203ca2002-05-31 07:19:38 +00001077 }
Björn Stenberg82182852002-05-16 12:53:40 +00001078 dirlevel++;
1079 dircursor=0;
Eric Linenbergecca1232002-09-09 14:25:39 +00001080 dirstart=0;
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +00001081 }
1082 else {
Björn Stenberg6224cdb2002-08-16 14:41:47 +00001083 int seed = current_tick;
Björn Stenbergc521ed12002-09-03 09:44:08 +00001084 bool play = false;
1085 int start_index=0;
Björn Stenbergdea31222002-10-08 15:42:40 +00001086
Björn Stenberg42770ea2002-06-10 13:24:27 +00001087 lcd_stop_scroll();
Björn Stenbergc521ed12002-09-03 09:44:08 +00001088 switch ( file->attr & TREE_ATTR_MASK ) {
1089 case TREE_ATTR_M3U:
Björn Stenberga108ec22004-01-14 00:13:04 +00001090 if (bookmark_autoload(buf))
1091 {
1092 restore = true;
1093 break;
1094 }
1095
Hardeep Sidhu9e426202003-07-01 21:05:43 +00001096 if (playlist_create(currdir, file->name) != -1)
1097 {
1098 if (global_settings.playlist_shuffle)
1099 playlist_shuffle(seed, -1);
Linus Nielsen Feltzing87d5cfe2003-06-01 00:41:46 +00001100 start_index = 0;
Hardeep Sidhu9e426202003-07-01 21:05:43 +00001101 playlist_start(start_index,0);
1102 play = true;
1103 }
1104 break;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001105
Hardeep Sidhu9e426202003-07-01 21:05:43 +00001106 case TREE_ATTR_MPA:
Björn Stenberga108ec22004-01-14 00:13:04 +00001107 if (bookmark_autoload(currdir))
1108 {
1109 restore = true;
1110 break;
1111 }
1112
Hardeep Sidhu9e426202003-07-01 21:05:43 +00001113 if (playlist_create(currdir, NULL) != -1)
1114 {
1115 start_index =
1116 build_playlist(dircursor+dirstart);
1117 if (global_settings.playlist_shuffle)
1118 {
1119 start_index =
1120 playlist_shuffle(seed,start_index);
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001121
Hardeep Sidhu9e426202003-07-01 21:05:43 +00001122 /* when shuffling dir.: play all files
1123 even if the file selected by user is
1124 not the first one */
1125 if (!global_settings.play_selected)
1126 start_index = 0;
1127 }
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001128
Hardeep Sidhu9e426202003-07-01 21:05:43 +00001129 playlist_start(start_index, 0);
1130 play = true;
1131 }
Björn Stenbergc521ed12002-09-03 09:44:08 +00001132 break;
1133
1134 /* wps config file */
1135 case TREE_ATTR_WPS:
Björn Stenbergdea31222002-10-08 15:42:40 +00001136 wps_load(buf,true);
Björn Stenbergbda4ec12003-02-17 09:53:11 +00001137 set_file(buf, global_settings.wps_file,
1138 MAX_FILENAME);
Björn Stenberg1a682be2002-09-02 12:46:32 +00001139 restore = true;
1140 break;
Björn Stenbergc521ed12002-09-03 09:44:08 +00001141
Björn Stenberg08181c72002-10-08 09:40:05 +00001142 case TREE_ATTR_CFG:
Björn Stenberg9c16e122003-02-14 14:14:55 +00001143 if (!settings_load_config(buf))
1144 break;
1145 lcd_clear_display();
1146 lcd_puts(0,0,str(LANG_SETTINGS_LOADED1));
1147 lcd_puts(0,1,str(LANG_SETTINGS_LOADED2));
1148#ifdef HAVE_LCD_BITMAP
1149 lcd_update();
1150
1151 /* maybe we have a new font */
Linus Nielsen Feltzing77936e62004-03-16 13:44:56 +00001152 tree_max_on_screen = recalc_screen_height();
Björn Stenberg9c16e122003-02-14 14:14:55 +00001153 /* make sure cursor is on screen */
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001154 while ( dircursor > tree_max_on_screen )
Björn Stenberg9c16e122003-02-14 14:14:55 +00001155 {
1156 dircursor--;
1157 dirstart++;
1158 }
1159#endif
1160 sleep(HZ/2);
Justin Heinere4a27612002-09-05 01:20:10 +00001161 restore = true;
1162 break;
Justin Heinere4a27612002-09-05 01:20:10 +00001163
Björn Stenberga108ec22004-01-14 00:13:04 +00001164 case TREE_ATTR_BMARK:
1165 bookmark_load(buf, false);
1166 restore = true;
1167 reload_dir = true;
1168 break;
1169
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001170 case TREE_ATTR_TXT:
Björn Stenbergba371fb2003-06-29 16:33:04 +00001171 plugin_load("/.rockbox/rocks/viewer.rock",buf);
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001172 restore = true;
1173 break;
1174
Daniel Stenberga007ebf2002-09-24 12:40:52 +00001175 case TREE_ATTR_LNG:
Daniel Stenberg85305da2002-09-24 13:37:38 +00001176 if(!lang_load(buf)) {
Björn Stenberge6df8412003-02-23 18:52:53 +00001177 set_file(buf, global_settings.lang_file,
Björn Stenbergbda4ec12003-02-17 09:53:11 +00001178 MAX_FILENAME);
Daniel Stenberg1afa3952004-01-08 09:58:58 +00001179 splash(HZ, true, str(LANG_LANGUAGE_LOADED));
Daniel Stenberg85305da2002-09-24 13:37:38 +00001180 restore = true;
1181 }
Daniel Stenberga007ebf2002-09-24 12:40:52 +00001182 break;
1183
Björn Stenbergbed3d3f2002-09-20 08:07:51 +00001184#ifdef HAVE_LCD_BITMAP
Jörg Hohensohn16948472003-10-30 23:48:36 +00001185 /* chip-8 game */
1186 case TREE_ATTR_CH8:
1187 plugin_load("/.rockbox/rocks/chip8.rock",buf);
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001188 break;
Jörg Hohensohn16948472003-10-30 23:48:36 +00001189
Jörg Hohensohnbd8f4482003-12-15 07:44:43 +00001190 /* "movie" animation */
1191 case TREE_ATTR_RVF:
1192 plugin_load("/.rockbox/rocks/video.rock",buf);
1193 break;
1194
Björn Stenbergbed3d3f2002-09-20 08:07:51 +00001195 case TREE_ATTR_FONT:
Björn Stenbergbed3d3f2002-09-20 08:07:51 +00001196 font_load(buf);
Björn Stenberge6df8412003-02-23 18:52:53 +00001197 set_file(buf, global_settings.font_file,
Björn Stenbergbda4ec12003-02-17 09:53:11 +00001198 MAX_FILENAME);
Björn Stenbergdea31222002-10-08 15:42:40 +00001199
Linus Nielsen Feltzing77936e62004-03-16 13:44:56 +00001200 tree_max_on_screen = recalc_screen_height();
Björn Stenbergbed3d3f2002-09-20 08:07:51 +00001201 /* make sure cursor is on screen */
1202 while ( dircursor > tree_max_on_screen ) {
1203 dircursor--;
1204 dirstart++;
1205 }
1206 restore = true;
1207 break;
1208#endif
1209
Björn Stenbergc521ed12002-09-03 09:44:08 +00001210#ifndef SIMULATOR
1211 /* firmware file */
1212 case TREE_ATTR_MOD:
Björn Stenbergc521ed12002-09-03 09:44:08 +00001213 rolo_load(buf);
Björn Stenberg1a682be2002-09-02 12:46:32 +00001214 break;
Jörg Hohensohn8d2a4082003-07-27 22:08:42 +00001215
1216 /* ucl flash file */
1217 case TREE_ATTR_UCL:
1218 plugin_load("/.rockbox/rocks/rockbox_flash.rock",buf);
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001219 break;
Björn Stenbergc521ed12002-09-03 09:44:08 +00001220#endif
Björn Stenbergba371fb2003-06-29 16:33:04 +00001221
1222 /* plugin file */
1223 case TREE_ATTR_ROCK:
1224 if (plugin_load(buf,NULL) == PLUGIN_USB_CONNECTED)
1225 reload_root = true;
1226 else
1227 restore = true;
1228 break;
Björn Stenberg6224cdb2002-08-16 14:41:47 +00001229 }
1230
Björn Stenbergc521ed12002-09-03 09:44:08 +00001231 if ( play ) {
1232 if ( global_settings.resume ) {
1233 /* the resume_index must always be the index in the
1234 shuffled list in case shuffle is enabled */
1235 global_settings.resume_index = start_index;
1236 global_settings.resume_offset = 0;
Björn Stenbergc521ed12002-09-03 09:44:08 +00001237 settings_save();
1238 }
1239
Björn Stenberga108ec22004-01-14 00:13:04 +00001240 start_wps = true;
Björn Stenbergc521ed12002-09-03 09:44:08 +00001241 }
Björn Stenbergde5477c2003-09-29 21:26:53 +00001242 else if (*dirfilter > NUM_FILTER_MODES)
1243 exit_func = true;
Björn Stenberg82182852002-05-16 12:53:40 +00001244 }
Björn Stenbergbb9aaf52002-06-25 13:26:04 +00001245 restore = true;
Björn Stenberg82182852002-05-16 12:53:40 +00001246 break;
Eric Linenberg9e91b952002-08-06 18:11:00 +00001247
Eric Linenberg9e91b952002-08-06 18:11:00 +00001248 case TREE_PREV:
Björn Stenbergc1d9b152002-08-07 20:51:37 +00001249 case TREE_PREV | BUTTON_REPEAT:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001250#ifdef BUTTON_RC_LEFT
Björn Stenberg8190b5d2003-05-20 12:15:09 +00001251 case BUTTON_RC_LEFT:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001252#endif
Eric Linenberg9e91b952002-08-06 18:11:00 +00001253 if(filesindir) {
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001254 if(dircursor) {
Markus Braun000c2db2002-08-30 13:49:32 +00001255 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, false);
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001256 dircursor--;
Markus Braun000c2db2002-08-30 13:49:32 +00001257 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true);
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001258 }
1259 else {
Eric Linenbergecca1232002-09-09 14:25:39 +00001260 if (dirstart) {
1261 dirstart--;
Björn Stenbergde5477c2003-09-29 21:26:53 +00001262 numentries = showdir(currdir, dirstart, dirfilter);
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +00001263 update_all=true;
Markus Braun000c2db2002-08-30 13:49:32 +00001264 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true);
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001265 }
1266 else {
Björn Stenbergcd225732002-08-11 09:17:47 +00001267 if (numentries < tree_max_on_screen) {
Markus Braun000c2db2002-08-30 13:49:32 +00001268 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor,
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001269 false);
1270 dircursor = numentries - 1;
Markus Braun000c2db2002-08-30 13:49:32 +00001271 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor,
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001272 true);
1273 }
1274 else {
Eric Linenbergecca1232002-09-09 14:25:39 +00001275 dirstart = numentries - tree_max_on_screen;
Björn Stenbergcd225732002-08-11 09:17:47 +00001276 dircursor = tree_max_on_screen - 1;
Björn Stenbergde5477c2003-09-29 21:26:53 +00001277 numentries = showdir(currdir, dirstart, dirfilter);
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +00001278 update_all = true;
Markus Braun000c2db2002-08-30 13:49:32 +00001279 put_cursorxy(CURSOR_X, CURSOR_Y +
Björn Stenbergcd225732002-08-11 09:17:47 +00001280 tree_max_on_screen - 1, true);
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001281 }
1282 }
1283 }
Linus Nielsen Feltzing1a271202002-10-28 09:11:42 +00001284 need_update = true;
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001285 }
Björn Stenberg82182852002-05-16 12:53:40 +00001286 break;
Björn Stenberg244688e2002-05-16 14:48:40 +00001287
Björn Stenbergcf55acf2002-06-12 08:59:48 +00001288 case TREE_NEXT:
Björn Stenbergc1d9b152002-08-07 20:51:37 +00001289 case TREE_NEXT | BUTTON_REPEAT:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001290#ifdef BUTTON_RC_RIGHT
Björn Stenberg8190b5d2003-05-20 12:15:09 +00001291 case BUTTON_RC_RIGHT:
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001292#endif
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001293 if(filesindir)
1294 {
Eric Linenbergecca1232002-09-09 14:25:39 +00001295 if (dircursor + dirstart + 1 < numentries ) {
Björn Stenbergcd225732002-08-11 09:17:47 +00001296 if(dircursor+1 < tree_max_on_screen) {
Linus Nielsen Feltzinge43b78a2003-04-16 00:12:31 +00001297 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, false);
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001298 dircursor++;
Markus Braun000c2db2002-08-30 13:49:32 +00001299 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true);
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001300 }
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001301 else {
Eric Linenbergecca1232002-09-09 14:25:39 +00001302 dirstart++;
Björn Stenbergde5477c2003-09-29 21:26:53 +00001303 numentries = showdir(currdir, dirstart, dirfilter);
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +00001304 update_all = true;
Markus Braun000c2db2002-08-30 13:49:32 +00001305 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true);
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001306 }
1307 }
1308 else {
Björn Stenbergcd225732002-08-11 09:17:47 +00001309 if(numentries < tree_max_on_screen) {
Linus Nielsen Feltzinge43b78a2003-04-16 00:12:31 +00001310 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, false);
Eric Linenbergecca1232002-09-09 14:25:39 +00001311 dirstart = dircursor = 0;
Markus Braun000c2db2002-08-30 13:49:32 +00001312 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true);
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001313 }
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001314 else {
Eric Linenbergecca1232002-09-09 14:25:39 +00001315 dirstart = dircursor = 0;
Björn Stenbergde5477c2003-09-29 21:26:53 +00001316 numentries = showdir(currdir, dirstart, dirfilter);
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +00001317 update_all=true;
Markus Braun000c2db2002-08-30 13:49:32 +00001318 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true);
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001319 }
1320 }
Linus Nielsen Feltzing1a271202002-10-28 09:11:42 +00001321 need_update = true;
Linus Nielsen Feltzingfe689a82002-07-22 22:45:20 +00001322 }
Björn Stenberg82182852002-05-16 12:53:40 +00001323 break;
Björn Stenberge493efd2002-05-21 14:30:54 +00001324
Björn Stenberg0ad20102002-09-03 20:47:23 +00001325 case TREE_MENU:
Linus Nielsen Feltzingf97756e2003-11-04 16:47:05 +00001326 if (*dirfilter < NUM_FILTER_MODES)
1327 {
1328 lcd_stop_scroll();
1329 if (main_menu())
1330 reload_root = true;
1331 restore = true;
1332 }
Björn Stenberge493efd2002-05-21 14:30:54 +00001333 break;
Björn Stenbergbb9aaf52002-06-25 13:26:04 +00001334
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001335#ifdef BUTTON_ON /* I bet the folks without ON-button want this to
1336 work on a different button */
Björn Stenbergbb9aaf52002-06-25 13:26:04 +00001337 case BUTTON_ON:
Björn Stenbergcaebdd42003-01-15 14:52:53 +00001338 if (handle_on(&dirstart, &dircursor, numentries,
Björn Stenbergde5477c2003-09-29 21:26:53 +00001339 tree_max_on_screen, dirfilter))
Linus Nielsen Feltzing8abcf1b2002-08-07 06:04:24 +00001340 {
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +00001341 /* start scroll */
Björn Stenberg34d1e1b2002-06-27 01:20:08 +00001342 restore = true;
1343 }
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +00001344 else
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +00001345 {
1346 if (mpeg_status() & MPEG_STATUS_PLAY)
1347 {
Björn Stenberga108ec22004-01-14 00:13:04 +00001348 start_wps=true;
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +00001349 }
Linus Nielsen Feltzing6e49e782003-07-08 09:19:12 +00001350 else
1351 {
1352 start_resume(false);
1353 restore = true;
1354 }
Björn Stenberg5f8ac6d2002-09-29 22:24:00 +00001355 }
Björn Stenbergbb9aaf52002-06-25 13:26:04 +00001356 break;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001357#endif
Linus Nielsen Feltzingda501ee2002-06-30 16:27:39 +00001358
Markus Braunde8fbf02002-08-07 10:35:26 +00001359#ifdef HAVE_RECORDER_KEYPAD
Björn Stenbergabe11fd2002-09-03 15:58:47 +00001360 case BUTTON_F2:
Linus Nielsen Feltzingf97756e2003-11-04 16:47:05 +00001361 if (*dirfilter < NUM_FILTER_MODES)
1362 {
Linus Nielsen Feltzing10b92c42004-03-12 10:20:33 +00001363 if (quick_screen(CONTEXT_TREE, BUTTON_F2))
Linus Nielsen Feltzingf97756e2003-11-04 16:47:05 +00001364 reload_root = true;
1365 restore = true;
1366 break;
1367 }
Björn Stenbergabe11fd2002-09-03 15:58:47 +00001368
1369 case BUTTON_F3:
Linus Nielsen Feltzingf97756e2003-11-04 16:47:05 +00001370 if (*dirfilter < NUM_FILTER_MODES)
1371 {
Linus Nielsen Feltzing10b92c42004-03-12 10:20:33 +00001372 if (quick_screen(CONTEXT_TREE, BUTTON_F3))
Linus Nielsen Feltzingf97756e2003-11-04 16:47:05 +00001373 reload_root = true;
Daniel Stenberg93b231c2002-09-12 13:33:59 +00001374
1375#ifdef HAVE_LCD_BITMAP
Linus Nielsen Feltzing77936e62004-03-16 13:44:56 +00001376 tree_max_on_screen = recalc_screen_height();
Björn Stenbergabe11fd2002-09-03 15:58:47 +00001377#endif
Linus Nielsen Feltzingf97756e2003-11-04 16:47:05 +00001378 restore = true;
1379 }
Markus Braunde8fbf02002-08-07 10:35:26 +00001380 break;
Markus Braunc41dcb92002-08-20 19:39:55 +00001381#endif
Markus Braunde8fbf02002-08-07 10:35:26 +00001382
Björn Stenbergb1b8bd42002-09-24 17:22:12 +00001383 case SYS_USB_CONNECTED:
Markus Braun88098be2002-10-11 08:56:23 +00001384 status_set_playmode(STATUS_STOP);
Björn Stenbergb1b8bd42002-09-24 17:22:12 +00001385 usb_screen();
Björn Stenberg0ad20102002-09-03 20:47:23 +00001386 reload_root = true;
Björn Stenbergb1b8bd42002-09-24 17:22:12 +00001387 break;
Linus Nielsen Feltzing1a271202002-10-28 09:11:42 +00001388
1389 case BUTTON_NONE:
Jörg Hohensohn6e86b662004-03-28 10:21:58 +00001390 if (thumbnail_time != -1 &&
1391 TIME_AFTER(current_tick, thumbnail_time))
1392 { /* a delayed hovering thumbnail is due now */
1393 int res;
1394 DEBUGF("Playing directory thumbnail: %s", currdir);
1395 res = play_dirname(lasti);
1396 if (res < 0) /* failed, not existing */
1397 { /* say the number instead, as a fallback */
1398 talk_id(VOICE_DIR, false);
1399 talk_number(lasti+1, true);
1400 }
1401 thumbnail_time = -1; /* job done */
1402 }
Björn Stenberg942bc942003-04-23 11:26:25 +00001403 status_draw(false);
Linus Nielsen Feltzing1a271202002-10-28 09:11:42 +00001404 break;
Björn Stenberg82182852002-05-16 12:53:40 +00001405 }
Björn Stenberg42770ea2002-06-10 13:24:27 +00001406
Björn Stenberg457b8a02002-08-26 13:21:14 +00001407 if ( button )
1408 ata_spin();
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001409
Björn Stenberga108ec22004-01-14 00:13:04 +00001410 if (start_wps)
1411 {
1412 lcd_stop_scroll();
1413 if (wps_show() == SYS_USB_CONNECTED)
1414 reload_root = true;
1415#ifdef HAVE_LCD_BITMAP
Linus Nielsen Feltzing77936e62004-03-16 13:44:56 +00001416 tree_max_on_screen = recalc_screen_height();
Björn Stenberga108ec22004-01-14 00:13:04 +00001417#endif
1418 restore = true;
1419 start_wps=false;
1420 }
1421
Björn Stenberg0ad20102002-09-03 20:47:23 +00001422 /* do we need to rescan dir? */
Daniel Stenbergd3d29052003-03-07 08:10:10 +00001423 if (reload_dir || reload_root ||
Björn Stenbergde5477c2003-09-29 21:26:53 +00001424 lastfilter != *dirfilter ||
Björn Stenberga7dcf912002-09-24 19:12:09 +00001425 lastsortcase != global_settings.sort_case)
Björn Stenberg0ad20102002-09-03 20:47:23 +00001426 {
1427 if ( reload_root ) {
1428 strcpy(currdir, "/");
1429 dirlevel = 0;
1430 reload_root = false;
1431 }
Daniel Stenbergd3d29052003-03-07 08:10:10 +00001432 if (! reload_dir )
1433 {
1434 dircursor = 0;
1435 dirstart = 0;
1436 lastdir[0] = 0;
1437 }
Björn Stenbergde5477c2003-09-29 21:26:53 +00001438
1439 lastfilter = *dirfilter;
Björn Stenberg0ad20102002-09-03 20:47:23 +00001440 lastsortcase = global_settings.sort_case;
Björn Stenberg0ad20102002-09-03 20:47:23 +00001441 restore = true;
Björn Stenberga108ec22004-01-14 00:13:04 +00001442 while (button_get(false)); /* clear button queue */
Björn Stenberg0ad20102002-09-03 20:47:23 +00001443 }
1444
Björn Stenbergde5477c2003-09-29 21:26:53 +00001445 if (exit_func)
1446 break;
1447
Björn Stenbergcaebdd42003-01-15 14:52:53 +00001448 if (restore || reload_dir) {
Björn Stenbergbb9aaf52002-06-25 13:26:04 +00001449 /* restore display */
Linus Nielsen Feltzing57e928f2003-04-14 07:53:58 +00001450
Linus Nielsen Feltzing9431ae52004-03-17 11:57:25 +00001451#ifdef HAVE_LCD_BITMAP
Linus Nielsen Feltzinge2546322004-03-17 07:43:19 +00001452 tree_max_on_screen = recalc_screen_height();
Linus Nielsen Feltzing9431ae52004-03-17 11:57:25 +00001453#endif
Linus Nielsen Feltzinge2546322004-03-17 07:43:19 +00001454
Linus Nielsen Feltzinge10fc4c2002-08-08 10:46:10 +00001455 /* We need to adjust if the number of lines on screen have
1456 changed because of a status bar change */
Björn Stenbergcd225732002-08-11 09:17:47 +00001457 if(CURSOR_Y+LINE_Y+dircursor>tree_max_on_screen) {
Eric Linenbergecca1232002-09-09 14:25:39 +00001458 dirstart++;
Linus Nielsen Feltzinge10fc4c2002-08-08 10:46:10 +00001459 dircursor--;
1460 }
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001461#ifdef HAVE_LCD_BITMAP
1462 /* the sub-screen might've ruined the margins */
1463 lcd_setmargins(MARGIN_X,MARGIN_Y); /* leave room for cursor and
1464 icon */
Björn Stenbergba371fb2003-06-29 16:33:04 +00001465 lcd_setfont(FONT_UI);
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001466#endif
Björn Stenbergde5477c2003-09-29 21:26:53 +00001467 numentries = showdir(currdir, dirstart, dirfilter);
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +00001468 update_all = true;
Markus Braun000c2db2002-08-30 13:49:32 +00001469 put_cursorxy(CURSOR_X, CURSOR_Y + dircursor, true);
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001470
Linus Nielsen Feltzing1a271202002-10-28 09:11:42 +00001471 need_update = true;
Björn Stenbergcaebdd42003-01-15 14:52:53 +00001472 reload_dir = false;
Björn Stenbergbb9aaf52002-06-25 13:26:04 +00001473 }
Björn Stenberg42770ea2002-06-10 13:24:27 +00001474
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +00001475 if ( numentries && need_update) {
Eric Linenbergecca1232002-09-09 14:25:39 +00001476 i = dirstart+dircursor;
Markus Braunde8fbf02002-08-07 10:35:26 +00001477
1478 /* if MP3 filter is on, cut off the extension */
1479 if(lasti!=i || restore) {
Markus Braunde8fbf02002-08-07 10:35:26 +00001480 lcd_stop_scroll();
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +00001481
1482 /* So if lastdircursor and dircursor differ, and then full
1483 screen was not refreshed, restore the previous line */
1484 if ((lastdircursor != dircursor) && !update_all ) {
Björn Stenbergde5477c2003-09-29 21:26:53 +00001485 showfileline(lastdircursor, lasti, false, dirfilter); /* no scroll */
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +00001486 }
Kjell Ericson767d6042003-01-23 14:28:16 +00001487 lasti=i;
1488 lastdircursor=dircursor;
Jörg Hohensohn18e91a72004-03-31 07:18:10 +00001489 thumbnail_time = -1; /* cancel whatever we were about to say */
Linus Nielsen Feltzing1a271202002-10-28 09:11:42 +00001490
Björn Stenbergde5477c2003-09-29 21:26:53 +00001491 showfileline(dircursor, i, true, dirfilter); /* scroll please */
Linus Nielsen Feltzing1a271202002-10-28 09:11:42 +00001492 need_update = true;
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +00001493
1494 if (dircache[i].attr & ATTR_DIRECTORY) /* directory? */
1495 {
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +00001496 /* play directory thumbnail */
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +00001497 if (global_settings.talk_dir == 4) /* hover */
Jörg Hohensohn18e91a72004-03-31 07:18:10 +00001498 { /* "schedule" a thumbnail, to have a little dalay */
Jörg Hohensohn6e86b662004-03-28 10:21:58 +00001499 thumbnail_time = current_tick + HOVER_DELAY;
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +00001500 }
Jörg Hohensohn6e86b662004-03-28 10:21:58 +00001501 else if (global_settings.talk_dir == 1) /* dirs as numbers */
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +00001502 {
1503 talk_id(VOICE_DIR, false);
1504 talk_number(i+1, true);
1505 }
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +00001506 else if (global_settings.talk_dir == 2) /* dirs spelled */
1507 {
1508 talk_spell(dircache[i].name, false);
1509 }
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +00001510 }
1511 else if (global_settings.talk_file == 1) /* files as numbers */
1512 {
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +00001513 /* try to find a voice ID for the extension, if known */
1514 int j;
1515 int ext_id = -1; /* default to none */
1516 for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++)
1517 {
1518 if ((dircache[i].attr & TREE_ATTR_MASK) == filetypes[j].tree_attr)
1519 {
1520 ext_id = filetypes[j].voiceclip;
1521 break;
1522 }
1523 }
1524
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +00001525 /* enqueue_next is true if still talking the dir name */
1526 talk_id(VOICE_FILE, enqueue_next);
1527 talk_number(i-dirsindir+1, true);
Jörg Hohensohnc8592ba2004-04-04 19:08:44 +00001528 talk_id(ext_id, true);
1529 enqueue_next = false;
1530 }
1531 else if (global_settings.talk_file == 2) /* files spelled */
1532 {
1533 /* enqueue_next is true if still talking the dir name */
1534 talk_spell(dircache[i].name, enqueue_next);
Jörg Hohensohn3aa99e12004-03-27 00:11:01 +00001535 enqueue_next = false;
1536 }
1537
Markus Braunde8fbf02002-08-07 10:35:26 +00001538 }
1539 }
Linus Nielsen Feltzing1a271202002-10-28 09:11:42 +00001540
1541 if(need_update) {
1542 lcd_update();
1543
1544 need_update = false;
Daniel Stenbergcc46b4a2003-01-24 10:56:59 +00001545 update_all = false;
Linus Nielsen Feltzing1a271202002-10-28 09:11:42 +00001546 }
Björn Stenberg82182852002-05-16 12:53:40 +00001547 }
1548
Mats Lidell816bc8c2003-01-31 08:43:12 +00001549 return true;
Björn Stenberg82182852002-05-16 12:53:40 +00001550}
Björn Stenbergefb165f2003-01-29 13:20:22 +00001551
1552static int plsize = 0;
Hardeep Sidhu53d82532004-03-21 22:27:56 +00001553static bool add_dir(char* dirname, int len, int fd)
Björn Stenbergefb165f2003-01-29 13:20:22 +00001554{
1555 bool abort = false;
Daniel Stenbergb8a86182003-01-29 17:14:55 +00001556 DIR* dir;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001557
Björn Stenbergefb165f2003-01-29 13:20:22 +00001558 /* check for user abort */
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001559#ifdef BUTTON_STOP
Björn Stenbergefb165f2003-01-29 13:20:22 +00001560 if (button_get(false) == BUTTON_STOP)
1561#else
1562 if (button_get(false) == BUTTON_OFF)
1563#endif
1564 return true;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001565
Daniel Stenbergb8a86182003-01-29 17:14:55 +00001566 dir = opendir(dirname);
Björn Stenbergefb165f2003-01-29 13:20:22 +00001567 if(!dir)
1568 return true;
1569
1570 while (true) {
1571 struct dirent *entry;
1572
1573 entry = readdir(dir);
1574 if (!entry)
1575 break;
1576 if (entry->attribute & ATTR_DIRECTORY) {
Hardeep Sidhu53d82532004-03-21 22:27:56 +00001577 int dirlen = strlen(dirname);
1578 bool result;
1579
Björn Stenbergefb165f2003-01-29 13:20:22 +00001580 if (!strcmp(entry->d_name, ".") ||
1581 !strcmp(entry->d_name, ".."))
1582 continue;
Hardeep Sidhu53d82532004-03-21 22:27:56 +00001583
Björn Stenberg10abfec2003-03-11 09:57:46 +00001584 if (dirname[1])
Hardeep Sidhu53d82532004-03-21 22:27:56 +00001585 snprintf(dirname+dirlen, len-dirlen, "/%s", entry->d_name);
Björn Stenberg10abfec2003-03-11 09:57:46 +00001586 else
Hardeep Sidhu53d82532004-03-21 22:27:56 +00001587 snprintf(dirname, len, "/%s", entry->d_name);
1588
1589 result = add_dir(dirname, len, fd);
1590 dirname[dirlen] = '\0';
1591 if (result) {
Björn Stenbergefb165f2003-01-29 13:20:22 +00001592 abort = true;
1593 break;
1594 }
1595 }
1596 else {
1597 int x = strlen(entry->d_name);
1598 if ((!strcasecmp(&entry->d_name[x-4], ".mp3")) ||
1599 (!strcasecmp(&entry->d_name[x-4], ".mp2")) ||
1600 (!strcasecmp(&entry->d_name[x-4], ".mpa")))
1601 {
Hardeep Sidhu53d82532004-03-21 22:27:56 +00001602 char buf[8];
Björn Stenbergefb165f2003-01-29 13:20:22 +00001603 write(fd, dirname, strlen(dirname));
1604 write(fd, "/", 1);
1605 write(fd, entry->d_name, x);
1606 write(fd, "\n", 1);
1607
1608 plsize++;
1609 snprintf(buf, sizeof buf, "%d", plsize);
1610#ifdef HAVE_LCD_BITMAP
1611 lcd_puts(0,4,buf);
1612 lcd_update();
1613#else
1614 x = 10;
1615 if (plsize > 999)
1616 x=7;
1617 else {
1618 if (plsize > 99)
1619 x=8;
1620 else {
1621 if (plsize > 9)
1622 x=9;
1623 }
1624 }
1625 lcd_puts(x,0,buf);
1626#endif
1627 }
1628 }
1629 }
1630 closedir(dir);
1631
1632 return abort;
1633}
1634
1635bool create_playlist(void)
1636{
1637 int fd;
1638 char filename[MAX_PATH];
1639
1640 snprintf(filename, sizeof filename, "%s.m3u",
1641 currdir[1] ? currdir : "/root");
1642
1643 lcd_clear_display();
1644 lcd_puts(0,0,str(LANG_CREATING));
1645 lcd_puts_scroll(0,1,filename);
1646 lcd_update();
1647
1648 fd = creat(filename,0);
Linus Nielsen Feltzing887e2172003-03-21 03:07:31 +00001649 if (fd < 0)
Björn Stenbergefb165f2003-01-29 13:20:22 +00001650 return false;
1651
Hardeep Sidhu53d82532004-03-21 22:27:56 +00001652 snprintf(filename, sizeof(filename), "%s", currdir[1] ? currdir : "/");
Björn Stenbergefb165f2003-01-29 13:20:22 +00001653 plsize = 0;
Hardeep Sidhu53d82532004-03-21 22:27:56 +00001654 add_dir(filename, sizeof(filename), fd);
Björn Stenbergefb165f2003-01-29 13:20:22 +00001655 close(fd);
1656 sleep(HZ);
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001657
Linus Nielsen Feltzing887e2172003-03-21 03:07:31 +00001658 return true;
Björn Stenbergefb165f2003-01-29 13:20:22 +00001659}
Linus Nielsen Feltzing20d031f2003-05-09 16:01:21 +00001660
Björn Stenbergde5477c2003-09-29 21:26:53 +00001661bool rockbox_browse(char *root, int dirfilter)
1662{
1663 bool rc;
1664 int dircursor_save = dircursor;
1665 int dirstart_save = dirstart;
1666 int dirlevel_save = dirlevel;
1667 int dirpos_save = dirpos[0];
1668 int cursorpos_save = cursorpos[0];
1669
1670 memcpy(currdir_save, currdir, sizeof(currdir));
Linus Nielsen Feltzing130dccf2003-10-10 10:19:44 +00001671 reload_dir = true;
Hardeep Sidhu11280c72004-01-18 21:26:34 +00001672 start_wps = false;
Björn Stenbergde5477c2003-09-29 21:26:53 +00001673 rc = dirbrowse(root, &dirfilter);
1674 memcpy(currdir, currdir_save, sizeof(currdir));
1675
1676 reload_dir = true;
1677 dirstart = dirstart_save;
1678 cursorpos[0] = cursorpos_save;
1679 dirlevel = dirlevel_save;
1680 dircursor = dircursor_save;
1681 dirpos[0] = dirpos_save;
1682
1683 return false;
1684}
1685
Linus Nielsen Feltzing20d031f2003-05-09 16:01:21 +00001686void tree_init(void)
1687{
1688 /* We copy the settings value in case it is changed by the user. We can't
Linus Nielsen Feltzing92e9b152003-05-17 20:43:03 +00001689 use it until the next reboot. */
Linus Nielsen Feltzing20d031f2003-05-09 16:01:21 +00001690 max_files_in_dir = global_settings.max_files_in_dir;
1691 name_buffer_size = AVERAGE_FILENAME_LENGTH * max_files_in_dir;
Daniel Stenberg8e43ccb2003-12-12 13:34:27 +00001692
Linus Nielsen Feltzing20d031f2003-05-09 16:01:21 +00001693 name_buffer = buffer_alloc(name_buffer_size);
1694 dircache = buffer_alloc(max_files_in_dir * sizeof(struct entry));
1695}
Björn Stenberga108ec22004-01-14 00:13:04 +00001696
1697void bookmark_play(char *resume_file, int index, int offset, int seed)
1698{
1699 int len=strlen(resume_file);
1700
1701 if (!strcasecmp(&resume_file[len-4], ".m3u"))
1702 {
1703 char* slash;
1704 // check that the file exists
1705 int fd = open(resume_file, O_RDONLY);
1706 if(fd<0)
1707 return;
1708 close(fd);
1709
1710 slash = strrchr(resume_file,'/');
1711 if (slash)
1712 {
1713 char* cp;
1714 *slash=0;
1715
1716 cp=resume_file;
1717 if (!cp[0])
1718 cp="/";
1719
1720 if (playlist_create(cp, slash+1) != -1)
1721 {
1722 if (global_settings.playlist_shuffle)
1723 playlist_shuffle(seed, -1);
1724 playlist_start(index,offset);
1725 }
1726 *slash='/';
1727 }
1728 }
1729 else
1730 {
1731 lastdir[0]='\0';
1732 if (playlist_create(resume_file, NULL) != -1)
1733 {
1734 resume_directory(resume_file);
1735 if (global_settings.playlist_shuffle)
1736 playlist_shuffle(seed, -1);
1737 playlist_start(index,offset);
1738 }
1739 }
1740
1741 status_set_playmode(STATUS_PLAY);
1742 start_wps=true;
1743}