summaryrefslogtreecommitdiff
path: root/apps/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/tree.c')
-rw-r--r--apps/tree.c78
1 files changed, 56 insertions, 22 deletions
diff --git a/apps/tree.c b/apps/tree.c
index 211ddb2f9b..c7484ff420 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -104,12 +104,18 @@ static int ft_play_dirname(char* name);
104static void ft_play_filename(char *dir, char *file); 104static void ft_play_filename(char *dir, char *file);
105static void say_filetype(int attr); 105static void say_filetype(int attr);
106 106
107static struct entry* get_entry_at(struct tree_context *t, int index) 107struct entry* tree_get_entries(struct tree_context *t)
108{ 108{
109 struct entry* entries = t->cache.entries; 109 return core_get_data(t->cache.entries_handle);
110}
111
112struct entry* tree_get_entry_at(struct tree_context *t, int index)
113{
114 struct entry* entries = tree_get_entries(t);
110 return &entries[index]; 115 return &entries[index];
111} 116}
112 117
118
113static const char* tree_get_filename(int selected_item, void *data, 119static const char* tree_get_filename(int selected_item, void *data,
114 char *buffer, size_t buffer_len) 120 char *buffer, size_t buffer_len)
115{ 121{
@@ -122,12 +128,12 @@ static const char* tree_get_filename(int selected_item, void *data,
122 128
123 if (id3db) 129 if (id3db)
124 { 130 {
125 return tagtree_get_entry(&tc, selected_item)->name; 131 return tagtree_get_entry_name(&tc, selected_item, buffer, buffer_len);
126 } 132 }
127 else 133 else
128#endif 134#endif
129 { 135 {
130 struct entry* e = get_entry_at(local_tc, selected_item); 136 struct entry* e = tree_get_entry_at(local_tc, selected_item);
131 name = e->name; 137 name = e->name;
132 attr = e->attr; 138 attr = e->attr;
133 } 139 }
@@ -169,7 +175,7 @@ static int tree_get_filecolor(int selected_item, void * data)
169 if (*tc.dirfilter == SHOW_ID3DB) 175 if (*tc.dirfilter == SHOW_ID3DB)
170 return -1; 176 return -1;
171 struct tree_context * local_tc=(struct tree_context *)data; 177 struct tree_context * local_tc=(struct tree_context *)data;
172 struct entry* e = get_entry_at(local_tc, selected_item); 178 struct entry* e = tree_get_entry_at(local_tc, selected_item);
173 return filetype_get_color(e->name, e->attr); 179 return filetype_get_color(e->name, e->attr);
174} 180}
175#endif 181#endif
@@ -185,7 +191,7 @@ static enum themable_icons tree_get_fileicon(int selected_item, void * data)
185 else 191 else
186#endif 192#endif
187 { 193 {
188 struct entry* e = get_entry_at(local_tc, selected_item); 194 struct entry* e = tree_get_entry_at(local_tc, selected_item);
189 return filetype_get_icon(e->attr); 195 return filetype_get_icon(e->attr);
190 } 196 }
191} 197}
@@ -197,16 +203,17 @@ static int tree_voice_cb(int selected_item, void * data)
197 int attr=0; 203 int attr=0;
198#ifdef HAVE_TAGCACHE 204#ifdef HAVE_TAGCACHE
199 bool id3db = *(local_tc->dirfilter) == SHOW_ID3DB; 205 bool id3db = *(local_tc->dirfilter) == SHOW_ID3DB;
206 char buf[AVERAGE_FILENAME_LENGTH*2];
200 207
201 if (id3db) 208 if (id3db)
202 { 209 {
203 attr = tagtree_get_attr(local_tc); 210 attr = tagtree_get_attr(local_tc);
204 name = tagtree_get_entry(local_tc, selected_item)->name; 211 name = tagtree_get_entry_name(local_tc, selected_item, buf, sizeof(buf));
205 } 212 }
206 else 213 else
207#endif 214#endif
208 { 215 {
209 struct entry* e = get_entry_at(local_tc, selected_item); 216 struct entry* e = tree_get_entry_at(local_tc, selected_item);
210 name = e->name; 217 name = e->name;
211 attr = e->attr; 218 attr = e->attr;
212 } 219 }
@@ -329,7 +336,7 @@ static int tree_get_file_position(char * filename)
329 /* use lastfile to determine the selected item (default=0) */ 336 /* use lastfile to determine the selected item (default=0) */
330 for (i=0; i < tc.filesindir; i++) 337 for (i=0; i < tc.filesindir; i++)
331 { 338 {
332 e = get_entry_at(&tc, i); 339 e = tree_get_entry_at(&tc, i);
333 if (!strcasecmp(e->name, filename)) 340 if (!strcasecmp(e->name, filename))
334 return(i); 341 return(i);
335 } 342 }
@@ -531,7 +538,7 @@ char* get_current_file(char* buffer, size_t buffer_len)
531 return NULL; 538 return NULL;
532#endif 539#endif
533 540
534 struct entry* e = get_entry_at(&tc, tc.selected_item); 541 struct entry* e = tree_get_entry_at(&tc, tc.selected_item);
535 if (getcwd(buffer, buffer_len)) 542 if (getcwd(buffer, buffer_len))
536 { 543 {
537 if (tc.dirlength) 544 if (tc.dirlength)
@@ -650,7 +657,6 @@ static int dirbrowse(void)
650 657
651 gui_synclist_draw(&tree_lists); 658 gui_synclist_draw(&tree_lists);
652 while(1) { 659 while(1) {
653 struct entry *entries = tc.cache.entries;
654 bool restore = false; 660 bool restore = false;
655 if (tc.dirlevel < 0) 661 if (tc.dirlevel < 0)
656 tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */ 662 tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */
@@ -666,8 +672,9 @@ static int dirbrowse(void)
666 if ( numentries == 0 ) 672 if ( numentries == 0 )
667 break; 673 break;
668 674
675 short attr = tree_get_entry_at(&tc, tc.selected_item)->attr;
669 if ((tc.browse->flags & BROWSE_SELECTONLY) && 676 if ((tc.browse->flags & BROWSE_SELECTONLY) &&
670 !(entries[tc.selected_item].attr & ATTR_DIRECTORY)) 677 !(attr & ATTR_DIRECTORY))
671 { 678 {
672 tc.browse->flags |= BROWSE_SELECTED; 679 tc.browse->flags |= BROWSE_SELECTED;
673 get_current_file(tc.browse->buf, tc.browse->bufsize); 680 get_current_file(tc.browse->buf, tc.browse->bufsize);
@@ -792,15 +799,14 @@ static int dirbrowse(void)
792 else 799 else
793#endif 800#endif
794 { 801 {
795 attr = entries[tc.selected_item].attr; 802 struct entry *entry = tree_get_entry_at(&tc, tc.selected_item);
803 attr = entry->attr;
796 804
797 if (currdir[1]) /* Not in / */ 805 if (currdir[1]) /* Not in / */
798 snprintf(buf, sizeof buf, "%s/%s", 806 snprintf(buf, sizeof buf, "%s/%s",
799 currdir, 807 currdir, entry->name);
800 entries[tc.selected_item].name);
801 else /* In / */ 808 else /* In / */
802 snprintf(buf, sizeof buf, "/%s", 809 snprintf(buf, sizeof buf, "/%s", entry->name);
803 entries[tc.selected_item].name);
804 } 810 }
805 onplay_result = onplay(buf, attr, curr_context, hotkey); 811 onplay_result = onplay(buf, attr, curr_context, hotkey);
806 } 812 }
@@ -999,10 +1005,36 @@ int rockbox_browse(struct browse_context *browse)
999 return ret_val; 1005 return ret_val;
1000} 1006}
1001 1007
1008static int move_callback(int handle, void* current, void* new)
1009{
1010 struct tree_cache* cache = &tc.cache;
1011 if (cache->lock_count > 0)
1012 return BUFLIB_CB_CANNOT_MOVE;
1013
1014 size_t diff = new - current;
1015 /* FIX_PTR makes sure to not accidentally update static allocations */
1016#define FIX_PTR(x) \
1017 { if ((void*)x > current && (void*)x < (current+cache->name_buffer_size)) x+= diff; }
1018
1019 if (handle == cache->name_buffer_handle)
1020 { /* update entry structs, *even if they are struct tagentry */
1021 struct entry *this = core_get_data(cache->entries_handle);
1022 struct entry *last = this + cache->max_entries;
1023 for(; this < last; this++)
1024 FIX_PTR(this->name);
1025 }
1026 /* nothing to do if entries moved */
1027 return BUFLIB_CB_OK;
1028}
1029
1030static struct buflib_callbacks ops = {
1031 .move_callback = move_callback,
1032 .shrink_callback = NULL,
1033};
1034
1002void tree_mem_init(void) 1035void tree_mem_init(void)
1003{ 1036{
1004 /* initialize tree context struct */ 1037 /* initialize tree context struct */
1005 int handle;
1006 struct tree_cache* cache = &tc.cache; 1038 struct tree_cache* cache = &tc.cache;
1007 memset(&tc, 0, sizeof(tc)); 1039 memset(&tc, 0, sizeof(tc));
1008 tc.dirfilter = &global_settings.dirfilter; 1040 tc.dirfilter = &global_settings.dirfilter;
@@ -1010,12 +1042,14 @@ void tree_mem_init(void)
1010 1042
1011 cache->name_buffer_size = AVERAGE_FILENAME_LENGTH * 1043 cache->name_buffer_size = AVERAGE_FILENAME_LENGTH *
1012 global_settings.max_files_in_dir; 1044 global_settings.max_files_in_dir;
1013 handle = core_alloc("tree names", cache->name_buffer_size); 1045 cache->name_buffer_handle = core_alloc_ex("tree names",
1014 cache->name_buffer = core_get_data(handle); 1046 cache->name_buffer_size,
1047 &ops);
1015 1048
1016 cache->max_entries = global_settings.max_files_in_dir; 1049 cache->max_entries = global_settings.max_files_in_dir;
1017 handle = core_alloc("tree entries", cache->max_entries*(sizeof(struct entry))); 1050 cache->entries_handle = core_alloc_ex("tree entries",
1018 cache->entries = core_get_data(handle); 1051 cache->max_entries*(sizeof(struct entry)),
1052 &ops);
1019 tree_get_filetypes(&filetypes, &filetypes_count); 1053 tree_get_filetypes(&filetypes, &filetypes_count);
1020} 1054}
1021 1055