summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/codecs.c4
-rw-r--r--apps/filetree.c5
-rw-r--r--apps/filetypes.c7
-rw-r--r--apps/gui/skin_engine/skin_fonts.c2
-rw-r--r--apps/gui/skin_engine/skin_parser.c3
-rw-r--r--apps/gui/theme_settings.c4
-rw-r--r--apps/main.c17
-rw-r--r--apps/menus/main_menu.c5
-rw-r--r--apps/menus/theme_menu.c4
-rw-r--r--apps/misc.c29
-rw-r--r--apps/misc.h2
-rw-r--r--apps/playlist.c12
-rw-r--r--apps/playlist_catalog.c10
-rw-r--r--apps/plugin.c1
-rw-r--r--apps/plugin.h1
-rw-r--r--apps/radio/presets.c1
-rw-r--r--apps/radio/radioart.c1
-rw-r--r--apps/recorder/albumart.c1
-rw-r--r--apps/recorder/recording.c2
-rw-r--r--apps/root_menu.c10
-rw-r--r--apps/scrobbler.c2
-rw-r--r--apps/settings.c47
-rw-r--r--apps/settings.h45
-rw-r--r--apps/tagcache.c142
-rw-r--r--apps/tree.c4
-rw-r--r--firmware/SOURCES3
-rw-r--r--firmware/common/dircache.c11
-rw-r--r--firmware/common/filefuncs.c37
-rw-r--r--firmware/common/rbpaths.c84
-rw-r--r--firmware/common/unicode.c4
-rw-r--r--firmware/export/filefuncs.h5
-rw-r--r--firmware/export/rbpaths.h132
-rw-r--r--firmware/font.c20
-rw-r--r--firmware/include/dircache.h1
-rw-r--r--firmware/include/file.h5
-rwxr-xr-xtools/buildzip.pl7
-rwxr-xr-xtools/configure49
-rw-r--r--tools/root.make20
-rw-r--r--uisimulator/common/io.c16
-rw-r--r--wps/WPSLIST44
-rwxr-xr-xwps/wpsbuild.pl69
41 files changed, 620 insertions, 248 deletions
diff --git a/apps/codecs.c b/apps/codecs.c
index 154faa3f3f..29a664425a 100644
--- a/apps/codecs.c
+++ b/apps/codecs.c
@@ -193,8 +193,8 @@ struct codec_api ci = {
193 193
194void codec_get_full_path(char *path, const char *codec_root_fn) 194void codec_get_full_path(char *path, const char *codec_root_fn)
195{ 195{
196 snprintf(path, MAX_PATH-1, CODECS_DIR "/%s." CODEC_EXTENSION, 196 snprintf(path, MAX_PATH-1, "%s/%s." CODEC_EXTENSION,
197 codec_root_fn); 197 CODECS_DIR, codec_root_fn);
198} 198}
199 199
200static int codec_load_ram(int size, struct codec_api *api) 200static int codec_load_ram(int size, struct codec_api *api)
diff --git a/apps/filetree.c b/apps/filetree.c
index 460ab9e453..fa942b263d 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -609,11 +609,12 @@ int ft_enter(struct tree_context* c)
609 case FILE_ATTR_ROCK: 609 case FILE_ATTR_ROCK:
610 case FILE_ATTR_LUA: 610 case FILE_ATTR_LUA:
611 { 611 {
612 char *plugin = buf, *argument = NULL; 612 char *plugin = buf, *argument = NULL, lua_path[MAX_PATH];
613 int ret; 613 int ret;
614 614
615 if ((file->attr & FILE_ATTR_MASK) == FILE_ATTR_LUA) { 615 if ((file->attr & FILE_ATTR_MASK) == FILE_ATTR_LUA) {
616 plugin = VIEWERS_DIR "/lua.rock"; /* Use a #define here ? */ 616 snprintf(lua_path, sizeof(lua_path)-1, "%s/lua.rock", VIEWERS_DIR); /* Use a #define here ? */
617 plugin = lua_path;
617 argument = buf; 618 argument = buf;
618 } 619 }
619 620
diff --git a/apps/filetypes.c b/apps/filetypes.c
index 4be2437a29..67a4c176fb 100644
--- a/apps/filetypes.c
+++ b/apps/filetypes.c
@@ -175,7 +175,7 @@ static char *filetypes_strdup(char* string)
175 return buffer; 175 return buffer;
176} 176}
177static void read_builtin_types(void); 177static void read_builtin_types(void);
178static void read_config(char* config_file); 178static void read_config(const char* config_file);
179#ifdef HAVE_LCD_COLOR 179#ifdef HAVE_LCD_COLOR
180/* Colors file format is similar to icons: 180/* Colors file format is similar to icons:
181 * ext:hex_color 181 * ext:hex_color
@@ -272,6 +272,7 @@ void read_viewer_theme_file(void)
272 272
273void filetype_init(void) 273void filetype_init(void)
274{ 274{
275 char path[MAX_PATH];
275 /* set the directory item first */ 276 /* set the directory item first */
276 filetypes[0].extension = NULL; 277 filetypes[0].extension = NULL;
277 filetypes[0].plugin = NULL; 278 filetypes[0].plugin = NULL;
@@ -280,7 +281,7 @@ void filetype_init(void)
280 281
281 filetype_count = 1; 282 filetype_count = 1;
282 read_builtin_types(); 283 read_builtin_types();
283 read_config(VIEWERS_CONFIG); 284 read_config(get_user_file_path(VIEWERS_CONFIG, IS_FILE, path, sizeof(path)));
284#ifdef HAVE_LCD_BITMAP 285#ifdef HAVE_LCD_BITMAP
285 read_viewer_theme_file(); 286 read_viewer_theme_file();
286#endif 287#endif
@@ -320,7 +321,7 @@ static void read_builtin_types(void)
320 } 321 }
321} 322}
322 323
323static void read_config(char* config_file) 324static void read_config(const char* config_file)
324{ 325{
325 char line[64], *s, *e; 326 char line[64], *s, *e;
326 char extension[8], plugin[32]; 327 char extension[8], plugin[32];
diff --git a/apps/gui/skin_engine/skin_fonts.c b/apps/gui/skin_engine/skin_fonts.c
index 92a6a22ccf..b3b4df2c92 100644
--- a/apps/gui/skin_engine/skin_fonts.c
+++ b/apps/gui/skin_engine/skin_fonts.c
@@ -100,7 +100,7 @@ int skin_font_load(char* font_name)
100 pf->buffer_size = SKIN_FONT_SIZE; 100 pf->buffer_size = SKIN_FONT_SIZE;
101 101
102 snprintf(filename, MAX_PATH, FONT_DIR "/%s.fnt", font_name); 102 snprintf(filename, MAX_PATH, FONT_DIR "/%s.fnt", font_name);
103 strcpy(font->name, font_name); 103 get_user_file_path(filename, FORCE_BUFFER_COPY, font->name, sizeof(font->name));
104 104
105 pf->fd = -1; 105 pf->fd = -1;
106 font->font_id = font_load(pf, filename); 106 font->font_id = font_load(pf, filename);
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index e5c89ab2b1..d0194c669b 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -1452,7 +1452,8 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
1452 strlcpy(bmpdir, buf, dot - buf + 1); 1452 strlcpy(bmpdir, buf, dot - buf + 1);
1453 } 1453 }
1454 else 1454 else
1455 { 1455 { /* fall back to backdrop dir for built-in themes */
1456 /* no get_user_file_path(), assuming we ship bmps for built-in themes */
1456 snprintf(bmpdir, MAX_PATH, "%s", BACKDROP_DIR); 1457 snprintf(bmpdir, MAX_PATH, "%s", BACKDROP_DIR);
1457 } 1458 }
1458 /* load the bitmaps that were found by the parsing */ 1459 /* load the bitmaps that were found by the parsing */
diff --git a/apps/gui/theme_settings.c b/apps/gui/theme_settings.c
index e9862eda3a..a975c218cd 100644
--- a/apps/gui/theme_settings.c
+++ b/apps/gui/theme_settings.c
@@ -97,7 +97,9 @@ void settings_apply_skins(void)
97 CHART2(">skin load ", skins[i].suffix); 97 CHART2(">skin load ", skins[i].suffix);
98 if (skins[i].setting[0] && skins[i].setting[0] != '-') 98 if (skins[i].setting[0] && skins[i].setting[0] != '-')
99 { 99 {
100 snprintf(buf, sizeof buf, WPS_DIR "/%s.%s", 100 char path[MAX_PATH];
101 snprintf(buf, sizeof buf, "%s/%s.%s",
102 get_user_file_path(WPS_DIR, false, path, sizeof(path)),
101 skins[i].setting, skins[i].suffix); 103 skins[i].setting, skins[i].suffix);
102 skins[i].loadfunc(screen, buf, true); 104 skins[i].loadfunc(screen, buf, true);
103 } 105 }
diff --git a/apps/main.c b/apps/main.c
index 6c6d09cbaa..67cd6d2f0d 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -131,6 +131,9 @@ static void init(void);
131#endif 131#endif
132int main(int argc, char *argv[]) 132int main(int argc, char *argv[])
133{ 133{
134#ifdef APPLICATION
135 paths_init();
136#endif
134 sys_handle_argv(argc, argv); 137 sys_handle_argv(argc, argv);
135#else 138#else
136/* main(), and various functions called by main() and init() may be 139/* main(), and various functions called by main() and init() may be
@@ -163,11 +166,17 @@ int main(void)
163 166
164#ifdef AUTOROCK 167#ifdef AUTOROCK
165 { 168 {
166 static const char filename[] = PLUGIN_APPS_DIR "/autostart.rock"; 169 char filename[MAX_PATH];
167 170 const char *file = get_user_file_path(
168 if(file_exists(filename)) /* no complaint if it doesn't exist */ 171#ifdef APPLICATION
172 ROCKBOX_DIR
173#else
174 PLUGIN_APPS_DIR
175#endif
176 "/autostart.rock", NEED_WRITE|IS_FILE, filename, sizeof(filename));
177 if(file_exists(file)) /* no complaint if it doesn't exist */
169 { 178 {
170 plugin_load((char*)filename, NULL); /* start if it does */ 179 plugin_load(file, NULL); /* start if it does */
171 } 180 }
172 } 181 }
173#endif /* #ifdef AUTOROCK */ 182#endif /* #ifdef AUTOROCK */
diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c
index a64b1f8e47..1d22dba7ea 100644
--- a/apps/menus/main_menu.c
+++ b/apps/menus/main_menu.c
@@ -110,9 +110,12 @@ MAKE_MENU(manage_settings, ID2P(LANG_MANAGE_MENU), NULL, Icon_Config,
110/***********************************/ 110/***********************************/
111/* INFO MENU */ 111/* INFO MENU */
112 112
113
113static bool show_credits(void) 114static bool show_credits(void)
114{ 115{
115 if (plugin_load(VIEWERS_DIR "/credits.rock",NULL) != PLUGIN_OK) 116 char credits[MAX_PATH] = { '\0' };
117 snprintf(credits, MAX_PATH, "%s/credits.rock", VIEWERS_DIR);
118 if (plugin_load(credits, NULL) != PLUGIN_OK)
116 { 119 {
117 /* show the rockbox logo and version untill a button is pressed */ 120 /* show the rockbox logo and version untill a button is pressed */
118 show_logo(); 121 show_logo();
diff --git a/apps/menus/theme_menu.c b/apps/menus/theme_menu.c
index f8fb06b22f..c6553728a1 100644
--- a/apps/menus/theme_menu.c
+++ b/apps/menus/theme_menu.c
@@ -241,9 +241,11 @@ static struct browse_folder_info themes = {THEME_DIR, SHOW_CFG};
241 241
242int browse_folder(void *param) 242int browse_folder(void *param)
243{ 243{
244 char path[MAX_PATH];
244 const struct browse_folder_info *info = 245 const struct browse_folder_info *info =
245 (const struct browse_folder_info*)param; 246 (const struct browse_folder_info*)param;
246 return rockbox_browse(info->dir, info->show_options); 247 return rockbox_browse(get_user_file_path(info->dir, 0, path, sizeof(path)),
248 info->show_options);
247} 249}
248 250
249#ifdef HAVE_LCD_BITMAP 251#ifdef HAVE_LCD_BITMAP
diff --git a/apps/misc.c b/apps/misc.c
index c378133ab2..39f17be298 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -742,35 +742,6 @@ char* strrsplt(char* str, int c)
742 return s; 742 return s;
743} 743}
744 744
745/* Test file existence, using dircache of possible */
746bool file_exists(const char *file)
747{
748 int fd;
749
750 if (!file || strlen(file) <= 0)
751 return false;
752
753#ifdef HAVE_DIRCACHE
754 if (dircache_is_enabled())
755 return (dircache_get_entry_ptr(file) != NULL);
756#endif
757
758 fd = open(file, O_RDONLY);
759 if (fd < 0)
760 return false;
761 close(fd);
762 return true;
763}
764
765bool dir_exists(const char *path)
766{
767 DIR* d = opendir(path);
768 if (!d)
769 return false;
770 closedir(d);
771 return true;
772}
773
774/* 745/*
775 * removes the extension of filename (if it doesn't start with a .) 746 * removes the extension of filename (if it doesn't start with a .)
776 * puts the result in buffer 747 * puts the result in buffer
diff --git a/apps/misc.h b/apps/misc.h
index 58a9085d55..0de68a001c 100644
--- a/apps/misc.h
+++ b/apps/misc.h
@@ -84,8 +84,6 @@ int hex_to_rgb(const char* hex, int* color);
84 84
85char* strrsplt(char* str, int c); 85char* strrsplt(char* str, int c);
86char* skip_whitespace(char* const str); 86char* skip_whitespace(char* const str);
87bool file_exists(const char *file);
88bool dir_exists(const char *path);
89 87
90/* 88/*
91 * removes the extension of filename (if it doesn't start with a .) 89 * removes the extension of filename (if it doesn't start with a .)
diff --git a/apps/playlist.c b/apps/playlist.c
index 4a6db883f7..2896f62e76 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -86,6 +86,7 @@
86#include "screens.h" 86#include "screens.h"
87#include "buffer.h" 87#include "buffer.h"
88#include "misc.h" 88#include "misc.h"
89#include "filefuncs.h"
89#include "button.h" 90#include "button.h"
90#include "filetree.h" 91#include "filetree.h"
91#include "abrepeat.h" 92#include "abrepeat.h"
@@ -103,7 +104,6 @@
103#include "rbunicode.h" 104#include "rbunicode.h"
104#include "root_menu.h" 105#include "root_menu.h"
105 106
106#define PLAYLIST_CONTROL_FILE ROCKBOX_DIR "/.playlist_control"
107#define PLAYLIST_CONTROL_FILE_VERSION 2 107#define PLAYLIST_CONTROL_FILE_VERSION 2
108 108
109/* 109/*
@@ -1440,7 +1440,12 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
1440 /* process random folder advance */ 1440 /* process random folder advance */
1441 if (global_settings.next_folder == FOLDER_ADVANCE_RANDOM) 1441 if (global_settings.next_folder == FOLDER_ADVANCE_RANDOM)
1442 { 1442 {
1443 int fd = open(ROCKBOX_DIR "/folder_advance_list.dat", O_RDONLY); 1443 char folder_advance_list[MAX_PATH];
1444 get_user_file_path(ROCKBOX_DIR, FORCE_BUFFER_COPY,
1445 folder_advance_list, sizeof(folder_advance_list));
1446 strlcat(folder_advance_list, "/folder_advance_list.dat",
1447 sizeof(folder_advance_list));
1448 int fd = open(folder_advance_list, O_RDONLY);
1444 if (fd >= 0) 1449 if (fd >= 0)
1445 { 1450 {
1446 char buffer[MAX_PATH]; 1451 char buffer[MAX_PATH];
@@ -1910,7 +1915,8 @@ void playlist_init(void)
1910 struct playlist_info* playlist = &current_playlist; 1915 struct playlist_info* playlist = &current_playlist;
1911 1916
1912 playlist->current = true; 1917 playlist->current = true;
1913 strlcpy(playlist->control_filename, PLAYLIST_CONTROL_FILE, 1918 get_user_file_path(PLAYLIST_CONTROL_FILE, IS_FILE|NEED_WRITE|FORCE_BUFFER_COPY,
1919 playlist->control_filename,
1914 sizeof(playlist->control_filename)); 1920 sizeof(playlist->control_filename));
1915 playlist->fd = -1; 1921 playlist->fd = -1;
1916 playlist->control_fd = -1; 1922 playlist->control_fd = -1;
diff --git a/apps/playlist_catalog.c b/apps/playlist_catalog.c
index f9a43da411..2fbffdaa3c 100644
--- a/apps/playlist_catalog.c
+++ b/apps/playlist_catalog.c
@@ -32,6 +32,7 @@
32#include "lang.h" 32#include "lang.h"
33#include "list.h" 33#include "list.h"
34#include "misc.h" 34#include "misc.h"
35#include "filefuncs.h"
35#include "onplay.h" 36#include "onplay.h"
36#include "playlist.h" 37#include "playlist.h"
37#include "settings.h" 38#include "settings.h"
@@ -77,8 +78,13 @@ static int initialize_catalog(void)
77 78
78 /* fall back to default directory if no or invalid config */ 79 /* fall back to default directory if no or invalid config */
79 if (default_dir) 80 if (default_dir)
80 strlcpy(playlist_dir, PLAYLIST_CATALOG_DEFAULT_DIR, 81 {
81 sizeof(playlist_dir)); 82 const char *dir = get_user_file_path(PLAYLIST_CATALOG_DEFAULT_DIR,
83 FORCE_BUFFER_COPY|NEED_WRITE,
84 playlist_dir, sizeof(playlist_dir));
85 if (!dir_exists(dir))
86 mkdir(dir);
87 }
82 88
83 playlist_dir_length = strlen(playlist_dir); 89 playlist_dir_length = strlen(playlist_dir);
84 90
diff --git a/apps/plugin.c b/apps/plugin.c
index 81ba006af7..b3baea757c 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -41,6 +41,7 @@
41#include "pcmbuf.h" 41#include "pcmbuf.h"
42#include "errno.h" 42#include "errno.h"
43#include "diacritic.h" 43#include "diacritic.h"
44#include "filefuncs.h"
44 45
45#if CONFIG_CHARGING 46#if CONFIG_CHARGING
46#include "power.h" 47#include "power.h"
diff --git a/apps/plugin.h b/apps/plugin.h
index cf1fd77426..5ee18d0078 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -66,6 +66,7 @@ void* plugin_get_buffer(size_t *buffer_size);
66#include "profile.h" 66#include "profile.h"
67#endif 67#endif
68#include "misc.h" 68#include "misc.h"
69#include "filefuncs.h"
69#if (CONFIG_CODEC == SWCODEC) 70#if (CONFIG_CODEC == SWCODEC)
70#include "dsp.h" 71#include "dsp.h"
71#include "codecs.h" 72#include "codecs.h"
diff --git a/apps/radio/presets.c b/apps/radio/presets.c
index aa265bcc74..e900afe734 100644
--- a/apps/radio/presets.c
+++ b/apps/radio/presets.c
@@ -30,6 +30,7 @@
30#include "file.h" 30#include "file.h"
31#include "string-extra.h" 31#include "string-extra.h"
32#include "misc.h" 32#include "misc.h"
33#include "filefuncs.h"
33#include "lang.h" 34#include "lang.h"
34#include "action.h" 35#include "action.h"
35#include "list.h" 36#include "list.h"
diff --git a/apps/radio/radioart.c b/apps/radio/radioart.c
index 7ba9881d84..85397c16b6 100644
--- a/apps/radio/radioart.c
+++ b/apps/radio/radioart.c
@@ -30,6 +30,7 @@
30#include "kernel.h" 30#include "kernel.h"
31#include "string-extra.h" 31#include "string-extra.h"
32#include "misc.h" 32#include "misc.h"
33#include "filefuncs.h"
33 34
34#define MAX_RADIOART_IMAGES 10 35#define MAX_RADIOART_IMAGES 10
35struct radioart { 36struct radioart {
diff --git a/apps/recorder/albumart.c b/apps/recorder/albumart.c
index 5eca713542..6b43576698 100644
--- a/apps/recorder/albumart.c
+++ b/apps/recorder/albumart.c
@@ -26,6 +26,7 @@
26#include "buffering.h" 26#include "buffering.h"
27#include "dircache.h" 27#include "dircache.h"
28#include "misc.h" 28#include "misc.h"
29#include "filefuncs.h"
29#include "settings.h" 30#include "settings.h"
30#include "wps.h" 31#include "wps.h"
31 32
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index ab7e7c9b32..0098d6bf78 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -56,7 +56,7 @@
56#include "sound_menu.h" 56#include "sound_menu.h"
57#include "timefuncs.h" 57#include "timefuncs.h"
58#include "debug.h" 58#include "debug.h"
59#include "misc.h" 59#include "filefuncs.h"
60#include "tree.h" 60#include "tree.h"
61#include "string.h" 61#include "string.h"
62#include "dir.h" 62#include "dir.h"
diff --git a/apps/root_menu.c b/apps/root_menu.c
index 53c522a773..7965673b67 100644
--- a/apps/root_menu.c
+++ b/apps/root_menu.c
@@ -341,7 +341,7 @@ static int plugins_menu(void* param)
341 MENUITEM_STRINGLIST(plugins_menu_items, ID2P(LANG_PLUGINS), NULL, 341 MENUITEM_STRINGLIST(plugins_menu_items, ID2P(LANG_PLUGINS), NULL,
342 ID2P(LANG_PLUGIN_GAMES), 342 ID2P(LANG_PLUGIN_GAMES),
343 ID2P(LANG_PLUGIN_APPS), ID2P(LANG_PLUGIN_DEMOS)); 343 ID2P(LANG_PLUGIN_APPS), ID2P(LANG_PLUGIN_DEMOS));
344 char *folder; 344 const char *folder;
345 int retval = GO_TO_PREVIOUS; 345 int retval = GO_TO_PREVIOUS;
346 int selection = 0, current = 0; 346 int selection = 0, current = 0;
347 while (retval == GO_TO_PREVIOUS) 347 while (retval == GO_TO_PREVIOUS)
@@ -646,7 +646,13 @@ void root_menu(void)
646 if ( action_userabort(HZ/5) ) 646 if ( action_userabort(HZ/5) )
647 break; 647 break;
648 } 648 }
649 next_screen = load_plugin_screen(PLUGIN_DEMOS_DIR "/pictureflow.rock"); 649 {
650 char pf_path[MAX_PATH];
651 snprintf(pf_path, sizeof(pf_path),
652 "%s/pictureflow.rock",
653 PLUGIN_DEMOS_DIR);
654 next_screen = load_plugin_screen(pf_path);
655 }
650 previous_browser = GO_TO_PICTUREFLOW; 656 previous_browser = GO_TO_PICTUREFLOW;
651 break; 657 break;
652#endif 658#endif
diff --git a/apps/scrobbler.c b/apps/scrobbler.c
index 8d9f694ec2..9b0decfb68 100644
--- a/apps/scrobbler.c
+++ b/apps/scrobbler.c
@@ -33,7 +33,7 @@ http://www.audioscrobbler.net/wiki/Portable_Player_Logging
33#include "buffer.h" 33#include "buffer.h"
34#include "settings.h" 34#include "settings.h"
35#include "ata_idle_notify.h" 35#include "ata_idle_notify.h"
36#include "misc.h" 36#include "filefuncs.h"
37#include "appevents.h" 37#include "appevents.h"
38 38
39#if CONFIG_RTC 39#if CONFIG_RTC
diff --git a/apps/settings.c b/apps/settings.c
index 6f1fd7ad2e..58585d60e1 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -25,6 +25,7 @@
25#include <limits.h> 25#include <limits.h>
26#include "inttypes.h" 26#include "inttypes.h"
27#include "config.h" 27#include "config.h"
28#include "rbpaths.h"
28#include "action.h" 29#include "action.h"
29#include "crc32.h" 30#include "crc32.h"
30#include "sound.h" 31#include "sound.h"
@@ -110,7 +111,6 @@ long lasttime = 0;
110[8-NVRAM_BLOCK_SIZE] data 111[8-NVRAM_BLOCK_SIZE] data
111*/ 112*/
112#define NVRAM_DATA_START 8 113#define NVRAM_DATA_START 8
113#define NVRAM_FILE ROCKBOX_DIR "/nvram.bin"
114static char nvram_buffer[NVRAM_BLOCK_SIZE]; 114static char nvram_buffer[NVRAM_BLOCK_SIZE];
115 115
116static bool read_nvram_data(char* buf, int max_len) 116static bool read_nvram_data(char* buf, int max_len)
@@ -118,7 +118,9 @@ static bool read_nvram_data(char* buf, int max_len)
118 unsigned crc32 = 0xffffffff; 118 unsigned crc32 = 0xffffffff;
119 int var_count = 0, i = 0, buf_pos = 0; 119 int var_count = 0, i = 0, buf_pos = 0;
120#ifndef HAVE_RTC_RAM 120#ifndef HAVE_RTC_RAM
121 int fd = open(NVRAM_FILE,O_RDONLY); 121 char path[MAX_PATH];
122 int fd = open(get_user_file_path(NVRAM_FILE, IS_FILE|NEED_WRITE,
123 path, sizeof(path)), O_RDONLY);
122 int bytes; 124 int bytes;
123 if (fd < 0) 125 if (fd < 0)
124 return false; 126 return false;
@@ -172,6 +174,7 @@ static bool write_nvram_data(char* buf, int max_len)
172 char var_count = 0; 174 char var_count = 0;
173#ifndef HAVE_RTC_RAM 175#ifndef HAVE_RTC_RAM
174 int fd; 176 int fd;
177 char path[MAX_PATH];
175#endif 178#endif
176 memset(buf,0,max_len); 179 memset(buf,0,max_len);
177 /* magic, version */ 180 /* magic, version */
@@ -195,7 +198,8 @@ static bool write_nvram_data(char* buf, int max_len)
195 max_len-NVRAM_DATA_START-1,0xffffffff); 198 max_len-NVRAM_DATA_START-1,0xffffffff);
196 memcpy(&buf[4],&crc32,4); 199 memcpy(&buf[4],&crc32,4);
197#ifndef HAVE_RTC_RAM 200#ifndef HAVE_RTC_RAM
198 fd = open(NVRAM_FILE,O_CREAT|O_TRUNC|O_WRONLY, 0666); 201 fd = open(get_user_file_path(NVRAM_FILE, IS_FILE|NEED_WRITE,
202 path, sizeof(path)),O_CREAT|O_TRUNC|O_WRONLY, 0666);
199 if (fd >= 0) 203 if (fd >= 0)
200 { 204 {
201 int len = write(fd,buf,max_len); 205 int len = write(fd,buf,max_len);
@@ -226,8 +230,12 @@ void settings_load(int which)
226 read_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE); 230 read_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
227 if (which&SETTINGS_HD) 231 if (which&SETTINGS_HD)
228 { 232 {
229 settings_load_config(CONFIGFILE,false); 233 const char *file;
230 settings_load_config(FIXEDSETTINGSFILE,false); 234 char path[MAX_PATH];
235 file = get_user_file_path(CONFIGFILE, IS_FILE|NEED_WRITE, path, sizeof(path));
236 settings_load_config(file, false);
237 file = get_user_file_path(FIXEDSETTINGSFILE, IS_FILE, path, sizeof(path));
238 settings_load_config(file, false);
231 } 239 }
232} 240}
233 241
@@ -334,10 +342,12 @@ bool settings_load_config(const char* file, bool apply)
334 char storage[MAX_PATH]; 342 char storage[MAX_PATH];
335 if (settings[i].filename_setting->prefix) 343 if (settings[i].filename_setting->prefix)
336 { 344 {
337 int len = strlen(settings[i].filename_setting->prefix); 345 char prefix_dir[MAX_PATH];
338 if (!strncasecmp(value, 346 const char *dir = get_user_file_path(
339 settings[i].filename_setting->prefix, 347 settings[i].filename_setting->prefix,
340 len)) 348 0, prefix_dir, sizeof(prefix_dir));
349 int len = strlen(dir);
350 if (!strncasecmp(value, dir, len))
341 { 351 {
342 strlcpy(storage, &value[len], MAX_PATH); 352 strlcpy(storage, &value[len], MAX_PATH);
343 } 353 }
@@ -470,6 +480,10 @@ bool cfg_to_string(int i/*setting_id*/, char* buf, int buf_len)
470 if (((char*)settings[i].setting)[0] 480 if (((char*)settings[i].setting)[0]
471 && settings[i].filename_setting->prefix) 481 && settings[i].filename_setting->prefix)
472 { 482 {
483 char path[MAX_PATH];
484 const char *prefix = get_user_file_path(
485 settings[i].filename_setting->prefix, 0,
486 path, sizeof(path));
473 if (((char*)settings[i].setting)[0] == '-') 487 if (((char*)settings[i].setting)[0] == '-')
474 { 488 {
475 buf[0] = '-'; 489 buf[0] = '-';
@@ -477,8 +491,7 @@ bool cfg_to_string(int i/*setting_id*/, char* buf, int buf_len)
477 } 491 }
478 else 492 else
479 { 493 {
480 snprintf(buf,buf_len,"%s%s%s", 494 snprintf(buf,buf_len,"%s%s%s", prefix,
481 settings[i].filename_setting->prefix,
482 (char*)settings[i].setting, 495 (char*)settings[i].setting,
483 settings[i].filename_setting->suffix); 496 settings[i].filename_setting->suffix);
484 } 497 }
@@ -589,8 +602,11 @@ static void flush_global_status_callback(void *data)
589static void flush_config_block_callback(void *data) 602static void flush_config_block_callback(void *data)
590{ 603{
591 (void)data; 604 (void)data;
605 char path[MAX_PATH];
592 write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE); 606 write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
593 settings_write_config(CONFIGFILE, SETTINGS_SAVE_CHANGED); 607 settings_write_config(
608 get_user_file_path(CONFIGFILE, IS_FILE|NEED_WRITE, path, sizeof(path)),
609 SETTINGS_SAVE_CHANGED);
594} 610}
595 611
596/* 612/*
@@ -634,8 +650,8 @@ int settings_save(void)
634 650
635bool settings_save_config(int options) 651bool settings_save_config(int options)
636{ 652{
637 char filename[MAX_PATH]; 653 char filename[MAX_PATH], path[MAX_PATH];
638 char *folder, *namebase; 654 const char *folder, *namebase;
639 switch (options) 655 switch (options)
640 { 656 {
641 case SETTINGS_SAVE_THEME: 657 case SETTINGS_SAVE_THEME:
@@ -663,6 +679,8 @@ bool settings_save_config(int options)
663 namebase = "config"; 679 namebase = "config";
664 break; 680 break;
665 } 681 }
682
683 folder = get_user_file_path(folder, NEED_WRITE, path, sizeof(path));
666 create_numbered_filename(filename, folder, namebase, ".cfg", 2 684 create_numbered_filename(filename, folder, namebase, ".cfg", 2
667 IF_CNFN_NUM_(, NULL)); 685 IF_CNFN_NUM_(, NULL));
668 686
@@ -1180,6 +1198,7 @@ bool set_option(const char* string, const void* variable, enum optiontype type,
1180 if (!option_screen(&item, NULL, false, NULL)) 1198 if (!option_screen(&item, NULL, false, NULL))
1181 { 1199 {
1182 if (type == BOOL) 1200 if (type == BOOL)
1201
1183 *(bool*)variable = (temp == 1); 1202 *(bool*)variable = (temp == 1);
1184 else 1203 else
1185 *(int*)variable = temp; 1204 *(int*)variable = temp;
diff --git a/apps/settings.h b/apps/settings.h
index 63305b5ae7..7deb2def41 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -33,6 +33,7 @@
33#if CONFIG_CODEC == SWCODEC 33#if CONFIG_CODEC == SWCODEC
34#include "audio.h" 34#include "audio.h"
35#endif 35#endif
36#include "rbpaths.h"
36 37
37struct opt_items { 38struct opt_items {
38 unsigned const char* string; 39 unsigned const char* string;
@@ -40,50 +41,6 @@ struct opt_items {
40}; 41};
41 42
42/** Setting values defines **/ 43/** Setting values defines **/
43
44/* name of directory where configuration, fonts and other data
45 * files are stored */
46#ifdef __PCTOOL__
47#undef ROCKBOX_DIR
48#undef ROCKBOX_DIR_LEN
49#undef WPS_DIR
50#define ROCKBOX_DIR "."
51#define ROCKBOX_DIR_LEN 1
52#else
53
54/* ROCKBOX_DIR is now defined in autoconf.h for flexible build types */
55#ifndef ROCKBOX_DIR
56#error ROCKBOX_DIR not defined (should be in autoconf.h)
57#endif
58#define ROCKBOX_DIR_LEN (sizeof(ROCKBOX_DIR)-1)
59#endif /* def __PCTOOL__ */
60
61
62#define FONT_DIR ROCKBOX_DIR "/fonts"
63#define LANG_DIR ROCKBOX_DIR "/langs"
64#define WPS_DIR ROCKBOX_DIR "/wps"
65#define SBS_DIR WPS_DIR
66#define THEME_DIR ROCKBOX_DIR "/themes"
67#define ICON_DIR ROCKBOX_DIR "/icons"
68
69#define PLUGIN_DIR ROCKBOX_DIR "/rocks"
70#define PLUGIN_GAMES_DIR PLUGIN_DIR "/games"
71#define PLUGIN_APPS_DIR PLUGIN_DIR "/apps"
72#define PLUGIN_DEMOS_DIR PLUGIN_DIR "/demos"
73#define VIEWERS_DIR PLUGIN_DIR "/viewers"
74
75#define BACKDROP_DIR ROCKBOX_DIR "/backdrops"
76#define REC_BASE_DIR "/"
77#define EQS_DIR ROCKBOX_DIR "/eqs"
78#define CODECS_DIR ROCKBOX_DIR "/codecs"
79#define RECPRESETS_DIR ROCKBOX_DIR "/recpresets"
80#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
81#define PLAYLIST_CATALOG_DEFAULT_DIR "/Playlists"
82
83#define VIEWERS_CONFIG ROCKBOX_DIR "/viewers.config"
84#define CONFIGFILE ROCKBOX_DIR "/config.cfg"
85#define FIXEDSETTINGSFILE ROCKBOX_DIR "/fixed.cfg"
86
87#define MAX_FILENAME 32 44#define MAX_FILENAME 32
88 45
89 46
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 1094c92a97..898263ef23 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -73,6 +73,7 @@
73#include "buffer.h" 73#include "buffer.h"
74#include "crc32.h" 74#include "crc32.h"
75#include "misc.h" 75#include "misc.h"
76#include "filefuncs.h"
76#include "settings.h" 77#include "settings.h"
77#include "dir.h" 78#include "dir.h"
78#include "structec.h" 79#include "structec.h"
@@ -292,15 +293,17 @@ static bool is_dircache_intact(void)
292static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write) 293static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
293{ 294{
294 int fd; 295 int fd;
295 char buf[MAX_PATH]; 296 char buf[MAX_PATH], path[MAX_PATH];
297 const char * file;
296 int rc; 298 int rc;
297 299
298 if (TAGCACHE_IS_NUMERIC(tag) || tag < 0 || tag >= TAG_COUNT) 300 if (TAGCACHE_IS_NUMERIC(tag) || tag < 0 || tag >= TAG_COUNT)
299 return -1; 301 return -1;
300 302
301 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag); 303 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag);
304 file = get_user_file_path(buf, IS_FILE | NEED_WRITE, path, sizeof(path));
302 305
303 fd = open(buf, write ? O_RDWR : O_RDONLY); 306 fd = open(file, write ? O_RDWR : O_RDONLY);
304 if (fd < 0) 307 if (fd < 0)
305 { 308 {
306 logf("tag file open failed: tag=%d write=%d file=%s", tag, write, buf); 309 logf("tag file open failed: tag=%d write=%d file=%s", tag, write, buf);
@@ -325,8 +328,12 @@ static int open_master_fd(struct master_header *hdr, bool write)
325{ 328{
326 int fd; 329 int fd;
327 int rc; 330 int rc;
331 char path[MAX_PATH];
328 332
329 fd = open(TAGCACHE_FILE_MASTER, write ? O_RDWR : O_RDONLY); 333 fd = open(get_user_file_path(TAGCACHE_FILE_MASTER,
334 IS_FILE|NEED_WRITE,
335 path, sizeof(path)),
336 write ? O_RDWR : O_RDONLY);
330 if (fd < 0) 337 if (fd < 0)
331 { 338 {
332 logf("master file open failed for R/W"); 339 logf("master file open failed for R/W");
@@ -668,9 +675,11 @@ static bool open_files(struct tagcache_search *tcs, int tag)
668{ 675{
669 if (tcs->idxfd[tag] < 0) 676 if (tcs->idxfd[tag] < 0)
670 { 677 {
671 char fn[MAX_PATH]; 678 char fn[MAX_PATH], path[MAX_PATH];
679 const char *file;
672 680
673 snprintf(fn, sizeof fn, TAGCACHE_FILE_INDEX, tag); 681 snprintf(fn, sizeof fn, TAGCACHE_FILE_INDEX, tag);
682 file = get_user_file_path(fn, IS_FILE | NEED_WRITE, path, sizeof(path));
674 tcs->idxfd[tag] = open(fn, O_RDONLY); 683 tcs->idxfd[tag] = open(fn, O_RDONLY);
675 } 684 }
676 685
@@ -1159,14 +1168,17 @@ static void remove_files(void)
1159 tc_stat.ready = false; 1168 tc_stat.ready = false;
1160 tc_stat.ramcache = false; 1169 tc_stat.ramcache = false;
1161 tc_stat.econ = false; 1170 tc_stat.econ = false;
1162 remove(TAGCACHE_FILE_MASTER); 1171 remove(get_user_file_path(TAGCACHE_FILE_MASTER, NEED_WRITE|IS_FILE,
1172 buf, sizeof(buf)));
1163 for (i = 0; i < TAG_COUNT; i++) 1173 for (i = 0; i < TAG_COUNT; i++)
1164 { 1174 {
1175 char buf2[MAX_PATH];
1165 if (TAGCACHE_IS_NUMERIC(i)) 1176 if (TAGCACHE_IS_NUMERIC(i))
1166 continue; 1177 continue;
1167 1178
1179 /* database_%d.tcd -> database_0.tcd */
1168 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, i); 1180 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, i);
1169 remove(buf); 1181 remove(get_user_file_path(buf, NEED_WRITE | IS_FILE, buf2, sizeof(buf2)));
1170 } 1182 }
1171} 1183}
1172 1184
@@ -1317,10 +1329,11 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs,
1317 1329
1318 if (!TAGCACHE_IS_NUMERIC(clause->tag) && tcs->idxfd[clause->tag] < 0) 1330 if (!TAGCACHE_IS_NUMERIC(clause->tag) && tcs->idxfd[clause->tag] < 0)
1319 { 1331 {
1320 char buf[MAX_PATH]; 1332 char buf[MAX_PATH], path[MAX_PATH];
1321 1333 const char *file;
1322 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, clause->tag); 1334 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, clause->tag);
1323 tcs->idxfd[clause->tag] = open(buf, O_RDONLY); 1335 file = get_user_file_path(buf, IS_FILE | NEED_WRITE, path, sizeof(path));
1336 tcs->idxfd[clause->tag] = open(file, O_RDONLY);
1324 } 1337 }
1325 1338
1326 tcs->clause[tcs->clause_count] = clause; 1339 tcs->clause[tcs->clause_count] = clause;
@@ -2344,7 +2357,8 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2344 struct master_header tcmh; 2357 struct master_header tcmh;
2345 struct index_entry idxbuf[IDX_BUF_DEPTH]; 2358 struct index_entry idxbuf[IDX_BUF_DEPTH];
2346 int idxbuf_pos; 2359 int idxbuf_pos;
2347 char buf[TAG_MAXLEN+32]; 2360 char buf[TAG_MAXLEN+32], path[MAX_PATH];
2361 const char *file;
2348 int fd = -1, masterfd; 2362 int fd = -1, masterfd;
2349 bool error = false; 2363 bool error = false;
2350 int init; 2364 int init;
@@ -2492,7 +2506,8 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2492 * anything whether the index type is sorted or not. 2506 * anything whether the index type is sorted or not.
2493 */ 2507 */
2494 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, index_type); 2508 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, index_type);
2495 fd = open(buf, O_WRONLY | O_CREAT | O_TRUNC, 0666); 2509 file = get_user_file_path(buf, IS_FILE | NEED_WRITE, path, sizeof(path));
2510 fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
2496 if (fd < 0) 2511 if (fd < 0)
2497 { 2512 {
2498 logf("%s open fail", buf); 2513 logf("%s open fail", buf);
@@ -2512,18 +2527,21 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2512 } 2527 }
2513 } 2528 }
2514 2529
2530 file = get_user_file_path(TAGCACHE_FILE_MASTER,
2531 IS_FILE|NEED_WRITE,
2532 buf, sizeof(buf));
2515 /* Loading the tag lookup file as "master file". */ 2533 /* Loading the tag lookup file as "master file". */
2516 logf("Loading index file"); 2534 logf("Loading index file");
2517 masterfd = open(TAGCACHE_FILE_MASTER, O_RDWR); 2535 masterfd = open(file, O_RDWR);
2518 2536
2519 if (masterfd < 0) 2537 if (masterfd < 0)
2520 { 2538 {
2521 logf("Creating new DB"); 2539 logf("Creating new DB");
2522 masterfd = open(TAGCACHE_FILE_MASTER, O_WRONLY | O_CREAT | O_TRUNC, 0666); 2540 masterfd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
2523 2541
2524 if (masterfd < 0) 2542 if (masterfd < 0)
2525 { 2543 {
2526 logf("Failure to create index file (%s)", TAGCACHE_FILE_MASTER); 2544 logf("Failure to create index file (%s)", file);
2527 close(fd); 2545 close(fd);
2528 return -2; 2546 return -2;
2529 } 2547 }
@@ -2831,6 +2849,8 @@ static bool commit(void)
2831{ 2849{
2832 struct tagcache_header tch; 2850 struct tagcache_header tch;
2833 struct master_header tcmh; 2851 struct master_header tcmh;
2852 char path[MAX_PATH];
2853 const char *file;
2834 int i, len, rc; 2854 int i, len, rc;
2835 int tmpfd; 2855 int tmpfd;
2836 int masterfd; 2856 int masterfd;
@@ -2844,7 +2864,10 @@ static bool commit(void)
2844 while (write_lock) 2864 while (write_lock)
2845 sleep(1); 2865 sleep(1);
2846 2866
2847 tmpfd = open(TAGCACHE_FILE_TEMP, O_RDONLY); 2867 file = get_user_file_path(TAGCACHE_FILE_TEMP,
2868 IS_FILE|NEED_WRITE, path, sizeof(path));
2869
2870 tmpfd = open(file, O_RDONLY);
2848 if (tmpfd < 0) 2871 if (tmpfd < 0)
2849 { 2872 {
2850 logf("nothing to commit"); 2873 logf("nothing to commit");
@@ -2860,7 +2883,7 @@ static bool commit(void)
2860 { 2883 {
2861 logf("incorrect tmpheader"); 2884 logf("incorrect tmpheader");
2862 close(tmpfd); 2885 close(tmpfd);
2863 remove(TAGCACHE_FILE_TEMP); 2886 remove(file);
2864 return false; 2887 return false;
2865 } 2888 }
2866 2889
@@ -2868,7 +2891,7 @@ static bool commit(void)
2868 { 2891 {
2869 logf("nothing to commit"); 2892 logf("nothing to commit");
2870 close(tmpfd); 2893 close(tmpfd);
2871 remove(TAGCACHE_FILE_TEMP); 2894 remove(file);
2872 return true; 2895 return true;
2873 } 2896 }
2874 2897
@@ -2876,7 +2899,8 @@ static bool commit(void)
2876 tc_stat.ready = check_all_headers(); 2899 tc_stat.ready = check_all_headers();
2877 2900
2878#ifdef HAVE_EEPROM_SETTINGS 2901#ifdef HAVE_EEPROM_SETTINGS
2879 remove(TAGCACHE_STATEFILE); 2902 remove(get_user_file_path(TAGCACHE_STATEFILE, IS_FILE | NEED_WRITE,
2903 path, sizeof(path)));
2880#endif 2904#endif
2881 2905
2882 /* At first be sure to unload the ramcache! */ 2906 /* At first be sure to unload the ramcache! */
@@ -2966,7 +2990,7 @@ static bool commit(void)
2966 } 2990 }
2967 2991
2968 close(tmpfd); 2992 close(tmpfd);
2969 remove(TAGCACHE_FILE_TEMP); 2993 remove(file);
2970 2994
2971 tc_stat.commit_step = 0; 2995 tc_stat.commit_step = 0;
2972 2996
@@ -3386,15 +3410,18 @@ bool tagcache_import_changelog(void)
3386 struct tagcache_header tch; 3410 struct tagcache_header tch;
3387 int clfd; 3411 int clfd;
3388 long masterfd; 3412 long masterfd;
3389 char buf[2048]; 3413 char buf[MAX(MAX_PATH, 2048)];
3414 const char *file;
3390 3415
3391 if (!tc_stat.ready) 3416 if (!tc_stat.ready)
3392 return false; 3417 return false;
3393 3418
3394 while (read_lock) 3419 while (read_lock)
3395 sleep(1); 3420 sleep(1);
3396 3421
3397 clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY); 3422 file = get_user_file_path(TAGCACHE_FILE_CHANGELOG,
3423 IS_FILE|NEED_WRITE, buf, sizeof(buf));
3424 clfd = open(file, O_RDONLY);
3398 if (clfd < 0) 3425 if (clfd < 0)
3399 { 3426 {
3400 logf("failure to open changelog"); 3427 logf("failure to open changelog");
@@ -3436,7 +3463,8 @@ bool tagcache_create_changelog(struct tagcache_search *tcs)
3436{ 3463{
3437 struct master_header myhdr; 3464 struct master_header myhdr;
3438 struct index_entry idx; 3465 struct index_entry idx;
3439 char buf[TAG_MAXLEN+32]; 3466 const char *file;
3467 char buf[MAX(TAG_MAXLEN+32, MAX_PATH)];
3440 char temp[32]; 3468 char temp[32];
3441 int clfd; 3469 int clfd;
3442 int i, j; 3470 int i, j;
@@ -3448,7 +3476,9 @@ bool tagcache_create_changelog(struct tagcache_search *tcs)
3448 return false; 3476 return false;
3449 3477
3450 /* Initialize the changelog */ 3478 /* Initialize the changelog */
3451 clfd = open(TAGCACHE_FILE_CHANGELOG, O_WRONLY | O_CREAT | O_TRUNC, 0666); 3479 file = get_user_file_path(TAGCACHE_FILE_CHANGELOG, IS_FILE | NEED_WRITE,
3480 buf, sizeof(buf));
3481 clfd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
3452 if (clfd < 0) 3482 if (clfd < 0)
3453 { 3483 {
3454 logf("failure to open changelog"); 3484 logf("failure to open changelog");
@@ -3766,11 +3796,15 @@ static bool allocate_tagcache(void)
3766static bool tagcache_dumpload(void) 3796static bool tagcache_dumpload(void)
3767{ 3797{
3768 struct statefile_header shdr; 3798 struct statefile_header shdr;
3799 char path[MAX_PATH];
3800 const char *file;
3769 int fd, rc; 3801 int fd, rc;
3770 long offpos; 3802 long offpos;
3771 int i; 3803 int i;
3772 3804
3773 fd = open(TAGCACHE_STATEFILE, O_RDONLY); 3805 file = get_user_file_path(TAGCACHE_STATEFILE, IS_FILE | NEED_WRITE,
3806 path, sizeof(path));
3807 fd = open(file, O_RDONLY);
3774 if (fd < 0) 3808 if (fd < 0)
3775 { 3809 {
3776 logf("no tagcache statedump"); 3810 logf("no tagcache statedump");
@@ -3816,12 +3850,16 @@ static bool tagcache_dumpload(void)
3816static bool tagcache_dumpsave(void) 3850static bool tagcache_dumpsave(void)
3817{ 3851{
3818 struct statefile_header shdr; 3852 struct statefile_header shdr;
3853 char path[MAX_PATH];
3854 const char *file;
3819 int fd; 3855 int fd;
3820 3856
3821 if (!tc_stat.ramcache) 3857 if (!tc_stat.ramcache)
3822 return false; 3858 return false;
3823 3859
3824 fd = open(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC, 0666); 3860 file = get_user_file_path(TAGCACHE_STATEFILE, IS_FILE | NEED_WRITE,
3861 path, sizeof(path));
3862 fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
3825 if (fd < 0) 3863 if (fd < 0)
3826 { 3864 {
3827 logf("failed to create a statedump"); 3865 logf("failed to create a statedump");
@@ -3847,7 +3885,8 @@ static bool load_tagcache(void)
3847 long bytesleft = tc_stat.ramcache_allocated; 3885 long bytesleft = tc_stat.ramcache_allocated;
3848 struct index_entry *idx; 3886 struct index_entry *idx;
3849 int rc, fd; 3887 int rc, fd;
3850 char *p; 3888 char *p, path[MAX_PATH];
3889 const char *file;
3851 int i, tag; 3890 int i, tag;
3852 3891
3853# ifdef HAVE_DIRCACHE 3892# ifdef HAVE_DIRCACHE
@@ -3858,8 +3897,11 @@ static bool load_tagcache(void)
3858# endif 3897# endif
3859 3898
3860 logf("loading tagcache to ram..."); 3899 logf("loading tagcache to ram...");
3861 3900
3862 fd = open(TAGCACHE_FILE_MASTER, O_RDONLY); 3901 file = get_user_file_path(TAGCACHE_FILE_MASTER,
3902 IS_FILE|NEED_WRITE,
3903 path, sizeof(path));
3904 fd = open(file, O_RDONLY);
3863 if (fd < 0) 3905 if (fd < 0)
3864 { 3906 {
3865 logf("tagcache open failed"); 3907 logf("tagcache open failed");
@@ -4069,12 +4111,14 @@ static bool load_tagcache(void)
4069static bool check_deleted_files(void) 4111static bool check_deleted_files(void)
4070{ 4112{
4071 int fd; 4113 int fd;
4072 char buf[TAG_MAXLEN+32]; 4114 char buf[TAG_MAXLEN+32], path[MAX_PATH];
4115 const char *file;
4073 struct tagfile_entry tfe; 4116 struct tagfile_entry tfe;
4074 4117
4075 logf("reverse scan..."); 4118 logf("reverse scan...");
4076 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag_filename); 4119 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag_filename);
4077 fd = open(buf, O_RDONLY); 4120 file = get_user_file_path(buf, IS_FILE | NEED_WRITE, path, sizeof(path));
4121 fd = open(file, O_RDONLY);
4078 4122
4079 if (fd < 0) 4123 if (fd < 0)
4080 { 4124 {
@@ -4232,6 +4276,8 @@ void tagcache_build(const char *path)
4232{ 4276{
4233 struct tagcache_header header; 4277 struct tagcache_header header;
4234 bool ret; 4278 bool ret;
4279 char buf[MAX_PATH];
4280 const char *file;
4235 4281
4236 curpath[0] = '\0'; 4282 curpath[0] = '\0';
4237 data_size = 0; 4283 data_size = 0;
@@ -4244,19 +4290,21 @@ void tagcache_build(const char *path)
4244#endif 4290#endif
4245 4291
4246 logf("updating tagcache"); 4292 logf("updating tagcache");
4293
4294 file = get_user_file_path(TAGCACHE_FILE_TEMP,
4295 IS_FILE|NEED_WRITE, buf, sizeof(buf));
4247 4296
4248 cachefd = open(TAGCACHE_FILE_TEMP, O_RDONLY); 4297
4249 if (cachefd >= 0) 4298 if (file_exists(file))
4250 { 4299 {
4251 logf("skipping, cache already waiting for commit"); 4300 logf("skipping, cache already waiting for commit");
4252 close(cachefd);
4253 return ; 4301 return ;
4254 } 4302 }
4255 4303
4256 cachefd = open(TAGCACHE_FILE_TEMP, O_RDWR | O_CREAT | O_TRUNC, 0666); 4304 cachefd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0666);
4257 if (cachefd < 0) 4305 if (cachefd < 0)
4258 { 4306 {
4259 logf("master file open failed: %s", TAGCACHE_FILE_TEMP); 4307 logf("master file open failed: %s", file);
4260 return ; 4308 return ;
4261 } 4309 }
4262 4310
@@ -4300,7 +4348,7 @@ void tagcache_build(const char *path)
4300#endif 4348#endif
4301 if (commit()) 4349 if (commit())
4302 { 4350 {
4303 remove(TAGCACHE_FILE_TEMP); 4351 remove(file);
4304 logf("tagcache built!"); 4352 logf("tagcache built!");
4305 } 4353 }
4306#ifdef __PCTOOL__ 4354#ifdef __PCTOOL__
@@ -4345,7 +4393,12 @@ void tagcache_unload_ramcache(void)
4345{ 4393{
4346 tc_stat.ramcache = false; 4394 tc_stat.ramcache = false;
4347 /* Just to make sure there is no statefile present. */ 4395 /* Just to make sure there is no statefile present. */
4348 // remove(TAGCACHE_STATEFILE); 4396
4397#if 0
4398 char path[MAX_PATH];
4399 remove(get_user_file_path(TAGCACHE_STATEFILE, IS_FILE | NEED_WRITE,
4400 path, sizeof(path)));
4401#endif
4349} 4402}
4350#endif 4403#endif
4351 4404
@@ -4354,6 +4407,7 @@ static void tagcache_thread(void)
4354{ 4407{
4355 struct queue_event ev; 4408 struct queue_event ev;
4356 bool check_done = false; 4409 bool check_done = false;
4410 char path[MAX_PATH];
4357 4411
4358 /* If the previous cache build/update was interrupted, commit 4412 /* If the previous cache build/update was interrupted, commit
4359 * the changes first in foreground. */ 4413 * the changes first in foreground. */
@@ -4370,7 +4424,8 @@ static void tagcache_thread(void)
4370 check_done = tagcache_dumpload(); 4424 check_done = tagcache_dumpload();
4371 } 4425 }
4372 4426
4373 remove(TAGCACHE_STATEFILE); 4427 remove(get_user_file_path(TAGCACHE_STATEFILE, IS_FILE | NEED_WRITE,
4428 buf, sizeof(buf)));
4374# endif 4429# endif
4375 4430
4376 /* Allocate space for the tagcache if found on disk. */ 4431 /* Allocate space for the tagcache if found on disk. */
@@ -4403,7 +4458,8 @@ static void tagcache_thread(void)
4403 4458
4404 case Q_REBUILD: 4459 case Q_REBUILD:
4405 remove_files(); 4460 remove_files();
4406 remove(TAGCACHE_FILE_TEMP); 4461 remove(get_user_file_path(TAGCACHE_FILE_TEMP,
4462 IS_FILE|NEED_WRITE, path, sizeof(path)));
4407 tagcache_build("/"); 4463 tagcache_build("/");
4408 break; 4464 break;
4409 4465
diff --git a/apps/tree.c b/apps/tree.c
index d63ddd448c..ed8e4d20bd 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -52,6 +52,7 @@
52#include "talk.h" 52#include "talk.h"
53#include "filetypes.h" 53#include "filetypes.h"
54#include "misc.h" 54#include "misc.h"
55#include "filefuncs.h"
55#include "filetree.h" 56#include "filetree.h"
56#include "tagtree.h" 57#include "tagtree.h"
57#ifdef HAVE_RECORDING 58#ifdef HAVE_RECORDING
@@ -260,7 +261,8 @@ static int tree_voice_cb(int selected_item, void * data)
260 261
261bool check_rockboxdir(void) 262bool check_rockboxdir(void)
262{ 263{
263 if(!dir_exists(ROCKBOX_DIR)) 264 char path[MAX_PATH];
265 if(!dir_exists(get_user_file_path(ROCKBOX_DIR, 0, path, sizeof(path))))
264 { /* No need to localise this message. 266 { /* No need to localise this message.
265 If .rockbox is missing, it wouldn't work anyway */ 267 If .rockbox is missing, it wouldn't work anyway */
266 int i; 268 int i;
diff --git a/firmware/SOURCES b/firmware/SOURCES
index b4f5301a84..d8cfadef11 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -105,6 +105,9 @@ common/dircache.c
105#endif /* HAVE_DIRCACHE */ 105#endif /* HAVE_DIRCACHE */
106common/filefuncs.c 106common/filefuncs.c
107common/format.c 107common/format.c
108#ifdef APPLICATION
109common/rbpaths.c
110#endif
108common/strcasecmp.c 111common/strcasecmp.c
109common/strcasestr.c 112common/strcasestr.c
110common/strnatcmp.c 113common/strnatcmp.c
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 906527f8f2..7b2cdd1d75 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -88,10 +88,13 @@ static int fdbind_idx = 0;
88 */ 88 */
89static int open_dircache_file(unsigned flags, int permissions) 89static int open_dircache_file(unsigned flags, int permissions)
90{ 90{
91 char path[MAX_PATH];
92 const char *file = get_user_file_path(DIRCACHE_FILE, IS_FILE|NEED_WRITE,
93 path, sizeof(path));
91 if (permissions != 0) 94 if (permissions != 0)
92 return open(DIRCACHE_FILE, flags, permissions); 95 return open(file, flags, permissions);
93 96
94 return open(DIRCACHE_FILE, flags); 97 return open(file, flags);
95} 98}
96 99
97/** 100/**
@@ -99,7 +102,9 @@ static int open_dircache_file(unsigned flags, int permissions)
99 */ 102 */
100static int remove_dircache_file(void) 103static int remove_dircache_file(void)
101{ 104{
102 return remove(DIRCACHE_FILE); 105 char path[MAX_PATH];
106 return remove(get_user_file_path(DIRCACHE_FILE, IS_FILE|NEED_WRITE,
107 path, sizeof(path)));
103} 108}
104#endif 109#endif
105/** 110/**
diff --git a/firmware/common/filefuncs.c b/firmware/common/filefuncs.c
index ca9113250a..c058267094 100644
--- a/firmware/common/filefuncs.c
+++ b/firmware/common/filefuncs.c
@@ -22,6 +22,7 @@
22#include "dir.h" 22#include "dir.h"
23#include "stdlib.h" 23#include "stdlib.h"
24#include "string.h" 24#include "string.h"
25#include "debug.h"
25 26
26#ifdef HAVE_MULTIVOLUME 27#ifdef HAVE_MULTIVOLUME
27/* returns on which volume this is, and copies the reduced name 28/* returns on which volume this is, and copies the reduced name
@@ -50,3 +51,39 @@ int strip_volume(const char* name, char* namecopy)
50 return volume; 51 return volume;
51} 52}
52#endif /* #ifdef HAVE_MULTIVOLUME */ 53#endif /* #ifdef HAVE_MULTIVOLUME */
54
55#ifndef __PCTOOL__
56/* Test file existence, using dircache of possible */
57bool file_exists(const char *file)
58{
59 int fd;
60
61#ifdef DEBUG
62 if (!file || strlen(file) <= 0)
63 {
64 DEBUGF("%s(): Invalid parameter!\n");
65 return false;
66 }
67#endif
68
69#ifdef HAVE_DIRCACHE
70 if (dircache_is_enabled())
71 return (dircache_get_entry_ptr(file) != NULL);
72#endif
73
74 fd = open(file, O_RDONLY);
75 if (fd < 0)
76 return false;
77 close(fd);
78 return true;
79}
80
81bool dir_exists(const char *path)
82{
83 DIR* d = opendir(path);
84 if (!d)
85 return false;
86 closedir(d);
87 return true;
88}
89#endif /* __PCTOOL__ */
diff --git a/firmware/common/rbpaths.c b/firmware/common/rbpaths.c
new file mode 100644
index 0000000000..69bc1387ef
--- /dev/null
+++ b/firmware/common/rbpaths.c
@@ -0,0 +1,84 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Thomas Martitz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22
23#include <stdio.h> /* snprintf */
24#include <stdlib.h>
25#include "rbpaths.h"
26#include "file.h" /* MAX_PATH */
27#include "dir.h"
28#include "gcc_extensions.h"
29#include "string-extra.h"
30#include "filefuncs.h"
31
32
33void paths_init(void)
34{
35 /* make sure $HOME/.config/rockbox.org exists, it's needed for config.cfg */
36 char home_path[MAX_PATH];
37 snprintf(home_path, sizeof(home_path), "%s/.config/rockbox.org", getenv("HOME"));
38 mkdir(home_path);
39}
40
41const char* get_user_file_path(const char *path,
42 unsigned flags,
43 char* buf,
44 const size_t bufsize)
45{
46 const char *ret = path;
47 const char *pos = path;
48 printf("%s(): looking for %s\n", __func__, path);
49 /* replace ROCKBOX_DIR in path with $HOME/.config/rockbox.org */
50 pos += ROCKBOX_DIR_LEN;
51 if (*pos == '/') pos += 1;
52
53 if (snprintf(buf, bufsize, "%s/.config/rockbox.org/%s", getenv("HOME"), pos)
54 >= (int)bufsize)
55 return NULL;
56
57 /* always return the replacement buffer (pointing to $HOME) if
58 * write access is needed */
59 if (flags & NEED_WRITE)
60 ret = buf;
61 else
62 {
63 if (flags & IS_FILE)
64 {
65 if (file_exists(buf))
66 ret = buf;
67 }
68 else
69 {
70 if (dir_exists(buf))
71 ret = buf;
72 }
73 }
74
75 /* make a copy if we're about to return the path*/
76 if (UNLIKELY((flags & FORCE_BUFFER_COPY) && (ret != buf)))
77 {
78 strlcpy(buf, ret, bufsize);
79 ret = buf;
80 }
81
82 printf("%s(): %s\n", __func__, ret);
83 return ret;
84}
diff --git a/firmware/common/unicode.c b/firmware/common/unicode.c
index 4ef6eaae2b..25d4a9129e 100644
--- a/firmware/common/unicode.c
+++ b/firmware/common/unicode.c
@@ -27,16 +27,16 @@
27 */ 27 */
28 28
29#include <stdio.h> 29#include <stdio.h>
30#include "config.h"
30#include "file.h" 31#include "file.h"
31#include "debug.h" 32#include "debug.h"
32#include "rbunicode.h" 33#include "rbunicode.h"
33#include "config.h" 34#include "rbpaths.h"
34 35
35#ifndef O_BINARY 36#ifndef O_BINARY
36#define O_BINARY 0 37#define O_BINARY 0
37#endif 38#endif
38 39
39#define CODEPAGE_DIR ROCKBOX_DIR"/codepages"
40static int default_codepage = 0; 40static int default_codepage = 0;
41static int loaded_cp_table = 0; 41static int loaded_cp_table = 0;
42 42
diff --git a/firmware/export/filefuncs.h b/firmware/export/filefuncs.h
index 130c5ff4be..3745c6bee3 100644
--- a/firmware/export/filefuncs.h
+++ b/firmware/export/filefuncs.h
@@ -28,4 +28,9 @@
28int strip_volume(const char* name, char* namecopy); 28int strip_volume(const char* name, char* namecopy);
29#endif 29#endif
30 30
31#ifndef __PCTOOL__
32bool file_exists(const char *file);
33bool dir_exists(const char *path);
34#endif
35
31#endif /* __INCLUDE_FILEFUNCS_H_ */ 36#endif /* __INCLUDE_FILEFUNCS_H_ */
diff --git a/firmware/export/rbpaths.h b/firmware/export/rbpaths.h
new file mode 100644
index 0000000000..cd87888cef
--- /dev/null
+++ b/firmware/export/rbpaths.h
@@ -0,0 +1,132 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Thomas Martitz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __PATHS_H__
23#define __PATHS_H__
24
25#include <stdbool.h>
26#include "autoconf.h"
27#include "string-extra.h"
28
29/* flags for get_user_file_path() */
30/* whether you need write access to that file/dir, especially true
31 * for runtime generated files (config.cfg) */
32#define NEED_WRITE (1<<0)
33/* file or directory? */
34#define IS_FILE (1<<1)
35/* make sure the path is copied into the passed buffer (it may return
36 * the passed path directly otherwise, e.g. always on target builds) */
37#define FORCE_BUFFER_COPY (1<<2)
38
39
40
41/* name of directory where configuration, fonts and other data
42 * files are stored */
43#ifdef __PCTOOL__
44#undef ROCKBOX_DIR
45#undef ROCKBOX_DIR_LEN
46#undef WPS_DIR
47#define ROCKBOX_DIR "."
48#define ROCKBOX_DIR_LEN 1
49#else
50
51/* ROCKBOX_DIR is now defined in autoconf.h for flexible build types */
52#ifndef ROCKBOX_DIR
53#error ROCKBOX_DIR not defined (should be in autoconf.h)
54#endif
55#define ROCKBOX_DIR_LEN (sizeof(ROCKBOX_DIR)-1)
56#endif /* def __PCTOOL__ */
57
58#ifndef APPLICATION
59
60/* make sure both are the same for native builds */
61#undef ROCKBOX_LIBRARY_PATH
62#define ROCKBOX_LIBRARY_PATH ROCKBOX_DIR
63
64#define PLUGIN_DIR ROCKBOX_DIR "/rocks"
65#define CODECS_DIR ROCKBOX_DIR "/codecs"
66
67#define REC_BASE_DIR "/"
68#define PLAYLIST_CATALOG_DEFAULT_DIR "/Playlists"
69
70#ifndef PLUGIN
71static inline __attribute__((always_inline)) const char* get_user_file_path(const char *path,
72 unsigned flags,
73 char* buf,
74 const size_t bufsize)
75{
76 if (flags & FORCE_BUFFER_COPY)
77 {
78 strlcpy(buf, path, bufsize);
79 return buf;
80 }
81 return path;
82}
83#endif
84
85#define paths_init()
86#else /* application */
87
88#define PLUGIN_DIR ROCKBOX_LIBRARY_PATH "/rockbox/rocks"
89#define CODECS_DIR ROCKBOX_LIBRARY_PATH "/rockbox/codecs"
90
91#define REC_BASE_DIR ROCKBOX_DIR "/"
92#define PLAYLIST_CATALOG_DEFAULT_DIR ROCKBOX_DIR "/Playlists"
93
94extern void paths_init(void);
95extern const char* get_user_file_path(const char *path,
96 unsigned flags,
97 char* buf,
98 const size_t bufsize);
99#endif /* APPLICATION */
100
101#define LANG_DIR ROCKBOX_DIR "/langs"
102
103#define PLUGIN_GAMES_DIR PLUGIN_DIR "/games"
104#define PLUGIN_APPS_DIR PLUGIN_DIR "/apps"
105#define PLUGIN_DEMOS_DIR PLUGIN_DIR "/demos"
106#define VIEWERS_DIR PLUGIN_DIR "/viewers"
107
108
109#define WPS_DIR ROCKBOX_DIR "/wps"
110#define SBS_DIR WPS_DIR
111#define THEME_DIR ROCKBOX_DIR "/themes"
112#define FONT_DIR ROCKBOX_DIR "/fonts"
113#define ICON_DIR ROCKBOX_DIR "/icons"
114
115#define BACKDROP_DIR ROCKBOX_DIR "/backdrops"
116#define EQS_DIR ROCKBOX_DIR "/eqs"
117
118/* need to fix this once the application gets record/radio abilities */
119#define RECPRESETS_DIR ROCKBOX_DIR "/recpresets"
120#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
121
122#define DIRCACHE_FILE ROCKBOX_DIR "/dircache.dat"
123#define CODEPAGE_DIR ROCKBOX_DIR "/codepages"
124
125#define VIEWERS_CONFIG ROCKBOX_DIR "/viewers.config"
126#define CONFIGFILE ROCKBOX_DIR "/config.cfg"
127#define FIXEDSETTINGSFILE ROCKBOX_DIR "/fixed.cfg"
128
129#define PLAYLIST_CONTROL_FILE ROCKBOX_DIR "/.playlist_control"
130#define NVRAM_FILE ROCKBOX_DIR "/nvram.bin"
131#define GLYPH_CACHE_FILE ROCKBOX_DIR "/.glyphcache"
132#endif /* __PATHS_H__ */
diff --git a/firmware/font.c b/firmware/font.c
index f1584713ed..b8ad76ec3a 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -36,6 +36,7 @@
36#include "panic.h" 36#include "panic.h"
37#include "rbunicode.h" 37#include "rbunicode.h"
38#include "diacritic.h" 38#include "diacritic.h"
39#include "rbpaths.h"
39 40
40#define MAX_FONTSIZE_FOR_16_BIT_OFFSETS 0xFFDB 41#define MAX_FONTSIZE_FOR_16_BIT_OFFSETS 0xFFDB
41 42
@@ -56,7 +57,6 @@
56#define FONT_HEADER_SIZE 36 57#define FONT_HEADER_SIZE 36
57#endif 58#endif
58 59
59#define GLYPH_CACHE_FILE ROCKBOX_DIR"/.glyphcache"
60 60
61#ifndef BOOTLOADER 61#ifndef BOOTLOADER
62/* Font cache includes */ 62/* Font cache includes */
@@ -606,12 +606,13 @@ void glyph_cache_save(struct font* pf)
606 pf = &font_ui; 606 pf = &font_ui;
607 if (pf->fd >= 0 && pf == &font_ui) 607 if (pf->fd >= 0 && pf == &font_ui)
608 { 608 {
609#ifdef WPSEDITOR 609 char path[MAX_PATH];
610 cache_fd = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666); 610 const char *file = get_user_file_path(GLYPH_CACHE_FILE, IS_FILE|NEED_WRITE,
611#else 611 path, sizeof(path));
612 cache_fd = creat(GLYPH_CACHE_FILE, 0666); 612
613#endif 613 cache_fd = open(file, O_WRONLY|O_CREAT|O_TRUNC, 0666);
614 if (cache_fd < 0) return; 614 if (cache_fd < 0)
615 return;
615 616
616 lru_traverse(&pf->cache._lru, glyph_file_write); 617 lru_traverse(&pf->cache._lru, glyph_file_write);
617 618
@@ -630,9 +631,10 @@ static void glyph_cache_load(struct font* pf)
630 int fd; 631 int fd;
631 unsigned char tmp[2]; 632 unsigned char tmp[2];
632 unsigned short ch; 633 unsigned short ch;
634 char path[MAX_PATH];
633 635
634 fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY); 636 fd = open(get_user_file_path(GLYPH_CACHE_FILE, IS_FILE|NEED_WRITE,
635 637 path, sizeof(path)), O_RDONLY|O_BINARY);
636 if (fd >= 0) { 638 if (fd >= 0) {
637 639
638 while (read(fd, tmp, 2) == 2) { 640 while (read(fd, tmp, 2) == 2) {
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h
index 4472d5fbe0..650b92632d 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -27,7 +27,6 @@
27 27
28#define DIRCACHE_RESERVE (1024*64) 28#define DIRCACHE_RESERVE (1024*64)
29#define DIRCACHE_LIMIT (1024*1024*6) 29#define DIRCACHE_LIMIT (1024*1024*6)
30#define DIRCACHE_FILE ROCKBOX_DIR"/dircache.dat"
31 30
32#define DIRCACHE_APPFLAG_TAGCACHE 0x0001 31#define DIRCACHE_APPFLAG_TAGCACHE 0x0001
33 32
diff --git a/firmware/include/file.h b/firmware/include/file.h
index 91b701d6d2..a9d1d05a11 100644
--- a/firmware/include/file.h
+++ b/firmware/include/file.h
@@ -22,13 +22,12 @@
22#ifndef _FILE_H_ 22#ifndef _FILE_H_
23#define _FILE_H_ 23#define _FILE_H_
24 24
25#undef MAX_PATH /* this avoids problems when building simulator */
26#define MAX_PATH 260
27
28#include <sys/types.h> 25#include <sys/types.h>
29#include "config.h" 26#include "config.h"
30#include "gcc_extensions.h" 27#include "gcc_extensions.h"
31 28
29#undef MAX_PATH /* this avoids problems when building simulator */
30#define MAX_PATH 260
32#define MAX_OPEN_FILES 11 31#define MAX_OPEN_FILES 11
33 32
34#ifndef SEEK_SET 33#ifndef SEEK_SET
diff --git a/tools/buildzip.pl b/tools/buildzip.pl
index 0358459c9c..7a127dea20 100755
--- a/tools/buildzip.pl
+++ b/tools/buildzip.pl
@@ -30,7 +30,6 @@ my $target_id; # passed in, not currently used
30my $rbdir=".rockbox"; # can be changed for special builds 30my $rbdir=".rockbox"; # can be changed for special builds
31my $app; 31my $app;
32 32
33
34sub glob_mkdir { 33sub glob_mkdir {
35 my ($dir) = @_; 34 my ($dir) = @_;
36 mkpath ($dir, $verbose, 0777); 35 mkpath ($dir, $verbose, 0777);
@@ -550,7 +549,7 @@ STOP
550 if(-d "$ROOT/wps") { 549 if(-d "$ROOT/wps") {
551 my $wps_build_cmd="perl $ROOT/wps/wpsbuild.pl "; 550 my $wps_build_cmd="perl $ROOT/wps/wpsbuild.pl ";
552 $wps_build_cmd=$wps_build_cmd."-v " if $verbose; 551 $wps_build_cmd=$wps_build_cmd."-v " if $verbose;
553 $wps_build_cmd=$wps_build_cmd." --rbdir=$rbdir -r $ROOT -m $modelname $ROOT/wps/WPSLIST $target"; 552 $wps_build_cmd=$wps_build_cmd." --tempdir=$temp_dir --rbdir=$rbdir -r $ROOT -m $modelname $ROOT/wps/WPSLIST $target";
554 print "wpsbuild: $wps_build_cmd\n" if $verbose; 553 print "wpsbuild: $wps_build_cmd\n" if $verbose;
555 system("$wps_build_cmd"); 554 system("$wps_build_cmd");
556 print "wps_build_cmd: done\n" if $verbose; 555 print "wps_build_cmd: done\n" if $verbose;
@@ -607,6 +606,10 @@ sub runone {
607 606
608 # in the app the the layout is different (no .rockbox, but bin/lib/share) 607 # in the app the the layout is different (no .rockbox, but bin/lib/share)
609 $app = ($modelname eq "application"); 608 $app = ($modelname eq "application");
609 unless ($app) {
610 #rbdir starts with '/', strip it
611 $rbdir = substr($rbdir, 1);
612 }
610 613
611 # build a full install .rockbox ($rbdir) directory 614 # build a full install .rockbox ($rbdir) directory
612 buildzip($target, $fonts); 615 buildzip($target, $fonts);
diff --git a/tools/configure b/tools/configure
index 0896e5b699..ce23c2a965 100755
--- a/tools/configure
+++ b/tools/configure
@@ -19,7 +19,12 @@ use_bootchart="#undef DO_BOOTCHART"
19 19
20scriptver=`echo '$Revision$' | sed -e 's:\\$::g' -e 's/Revision: //'` 20scriptver=`echo '$Revision$' | sed -e 's:\\$::g' -e 's/Revision: //'`
21 21
22rbdir=".rockbox" 22rbdir="/.rockbox"
23need_full_path=
24bindir=
25libdir=
26bindir_full=
27libdir_full=
23 28
24# 29#
25# Begin Function Definitions 30# Begin Function Definitions
@@ -2603,7 +2608,27 @@ fi
2603 target_id=100 2608 target_id=100
2604 modelname="application" 2609 modelname="application"
2605 target="-DAPPLICATION" 2610 target="-DAPPLICATION"
2606 memory=32 2611
2612 if [ -z "$PREFIX" ]; then
2613 rbdir="/usr/local/share/rockbox"
2614 bindir="/usr/local/bin"
2615 bindir_full=$bindir
2616 libdir="/usr/local/lib"
2617 libdir_full=$libdir
2618 else
2619 rbdir=`realpath $PREFIX/share/rockbox`
2620 bindir="$PREFIX/bin"
2621 libdir="$PREFIX/lib"
2622 if [ -d bindir ]; then
2623 bindir_full=`realpath $bindir`
2624 fi
2625 if [ -d libdir ]; then
2626 libdir_full=`realpath $libdir`
2627 fi
2628 fi
2629 need_full_path="yes"
2630
2631 memory=8
2607 uname=`uname` 2632 uname=`uname`
2608 simcc "sdl-app" 2633 simcc "sdl-app"
2609 tool="cp " 2634 tool="cp "
@@ -2999,7 +3024,15 @@ else
2999fi 3024fi
3000 3025
3001if [ "$ARG_RBDIR" ]; then 3026if [ "$ARG_RBDIR" ]; then
3002 rbdir=$ARG_RBDIR 3027 if [ "$need_full_path" = "yes" ]; then
3028 rbdir=`realpath $ARG_RBDIR`
3029 else # prepend '/' if needed
3030 if [ -z `echo $ARG_RBDIR | grep -P '/.*'` ]; then
3031 rbdir="/"$ARG_RBDIR
3032 else
3033 rbdir=$ARG_RBDIR
3034 fi
3035 fi
3003 echo "Using alternate rockbox dir: ${rbdir}" 3036 echo "Using alternate rockbox dir: ${rbdir}"
3004fi 3037fi
3005 3038
@@ -3010,6 +3043,8 @@ sed > autoconf.h \
3010 -e "s<@config_rtc@<$config_rtc<g" \ 3043 -e "s<@config_rtc@<$config_rtc<g" \
3011 -e "s<@have_rtc_alarm@<$have_rtc_alarm<g" \ 3044 -e "s<@have_rtc_alarm@<$have_rtc_alarm<g" \
3012 -e "s<@RBDIR@<${rbdir}<g" \ 3045 -e "s<@RBDIR@<${rbdir}<g" \
3046 -e "s<@binpath@<${bindir_full}<g" \
3047 -e "s<@libpath@<${libdir_full}<g" \
3013 -e "s<@have_backlight@<$have_backlight<g" \ 3048 -e "s<@have_backlight@<$have_backlight<g" \
3014 -e "s<@have_fmradio_in@<$have_fmradio_in<g" \ 3049 -e "s<@have_fmradio_in@<$have_fmradio_in<g" \
3015 -e "s<@have_ata_poweroff@<$have_ata_poweroff<g" \ 3050 -e "s<@have_ata_poweroff@<$have_ata_poweroff<g" \
@@ -3041,7 +3076,9 @@ sed > autoconf.h \
3041@have_rtc_alarm@ 3076@have_rtc_alarm@
3042 3077
3043/* root of Rockbox */ 3078/* root of Rockbox */
3044#define ROCKBOX_DIR "/@RBDIR@" 3079#define ROCKBOX_DIR "@RBDIR@"
3080#define ROCKBOX_BINARY_PATH "@binpath@"
3081#define ROCKBOX_LIBRARY_PATH "@libpath@"
3045 3082
3046#endif /* __BUILD_AUTOCONF_H */ 3083#endif /* __BUILD_AUTOCONF_H */
3047EOF 3084EOF
@@ -3154,6 +3191,8 @@ sed > Makefile \
3154 -e "s<@LANGS@<${buildlangs}<g" \ 3191 -e "s<@LANGS@<${buildlangs}<g" \
3155 -e "s<@USE_ELF@<${USE_ELF}<g" \ 3192 -e "s<@USE_ELF@<${USE_ELF}<g" \
3156 -e "s<@RBDIR@<${rbdir}<g" \ 3193 -e "s<@RBDIR@<${rbdir}<g" \
3194 -e "s<@binpath@<${bindir}<g" \
3195 -e "s<@libpath@<${libdir}<g" \
3157 -e "s<@PREFIX@<$PREFIX<g" \ 3196 -e "s<@PREFIX@<$PREFIX<g" \
3158 -e "s<@CMDLINE@<$cmdline<g" \ 3197 -e "s<@CMDLINE@<$cmdline<g" \
3159 -e "s<@SDLCONFIG@<$sdl<g" \ 3198 -e "s<@SDLCONFIG@<$sdl<g" \
@@ -3221,6 +3260,8 @@ export ENC_OPTS=@ENC_OPTS@
3221export ENCODER=@ENCODER@ 3260export ENCODER=@ENCODER@
3222export USE_ELF=@USE_ELF@ 3261export USE_ELF=@USE_ELF@
3223export RBDIR=@RBDIR@ 3262export RBDIR=@RBDIR@
3263export ROCKBOX_BINARY_PATH=@binpath@
3264export ROCKBOX_LIBRARY_PATH=@libpath@
3224export SDLCONFIG=@SDLCONFIG@ 3265export SDLCONFIG=@SDLCONFIG@
3225 3266
3226CONFIGURE_OPTIONS=@CMDLINE@ 3267CONFIGURE_OPTIONS=@CMDLINE@
diff --git a/tools/root.make b/tools/root.make
index d90b40f0c6..145b1ade72 100644
--- a/tools/root.make
+++ b/tools/root.make
@@ -24,16 +24,22 @@ TOOLS = $(TOOLSDIR)/rdf2binary $(TOOLSDIR)/convbdf \
24 24
25 25
26ifeq (,$(PREFIX)) 26ifeq (,$(PREFIX))
27ifeq ($(APP_TYPE),sdl-sim) 27ifdef APP_TYPE
28# for sims, set simdisk/ as default 28# for sims, set simdisk/ as default
29PREFIX = simdisk 29ifeq ($(APP_TYPE),sdl-sim)
30INSTALL = --install="$(PREFIX)" 30RBPREFIX = simdisk
31else ifeq ($(APP_TYPE),sdl-app)
32RBPREFIX = /usr/local
33endif
34
35INSTALL = --install="$(RBPREFIX)"
31else 36else
32# /dev/null as magic to tell it wasn't set, error out later in buildzip.pl 37# /dev/null as magic to tell it wasn't set, error out later in buildzip.pl
33INSTALL = --install=/dev/null 38INSTALL = --install=/dev/null
34endif 39endif
35else 40else
36INSTALL = --install="$(PREFIX)" 41RBPREFIX = $(PREFIX)
42INSTALL = --install="$(RBPREFIX)"
37endif 43endif
38 44
39RBINFO = $(BUILDDIR)/rockbox-info.txt 45RBINFO = $(BUILDDIR)/rockbox-info.txt
@@ -280,8 +286,8 @@ voice: voicetools $(BUILDDIR)/apps/features
280endif 286endif
281 287
282bininstall: $(BUILDDIR)/$(BINARY) 288bininstall: $(BUILDDIR)/$(BINARY)
283 @echo "Installing your rockbox binary in your '$(PREFIX)' dir" 289 @echo "Installing your rockbox binary in your '$(RBPREFIX)' dir"
284 $(SILENT)cp $(BINARY) "$(PREFIX)/.rockbox/" 290 $(SILENT)cp $(BINARY) "$(RBPREFIX)/.rockbox/"
285 291
286install: 292install:
287 @echo "Installing your build in your '$(PREFIX)' dir" 293 @echo "Installing your build in your '$(PREFIX)' dir"
@@ -351,4 +357,4 @@ ifneq (reconf,$(MAKECMDGOALS))
351endif 357endif
352 358
353reconf: 359reconf:
354 $(SILENT$)PREFIX=$(PREFIX) $(TOOLSDIR)/configure $(CONFIGURE_OPTIONS) 360 $(SILENT$)$(TOOLSDIR)/configure $(CONFIGURE_OPTIONS)
diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c
index bdcc7e6ca1..260e880b62 100644
--- a/uisimulator/common/io.c
+++ b/uisimulator/common/io.c
@@ -40,9 +40,6 @@
40#include "dir-win32.h" 40#include "dir-win32.h"
41#endif 41#endif
42 42
43#define MAX_PATH 260
44#define MAX_OPEN_FILES 11
45
46#include <fcntl.h> 43#include <fcntl.h>
47#include <SDL.h> 44#include <SDL.h>
48#include <SDL_thread.h> 45#include <SDL_thread.h>
@@ -52,7 +49,12 @@
52#include "config.h" 49#include "config.h"
53#include "ata.h" /* for IF_MV2 et al. */ 50#include "ata.h" /* for IF_MV2 et al. */
54#include "thread-sdl.h" 51#include "thread-sdl.h"
52#include "rbpaths.h"
55 53
54/* keep this in sync with file.h! */
55#undef MAX_PATH /* this avoids problems when building simulator */
56#define MAX_PATH 260
57#define MAX_OPEN_FILES 11
56 58
57/* Windows (and potentially other OSes) distinguish binary and text files. 59/* Windows (and potentially other OSes) distinguish binary and text files.
58 * Define a dummy for the others. */ 60 * Define a dummy for the others. */
@@ -255,7 +257,7 @@ static ssize_t io_trigger_and_wait(int cmd)
255 return result; 257 return result;
256} 258}
257 259
258#ifndef __PCTOOL__ 260#if !defined(__PCTOOL__) && !defined(APPLICATION)
259static const char *get_sim_pathname(const char *name) 261static const char *get_sim_pathname(const char *name)
260{ 262{
261 static char buffer[MAX_PATH]; /* sufficiently big */ 263 static char buffer[MAX_PATH]; /* sufficiently big */
@@ -520,7 +522,6 @@ int sim_fsync(int fd)
520void *sim_codec_load_ram(char* codecptr, int size, void **pd) 522void *sim_codec_load_ram(char* codecptr, int size, void **pd)
521{ 523{
522 void *hdr; 524 void *hdr;
523 char name[MAX_PATH];
524 char path[MAX_PATH]; 525 char path[MAX_PATH];
525 int fd; 526 int fd;
526 int codec_count; 527 int codec_count;
@@ -536,8 +537,9 @@ void *sim_codec_load_ram(char* codecptr, int size, void **pd)
536 to find an unused filename */ 537 to find an unused filename */
537 for (codec_count = 0; codec_count < 10; codec_count++) 538 for (codec_count = 0; codec_count < 10; codec_count++)
538 { 539 {
539 snprintf(name, sizeof(name), "/_temp_codec%d.dll", codec_count); 540 char name[MAX_PATH];
540 snprintf(path, sizeof(path), "%s", get_sim_pathname(name)); 541 const char *_name = get_user_file_path(ROCKBOX_DIR, 0, name, sizeof(name));
542 snprintf(path, sizeof(path), "%s/_temp_codec%d.dll", get_sim_pathname(_name), codec_count);
541 fd = OPEN(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU); 543 fd = OPEN(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU);
542 if (fd >= 0) 544 if (fd >= 0)
543 break; /* Created a file ok */ 545 break; /* Created a file ok */
diff --git a/wps/WPSLIST b/wps/WPSLIST
index 13cb263865..3068f48513 100644
--- a/wps/WPSLIST
+++ b/wps/WPSLIST
@@ -346,30 +346,30 @@ selector type.160x128x2: bar (inverse)
346selector type.138x110x2: bar (inverse) 346selector type.138x110x2: bar (inverse)
347 347
348#icons 348#icons
349iconset.320x240x16: /.rockbox/icons/tango_small.bmp 349iconset.320x240x16: icons/tango_small.bmp
350iconset.128x128x16: /.rockbox/icons/tango_small.bmp 350iconset.128x128x16: icons/tango_small.bmp
351iconset.132x80x16: /.rockbox/icons/tango_small.bmp 351iconset.132x80x16: icons/tango_small.bmp
352iconset.138x110x2: /.rockbox/icons/tango_small_mono.bmp 352iconset.138x110x2: icons/tango_small_mono.bmp
353iconset.160x128x16: /.rockbox/icons/tango_small.bmp 353iconset.160x128x16: icons/tango_small.bmp
354iconset.160x128x2: /.rockbox/icons/tango_small_mono.bmp 354iconset.160x128x2: icons/tango_small_mono.bmp
355iconset.176x132x16: /.rockbox/icons/tango_small.bmp 355iconset.176x132x16: icons/tango_small.bmp
356iconset.176x220x16: /.rockbox/icons/tango_small.bmp 356iconset.176x220x16: icons/tango_small.bmp
357iconset.220x176x16: /.rockbox/icons/tango_small.bmp 357iconset.220x176x16: icons/tango_small.bmp
358iconset.240x320x16: /.rockbox/icons/tango_small.bmp 358iconset.240x320x16: icons/tango_small.bmp
359iconset.240x400x16: /.rockbox/icons/tango_small.bmp 359iconset.240x400x16: icons/tango_small.bmp
360 360
361#viewer icons 361#viewer icons
362viewers iconset.320x240x16: /.rockbox/icons/tango_small_viewers.bmp 362viewers iconset.320x240x16: icons/tango_small_viewers.bmp
363viewers iconset.128x128x16: /.rockbox/icons/tango_small_viewers.bmp 363viewers iconset.128x128x16: icons/tango_small_viewers.bmp
364viewers iconset.132x80x16: /.rockbox/icons/tango_small_viewers.bmp 364viewers iconset.132x80x16: icons/tango_small_viewers.bmp
365viewers iconset.138x110x2: /.rockbox/icons/tango_small_viewers_mono.bmp 365viewers iconset.138x110x2: icons/tango_small_viewers_mono.bmp
366viewers iconset.160x128x16: /.rockbox/icons/tango_small_viewers.bmp 366viewers iconset.160x128x16: icons/tango_small_viewers.bmp
367viewers iconset.160x128x2: /.rockbox/icons/tango_small_viewers_mono.bmp 367viewers iconset.160x128x2: icons/tango_small_viewers_mono.bmp
368viewers iconset.176x132x16: /.rockbox/icons/tango_small_viewers.bmp 368viewers iconset.176x132x16: icons/tango_small_viewers.bmp
369viewers iconset.176x220x16: /.rockbox/icons/tango_small_viewers.bmp 369viewers iconset.176x220x16: icons/tango_small_viewers.bmp
370viewers iconset.220x176x16: /.rockbox/icons/tango_small_viewers.bmp 370viewers iconset.220x176x16: icons/tango_small_viewers.bmp
371viewers iconset.240x320x16: /.rockbox/icons/tango_small_viewers.bmp 371viewers iconset.240x320x16: icons/tango_small_viewers.bmp
372viewers iconset.240x400x16: /.rockbox/icons/tango_small_viewers.bmp 372viewers iconset.240x400x16: icons/tango_small_viewers.bmp
373 373
374# Whether the WPS is designed to have the statusbar on or off 374# Whether the WPS is designed to have the statusbar on or off
375Statusbar: top 375Statusbar: top
diff --git a/wps/wpsbuild.pl b/wps/wpsbuild.pl
index f07ad6dc01..7e54f109cb 100755
--- a/wps/wpsbuild.pl
+++ b/wps/wpsbuild.pl
@@ -14,6 +14,7 @@ use Getopt::Long qw(:config pass_through); # pass_through so not confused by -DT
14my $ROOT=".."; 14my $ROOT="..";
15my $verbose; 15my $verbose;
16my $rbdir=".rockbox"; 16my $rbdir=".rockbox";
17my $tempdir=".rockbox";
17my $wpslist; 18my $wpslist;
18my $target; 19my $target;
19my $modelname; 20my $modelname;
@@ -23,6 +24,7 @@ GetOptions ( 'r|root=s' => \$ROOT,
23 'm|modelname=s' => \$modelname, 24 'm|modelname=s' => \$modelname,
24 'v|verbose' => \$verbose, 25 'v|verbose' => \$verbose,
25 'rbdir=s' => \$rbdir, # If we want to put in a different directory 26 'rbdir=s' => \$rbdir, # If we want to put in a different directory
27 'tempdir=s' => \$tempdir, # override .rockbox temporary dir
26 ); 28 );
27 29
28($wpslist, $target) = @ARGV; 30($wpslist, $target) = @ARGV;
@@ -72,7 +74,7 @@ my $has_remote;
72if(!$wpslist) { 74if(!$wpslist) {
73 print "Usage: wpsbuilds.pl <WPSLIST> <target>\n", 75 print "Usage: wpsbuilds.pl <WPSLIST> <target>\n",
74 "Run this script in the root of the target build, and it will put all the\n", 76 "Run this script in the root of the target build, and it will put all the\n",
75 "stuff in $rbdir/wps/\n"; 77 "stuff in $tempdir/wps/\n and build the cfg according to $rbdir";
76 exit; 78 exit;
77} 79}
78 80
@@ -135,15 +137,15 @@ sub mkdirs
135{ 137{
136 my $wpsdir = $wps; 138 my $wpsdir = $wps;
137 $wpsdir =~ s/\.(r|)wps//; 139 $wpsdir =~ s/\.(r|)wps//;
138 mkdir "$rbdir/wps", 0777; 140 mkdir "$tempdir/wps", 0777;
139 mkdir "$rbdir/themes", 0777; 141 mkdir "$tempdir/themes", 0777;
140 142
141 if( -d "$rbdir/wps/$wpsdir") { 143 if( -d "$tempdir/wps/$wpsdir") {
142 #print STDERR "wpsbuild warning: directory wps/$wpsdir already exists!\n"; 144 #print STDERR "wpsbuild warning: directory wps/$wpsdir already exists!\n";
143 } 145 }
144 else 146 else
145 { 147 {
146 mkdir "$rbdir/wps/$wpsdir", 0777; 148 mkdir "$tempdir/wps/$wpsdir", 0777;
147 } 149 }
148} 150}
149 151
@@ -153,7 +155,7 @@ sub copybackdrop
153 if ($backdrop ne '') { 155 if ($backdrop ne '') {
154 my $dst = $backdrop; 156 my $dst = $backdrop;
155 $dst =~ s/(\.[0-9]*x[0-9]*x[0-9]*)//; 157 $dst =~ s/(\.[0-9]*x[0-9]*x[0-9]*)//;
156 my $cmd = "cp $ROOT/$backdrop $rbdir/$dst"; 158 my $cmd = "cp $ROOT/$backdrop $tempdir/$dst";
157 `$cmd`; 159 `$cmd`;
158 } 160 }
159} 161}
@@ -164,19 +166,19 @@ sub copythemefont
164 my $o = $_[0]; 166 my $o = $_[0];
165 167
166 $o =~ s/\.fnt/\.bdf/; 168 $o =~ s/\.fnt/\.bdf/;
167 mkdir "$rbdir/fonts"; 169 mkdir "$tempdir/fonts";
168 my $cmd ="$ROOT/tools/convbdf -f -o \"$rbdir/fonts/$_[0]\" \"$ROOT/fonts/$o\" "; 170 my $cmd ="$ROOT/tools/convbdf -f -o \"$tempdir/fonts/$_[0]\" \"$ROOT/fonts/$o\" ";
169 `$cmd`; 171 `$cmd`;
170} 172}
171 173
172sub copythemeicon 174sub copythemeicon
173{ 175{
174 #copy the icon specified by the theme 176 #copy the icon specified by the theme
175
176 if ($iconset ne '') { 177 if ($iconset ne '') {
177 $iconset =~ s/.rockbox/$rbdir/; 178 my $tempicon = $tempdir . "/" . $iconset;
178 $iconset =~ /\/(.*icons\/(.*))/i; 179 $iconset = $rbdir . "/" . $iconset;
179 `cp $ROOT/icons/$2 $1`; 180 $tempicon =~ /\/.*icons\/(.*)/i;
181 `cp $ROOT/icons/$1 $tempicon`;
180 } 182 }
181} 183}
182 184
@@ -185,9 +187,10 @@ sub copythemeviewericon
185 #copy the viewer icon specified by the theme 187 #copy the viewer icon specified by the theme
186 188
187 if ($viewericon ne '') { 189 if ($viewericon ne '') {
188 $viewericon =~ s/.rockbox/$rbdir/; 190 my $tempviewericon = $tempdir . "/" . $viewericon;
189 $viewericon =~ /\/(.*icons\/(.*))/i; 191 $viewericon = $rbdir . "/" . $viewericon;
190 `cp $ROOT/icons/$2 $1`; 192 $tempviewericon =~ /\/.*icons\/(.*)/i;
193 `cp $ROOT/icons/$1 $tempviewericon`;
191 } 194 }
192} 195}
193 196
@@ -209,20 +212,20 @@ sub copywps
209# system("cp $dir/$wps .rockbox/wps/"); 212# system("cp $dir/$wps .rockbox/wps/");
210 # check for <name>.WIDTHxHEIGHTxDEPTH.sbs 213 # check for <name>.WIDTHxHEIGHTxDEPTH.sbs
211 if (-e "$dir/$__sb") { 214 if (-e "$dir/$__sb") {
212 system("cp $dir/$__sb $rbdir/wps/$sbs"); 215 system("cp $dir/$__sb $tempdir/wps/$sbs");
213 } 216 }
214 # check for <name>.WIDTHxHEIGHTxDEPTH.<model>.sbs and overwrite the 217 # check for <name>.WIDTHxHEIGHTxDEPTH.<model>.sbs and overwrite the
215 # previous sb if needed 218 # previous sb if needed
216 $__sb = $sbs_prefix . "." . $req_size . "." . $modelname . ".sbs"; 219 $__sb = $sbs_prefix . "." . $req_size . "." . $modelname . ".sbs";
217 if (-e "$dir/$__sb") { 220 if (-e "$dir/$__sb") {
218 system("cp $dir/$__sb $rbdir/wps/$sbs"); 221 system("cp $dir/$__sb $tempdir/wps/$sbs");
219 } 222 }
220 223
221 if (-e "$dir/$req_t_wps" ) { 224 if (-e "$dir/$req_t_wps" ) {
222 system("cp $dir/$req_t_wps $rbdir/wps/$wps"); 225 system("cp $dir/$req_t_wps $tempdir/wps/$wps");
223 226
224 } elsif (-e "$dir/$req_g_wps") { 227 } elsif (-e "$dir/$req_g_wps") {
225 system("cp $dir/$req_g_wps $rbdir/wps/$wps"); 228 system("cp $dir/$req_g_wps $tempdir/wps/$wps");
226 229
227 open(WPSFILE, "$dir/$req_g_wps"); 230 open(WPSFILE, "$dir/$req_g_wps");
228 while (<WPSFILE>) { 231 while (<WPSFILE>) {
@@ -233,12 +236,12 @@ sub copywps
233 if ($#filelist >= 0) { 236 if ($#filelist >= 0) {
234 if (-e "$dir/$wps_prefix/$req_size") { 237 if (-e "$dir/$wps_prefix/$req_size") {
235 foreach $file (@filelist) { 238 foreach $file (@filelist) {
236 system("cp $dir/$wps_prefix/$req_size/$file $rbdir/wps/$wps_prefix/"); 239 system("cp $dir/$wps_prefix/$req_size/$file $tempdir/wps/$wps_prefix/");
237 } 240 }
238 } 241 }
239 elsif (-e "$dir/$wps_prefix") { 242 elsif (-e "$dir/$wps_prefix") {
240 foreach $file (@filelist) { 243 foreach $file (@filelist) {
241 system("cp $dir/$wps_prefix/$file $rbdir/wps/$wps_prefix/"); 244 system("cp $dir/$wps_prefix/$file $tempdir/wps/$wps_prefix/");
242 } 245 }
243 } 246 }
244 else { 247 else {
@@ -265,35 +268,35 @@ sub buildcfg {
265\# $cfg generated by wpsbuild.pl 268\# $cfg generated by wpsbuild.pl
266\# $wps is made by $author 269\# $wps is made by $author
267\# 270\#
268wps: /$rbdir/wps/$wps 271wps: $rbdir/wps/$wps
269MOO 272MOO
270; 273;
271 if(defined($sbs)) { 274 if(defined($sbs)) {
272 if ($sbs eq '') { 275 if ($sbs eq '') {
273 push @out, "sbs: -\n"; 276 push @out, "sbs: -\n";
274 } else { 277 } else {
275 push @out, "sbs: /$rbdir/wps/$sbs\n"; 278 push @out, "sbs: $rbdir/wps/$sbs\n";
276 } 279 }
277 } 280 }
278 if(defined($rsbs) && $has_remote) { 281 if(defined($rsbs) && $has_remote) {
279 if ($rsbs eq '') { 282 if ($rsbs eq '') {
280 push @out, "rsbs: -\n"; 283 push @out, "rsbs: -\n";
281 } else { 284 } else {
282 push @out, "rsbs: /$rbdir/wps/$rsbs\n"; 285 push @out, "rsbs: $rbdir/wps/$rsbs\n";
283 } 286 }
284 } 287 }
285 if($font) { 288 if($font) {
286 if ($font eq '') { 289 if ($font eq '') {
287 push @out, "font: -\n"; 290 push @out, "font: -\n";
288 } else { 291 } else {
289 push @out, "font: /$rbdir/fonts/$font\n"; 292 push @out, "font: $rbdir/fonts/$font\n";
290 } 293 }
291 } 294 }
292 if(defined($remotefont) && $has_remote) { 295 if(defined($remotefont) && $has_remote) {
293 if ($remotefont eq '') { 296 if ($remotefont eq '') {
294 push @out, "remote font: -\n"; 297 push @out, "remote font: -\n";
295 } else { 298 } else {
296 push @out, "remote font: /$rbdir/fonts/$remotefont\n"; 299 push @out, "remote font: $rbdir/fonts/$remotefont\n";
297 } 300 }
298 } 301 }
299 if($fgcolor && $main_depth > 2) { 302 if($fgcolor && $main_depth > 2) {
@@ -314,7 +317,7 @@ MOO
314 } else { 317 } else {
315 # clip resolution from filename 318 # clip resolution from filename
316 $backdrop =~ s/(\.[0-9]*x[0-9]*x[0-9]*)//; 319 $backdrop =~ s/(\.[0-9]*x[0-9]*x[0-9]*)//;
317 push @out, "backdrop: /$rbdir/$backdrop\n"; 320 push @out, "backdrop: $rbdir/$backdrop\n";
318 } 321 }
319 } 322 }
320 if($lineselectstart && $main_depth > 2) { 323 if($lineselectstart && $main_depth > 2) {
@@ -354,7 +357,7 @@ MOO
354 if ($rwps eq '') { 357 if ($rwps eq '') {
355 push @out, "rwps: -\n"; 358 push @out, "rwps: -\n";
356 } else { 359 } else {
357 push @out, "rwps: /$rbdir/wps/$rwps\n"; 360 push @out, "rwps: $rbdir/wps/$rwps\n";
358 } 361 }
359 } 362 }
360 if(defined($listviewport)) { 363 if(defined($listviewport)) {
@@ -371,11 +374,11 @@ MOO
371 push @out, "remote ui viewport: $listviewport\n"; 374 push @out, "remote ui viewport: $listviewport\n";
372 } 375 }
373 } 376 }
374 if(-f "$rbdir/wps/$cfg") { 377 if(-f "$tempdir/wps/$cfg") {
375 print STDERR "wpsbuild warning: wps/$cfg already exists!\n"; 378 print STDERR "wpsbuild warning: wps/$cfg already exists!\n";
376 } 379 }
377 else { 380 else {
378 open(CFG, ">$rbdir/themes/$cfg"); 381 open(CFG, ">$tempdir/themes/$cfg");
379 print CFG @out; 382 print CFG @out;
380 close(CFG); 383 close(CFG);
381 } 384 }
@@ -401,6 +404,12 @@ while(<WPS>) {
401 # skip comment 404 # skip comment
402 next; 405 next;
403 } 406 }
407
408 # prefix $rbdir with / if needed (needed for the theme.cfg)
409 unless ($rbdir =~ /\/.*/) {
410 $rbdir = "/" . $rbdir;
411 }
412
404 if($l =~ /^ *<(r|)wps>/i) { 413 if($l =~ /^ *<(r|)wps>/i) {
405 $isrwps = $1; 414 $isrwps = $1;
406 $within = 1; 415 $within = 1;