summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2004-05-21 20:08:24 +0000
committerBjörn Stenberg <bjorn@haxx.se>2004-05-21 20:08:24 +0000
commitfb00c2190bab443812581473032156eb1e804c30 (patch)
tree7ac8b3964e7ebf284b1eae3a384a036e928f568d
parent087a085790b2f9099e9b7c9184374a30520f408e (diff)
downloadrockbox-fb00c2190bab443812581473032156eb1e804c30.tar.gz
rockbox-fb00c2190bab443812581473032156eb1e804c30.zip
Plugin/file type association system. Patch #879411 by Henrik Backe
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4677 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/filetypes.c688
-rw-r--r--apps/filetypes.h53
-rw-r--r--apps/lang/english.lang36
-rw-r--r--apps/onplay.c34
-rw-r--r--apps/player/icons.h7
-rw-r--r--apps/plugins/Makefile2
-rw-r--r--apps/recorder/icons.c5
-rw-r--r--apps/recorder/icons.h10
-rw-r--r--apps/settings_menu.c2
-rw-r--r--apps/tree.c133
-rw-r--r--apps/tree.h34
-rw-r--r--uisimulator/win32/Makefile5
-rw-r--r--uisimulator/x11/Makefile5
13 files changed, 894 insertions, 120 deletions
diff --git a/apps/filetypes.c b/apps/filetypes.c
new file mode 100644
index 0000000000..f7eb33b74a
--- /dev/null
+++ b/apps/filetypes.c
@@ -0,0 +1,688 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 *
8 * $Id$
9 *
10 * Copyright (C) 2004 Henrik Backe
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
20#include <stdio.h>
21#include <string.h>
22#include <stdlib.h>
23#include <stdbool.h>
24
25#include "sprintf.h"
26#include "settings.h"
27#include "debug.h"
28#include "lang.h"
29#include "language.h"
30#include "kernel.h"
31#include "plugin.h"
32#include "filetypes.h"
33#include "screens.h"
34#include "icons.h"
35#include "dir.h"
36#include "file.h"
37#include "icons.h"
38
39/* max plugin name size without extensions and path */
40#define MAX_PLUGIN_LENGTH 32
41
42/* max filetypes (plugins & icons stored here) */
43#define MAX_FILETYPES 32
44
45/* max exttypes (extensions stored here) */
46#define MAX_EXTTYPES 32
47
48/* string buffer length */
49#define STRING_BUFFER_SIZE 256
50
51/* number of bytes for the binary icon */
52#define ICON_LENGTH 6
53
54/* mask for dynamic filetype info in attribute */
55#define FILETYPES_MASK 0xFF00
56
57/* filenames */
58#define ROCK_EXTENSION ".rock"
59#define VIEWERS_CONFIG ROCKBOX_DIR "/viewers.config"
60#define VIEWERS_DIR ROCKBOX_DIR "/viewers"
61
62/* global variables */
63static int cnt_filetypes;
64static int cnt_exttypes;
65static struct ext_type exttypes [MAX_EXTTYPES];
66static struct file_type filetypes[MAX_FILETYPES];
67static int first_soft_exttype;
68static int first_soft_filetype;
69static char* next_free_string;
70static char plugin_name[sizeof(VIEWERS_DIR) + 7 + MAX_PLUGIN_LENGTH];
71static char string_buffer[STRING_BUFFER_SIZE];
72
73/* prototypes */
74#ifdef HAVE_LCD_BITMAP
75static char* string2icon(char*);
76#endif
77static char* get_string(char*);
78static int find_attr_index(int);
79static bool read_config(char*);
80static void rm_whitespaces(char*);
81static void scan_plugins(void);
82
83/* initialize dynamic filetypes (called at boot from tree.c) */
84void filetype_init(void)
85{
86 int cnt,i,ix;
87 struct filetype* ftypes;
88
89 memset(exttypes,0,sizeof(exttypes));
90 memset(filetypes,0,sizeof(filetypes));
91 next_free_string=string_buffer;
92
93/* The special filetype folder must always be stored at index 0 */
94#ifdef HAVE_LCD_BITMAP
95 if (!filetypes[0].icon)
96 filetypes[0].icon = bitmap_icons_6x8[Folder];
97#else
98 if (!filetypes[0].icon)
99 filetypes[0].icon = Folder;
100 for (i=1; i < MAX_FILETYPES; i++)
101 filetypes[i].icon = -1;
102#endif
103
104 /* register hardcoded filetypes */
105 tree_get_filetypes(&ftypes, &cnt);
106 cnt_exttypes=0;
107 cnt_filetypes=0;
108
109 for (i = 0; i < cnt ; i++)
110 {
111 ix = ((ftypes[i].tree_attr & FILETYPES_MASK) >> 8);
112 if (ix < MAX_FILETYPES && i < MAX_EXTTYPES)
113 {
114#ifdef HAVE_LCD_BITMAP
115 if (filetypes[ix].icon == NULL)
116 filetypes[ix].icon=bitmap_icons_6x8[ftypes[i].icon];
117#else
118 if (filetypes[ix].icon == -1)
119 filetypes[ix].icon=ftypes[i].icon;
120#endif
121 if (ix > cnt_filetypes)
122 cnt_filetypes=ix;
123 exttypes[cnt_exttypes].type=&filetypes[ix];
124 exttypes[cnt_exttypes].extension=ftypes[i].extension;
125 cnt_exttypes++;
126 }
127 }
128 first_soft_exttype=cnt_exttypes;
129 cnt_filetypes++;
130 first_soft_filetype=cnt_filetypes;
131
132 /* register dynamic filetypes */
133 read_config(VIEWERS_CONFIG);
134 scan_plugins();
135}
136
137/* get icon */
138#ifdef HAVE_LCD_BITMAP
139char* filetype_get_icon(int attr)
140#else
141int filetype_get_icon(int attr)
142#endif
143{
144 int ix;
145
146 ix = find_attr_index(attr);
147
148 if (ix < 0)
149 {
150#ifdef HAVE_LCD_BITMAP
151 return NULL;
152#else
153 return -1;
154#endif
155 }
156 else
157 {
158 return filetypes[ix].icon;
159 }
160}
161
162/* get plugin */
163char* filetype_get_plugin(struct entry* file)
164{
165 int ix;
166
167 ix=find_attr_index(file->attr);
168
169 if (ix < 0)
170 {
171 return NULL;
172 }
173
174 if ((filetypes[ix].plugin == NULL) ||
175 (strlen(filetypes[ix].plugin) > MAX_PLUGIN_LENGTH))
176 return NULL;
177
178 snprintf(plugin_name, sizeof(plugin_name),
179 VIEWERS_DIR "/%s.rock",filetypes[ix].plugin);
180
181 return plugin_name;
182}
183
184/* check if filetype is supported */
185bool filetype_supported(int attr)
186{
187 int ix;
188
189 ix=find_attr_index(attr);
190
191 /* hard filetypes and soft filetypes with plugins is supported */
192 if (ix > 0)
193 if (filetypes[ix].plugin || ix < first_soft_filetype)
194 return true;
195
196 return false;
197}
198
199/* get the "dynamic" attribute for an extension */
200int filetype_get_attr(char* name)
201{
202 int i;
203
204 for (i=0; i < cnt_exttypes; i++)
205 {
206 if (exttypes[i].extension)
207 {
208 if (!strcasecmp(&name[strlen(name)-
209 strlen(exttypes[i].extension)],
210 exttypes[i].extension))
211 {
212 return ((((unsigned int)exttypes[i].type -
213 (unsigned int)&filetypes[0]) /
214 sizeof(struct file_type)) << 8);
215 }
216 }
217 }
218
219 return 0;
220}
221
222/* fill a menu list with viewers (used in onplay.c) */
223int filetype_load_menu(struct menu_item* menu,int max_items)
224{
225 int i;
226 int cnt=0;
227 char* dash;
228
229 for (i=0; i < cnt_filetypes; i++)
230 {
231 if (filetypes[i].plugin)
232 {
233 menu[cnt].desc = filetypes[i].plugin;
234 cnt++;
235 if (cnt == max_items)
236 break;
237 }
238 }
239 return cnt;
240}
241
242/* start a plugin with an argument (called from onplay.c) */
243void filetype_load_plugin(char* plugin, char* file)
244{
245 snprintf(plugin_name,sizeof(plugin_name),"%s/%s.rock",
246 VIEWERS_DIR,plugin);
247 plugin_load(plugin_name,file);
248}
249
250/* get index to filetypes[] from the file attribute */
251static int find_attr_index(int attr)
252{
253 int ix;
254 ix = ((attr & FILETYPES_MASK) >> 8);
255
256 if ((attr & ATTR_DIRECTORY)==ATTR_DIRECTORY)
257 {
258 ix=0;
259 }
260 else
261 {
262 if (ix==0)
263 ix=-1;
264 if (ix > cnt_filetypes)
265 ix=-1;
266 else
267 if ((filetypes[ix].plugin == NULL) &&
268#ifdef HAVE_LCD_BITMAP
269 (filetypes[ix].icon == NULL)
270#else
271 (filetypes[ix].icon == -1)
272#endif
273 )
274 ix=-1;
275 }
276
277 return ix;
278}
279
280/* scan the plugin directory and register filetypes */
281static void scan_plugins(void)
282{
283 DIR *dir;
284 struct dirent *entry;
285 char* cp;
286 char* dot;
287 char* dash;
288 int ix;
289 int i;
290 bool found;
291
292 dir = opendir(VIEWERS_DIR);
293 if(!dir)
294 return;
295
296 while (true)
297 {
298 /* exttypes[] full, bail out */
299 if (cnt_exttypes >= MAX_EXTTYPES)
300 {
301 splash(HZ,true,str(LANG_FILETYPES_EXTENSION_FULL));
302 break;
303 }
304
305 /* filetypes[] full, bail out */
306 if (cnt_filetypes >= MAX_FILETYPES)
307 {
308 splash(HZ,true,str(LANG_FILETYPES_FULL));
309 break;
310 }
311
312 entry = readdir(dir);
313
314 if (!entry)
315 break;
316
317 /* skip directories */
318 if ((entry->attribute & ATTR_DIRECTORY))
319 continue;
320
321 /* Skip FAT volume ID */
322 if (entry->attribute & ATTR_VOLUME_ID)
323 continue;
324
325 /* filter out dotfiles and hidden files */
326 if ((entry->d_name[0]=='.') ||
327 (entry->attribute & ATTR_HIDDEN)) {
328 continue;
329 }
330
331 /* filter out non rock files */
332 if (!strcasecmp(
333 &entry->d_name[strlen(entry->d_name) - sizeof(ROCK_EXTENSION) -1],
334 ROCK_EXTENSION)) {
335 continue;
336 }
337
338 /* filter out to long filenames */
339 if (strlen(entry->d_name) > MAX_PLUGIN_LENGTH + 5)
340 {
341 splash(HZ,true,str(LANG_FILETYPES_PLUGIN_NAME_LONG));
342 continue;
343 }
344
345 dot=strrchr(entry->d_name,'.');
346 *dot='\0';
347 dash=strchr(entry->d_name,'-');
348
349 /* add plugin and extension */
350 if (dash)
351 {
352 *dash='\0';
353 ix=(filetype_get_attr(entry->d_name) >> 8);
354 if (!ix)
355 {
356 cp=get_string(entry->d_name);
357 if (cp)
358 {
359 exttypes[cnt_exttypes].extension=cp;
360 exttypes[cnt_exttypes].type=&filetypes[cnt_filetypes];
361#ifdef HAVE_LCD_BITMAP
362 exttypes[cnt_exttypes].type->icon = bitmap_icons_6x8[Plugin];
363#else
364 exttypes[cnt_exttypes].type->icon = Plugin;
365#endif
366 cnt_exttypes++;
367
368 *dash='-';
369 cp=get_string(entry->d_name);
370 if (cp)
371 {
372 filetypes[cnt_filetypes].plugin=cp;
373 cnt_filetypes++;
374 }
375 else
376 break;
377 }
378 else
379 break;
380 }
381 else
382 {
383 *dash='-';
384 if (!filetypes[ix].plugin)
385 {
386 cp=get_string(entry->d_name);
387 if (cp)
388 {
389 filetypes[cnt_filetypes].plugin=cp;
390 cnt_filetypes++;
391 }
392 else
393 break;
394 }
395 }
396 *dash='-';
397 }
398 /* add plugin only */
399 else
400 {
401 found=false;
402 for (i = first_soft_filetype; i < cnt_filetypes; i++)
403 {
404 if (filetypes[i].plugin)
405 if (!strcasecmp(filetypes[i].plugin,entry->d_name))
406 {
407 found=true;
408 break;
409 }
410 }
411
412 if (!found)
413 {
414 cp=get_string(entry->d_name);
415 if (cp)
416 {
417 filetypes[cnt_filetypes].plugin=cp;
418 filetypes[cnt_filetypes].no_extension=true;
419 cnt_filetypes++;
420 }
421 else
422 break;
423 }
424 }
425 *dot='.';
426 }
427 closedir(dir);
428}
429
430/* read config file (or cahe file) */
431bool read_config(char* file)
432{
433 enum {extension,
434 plugin,
435#ifdef HAVE_LCD_BITMAP
436 icon,
437#endif
438 last};
439
440 int i;
441 int fd;
442 char* end;
443 char* cp;
444 char* str[last];
445 char buf[80];
446
447 fd = open(file, O_RDONLY);
448 if (fd < 0)
449 return false;
450
451 while (read_line(fd, buf, sizeof(buf)))
452 {
453 if (cnt_exttypes >= MAX_EXTTYPES)
454 {
455 splash(HZ,true,str(LANG_FILETYPES_EXTENSION_FULL));
456 break;
457 }
458
459 if (cnt_filetypes >= MAX_FILETYPES)
460 {
461 splash(HZ,true,str(LANG_FILETYPES_FULL));
462 break;
463 }
464
465 /* parse buffer */
466 rm_whitespaces(buf);
467
468 if (strlen(buf) == 0)
469 continue;
470
471 if (buf[0] == '#')
472 continue;
473
474 memset(str,0,sizeof(str));
475 i=0;
476 cp=buf;
477 while (*cp==',') {
478 cp++;
479 i++;
480 }
481 str[i] = strtok_r(cp, ",", &end);
482 i++;
483
484 while (end && i < last)
485 {
486 if (end)
487 {
488 cp=end;
489 while (*cp==',') {
490 cp++;
491 i++;
492 }
493 }
494 str[i] = strtok_r(NULL, ",", &end);
495 i++;
496 }
497
498 /* bail out if no icon and no plugin */
499 if ((!str[plugin] || !strlen(str[plugin])) &&
500#ifdef HAVE_LCD_BITMAP
501 (!str[icon] || !strlen(str[icon])) &&
502#endif
503 strlen(str[extension]))
504 continue;
505
506 /* bail out if no plugin and icon is incorrect*/
507 if ((!str[plugin] || !strlen(str[plugin])) &&
508#ifdef HAVE_LCD_BITMAP
509 (strlen(str[icon]) != ICON_LENGTH*2) &&
510#endif
511 strlen(str[extension]))
512 continue;
513
514 /* bail out if no icon and no plugin and no extension*/
515 if ((!str[plugin] || !strlen(str[plugin])) &&
516#ifdef HAVE_LCD_BITMAP
517 (!str[icon] || !strlen(str[icon])) &&
518#endif
519 (!str[extension] || !strlen(str[extension])))
520 continue;
521
522 /* add extension */
523 if (str[extension])
524 {
525 if (strlen(str[extension]))
526 {
527 cp=get_string(str[extension]);
528 if (cp)
529 {
530 exttypes[cnt_exttypes].type = &filetypes[cnt_filetypes];
531 exttypes[cnt_exttypes].extension = cp;
532 cnt_exttypes++;
533 }
534 else
535 break;
536
537#ifdef HAVE_LCD_BITMAP
538 /* add icon */
539 if (str[icon])
540 {
541 cp = string2icon(str[icon]);
542 if (cp)
543 filetypes[cnt_filetypes].icon = cp;
544 else
545 break;
546 }
547#endif
548 }
549 }
550
551 /* are we able to start plugin from onplay.c ?*/
552 if (str[plugin])
553 {
554 if (strlen(str[plugin]) > MAX_PLUGIN_LENGTH)
555 {
556 splash(HZ, true, str(LANG_FILETYPES_PLUGIN_NAME_LONG));
557 str[plugin] = NULL;
558 }
559 }
560
561 /* add plugin */
562 if (str[plugin])
563 {
564 if (strlen(str[plugin]))
565 {
566 cp=strrchr(str[plugin], '.');
567 if (cp)
568 *cp='\0';
569
570 cp = get_string(str[plugin]);
571 if (cp)
572 filetypes[cnt_filetypes].plugin = cp;
573 else
574 break;
575 }
576 }
577
578 if (filetypes[cnt_filetypes].plugin)
579 cnt_filetypes++;
580 }
581 close(fd);
582
583 return true;
584}
585
586#ifdef HAVE_LCD_BITMAP
587/* convert an ascii hexadecimal icon to a binary icon */
588static char* string2icon(char* str)
589{
590 char tmp[ICON_LENGTH*2];
591 char *cp;
592 int i;
593
594 if (strlen(str)!=ICON_LENGTH*2)
595 return NULL;
596
597 if ((sizeof(string_buffer) +
598 (unsigned int) string_buffer -
599 (unsigned int) next_free_string) < ICON_LENGTH)
600 {
601 splash(HZ,true,str(LANG_FILETYPES_STRING_BUFFER_EMPTY));
602 return NULL;
603 }
604
605 for (i=0; i<12; i++)
606 {
607 if (str[i] >= '0' && str[i] <= '9')
608 {
609 tmp[i]=str[i]-'0';
610 continue;
611 }
612
613 if (str[i] >= 'a' && str[i] <= 'f')
614 {
615 tmp[i]=str[i]-'a'+10;
616 continue;
617 }
618
619 if (str[i] >= 'A' && str[i] <= 'F')
620 {
621 tmp[i]=str[i]-'A'+10;
622 continue;
623 }
624
625 return NULL;
626 }
627
628 cp=next_free_string;
629 for (i = 0; i < ICON_LENGTH; i++)
630 cp[i]=((tmp[i*2]<<4) | tmp[i*2+1]);
631
632 next_free_string=&next_free_string[ICON_LENGTH];
633 return cp;
634}
635#endif
636
637/* get string from buffer */
638static char* get_string(char* str)
639{
640 unsigned int l=strlen(str)+1;
641 char* cp;
642
643 if (!str)
644 return NULL;
645
646 if (l <= (sizeof(string_buffer) +
647 (unsigned int) string_buffer -
648 (unsigned int) next_free_string))
649 {
650 strcpy(next_free_string,str);
651 cp=next_free_string;
652 next_free_string=&next_free_string[l];
653 return cp;
654 }
655 else
656 {
657 splash(HZ,true,str(LANG_FILETYPES_STRING_BUFFER_EMPTY));
658 return NULL;
659 }
660}
661
662/* remove all white spaces from string */
663static void rm_whitespaces(char* str)
664{
665 char *cp, *free;
666
667 cp=str;
668 free=cp;
669
670 while (cp < &str[strlen(str)])
671 {
672 switch (*cp)
673 {
674 case ' ' :
675 case '\t' :
676 case '\r' :
677 break;
678
679 default:
680 *free=*cp;
681 free++;
682 break;
683 }
684 cp++;
685 }
686
687 *free='\0';
688}
diff --git a/apps/filetypes.h b/apps/filetypes.h
new file mode 100644
index 0000000000..30bb71a38e
--- /dev/null
+++ b/apps/filetypes.h
@@ -0,0 +1,53 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:
9 *
10 * Copyright (C) 2002 Henrik Backe
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#ifndef _FILEHANDLE_H_
20#define _FILEHANDLE_H_
21
22#include <stdbool.h>
23#include <tree.h>
24#include <menu.h>
25
26int filetype_get_attr(char*);
27#ifdef HAVE_LCD_BITMAP
28char* filetype_get_icon(int);
29#else
30int filetype_get_icon(int);
31#endif
32char* filetype_get_plugin(struct entry*);
33void filetype_init(void);
34bool filetype_supported(int);
35int filetype_load_menu(struct menu_item*, int);
36void filetype_load_plugin(char*,char*);
37
38struct file_type {
39#ifdef HAVE_LCD_BITMAP
40 unsigned char* icon; /* the icon which shall be used for it, NULL if unknown */
41#else
42 int icon; /* the icon which shall be used for it, -1 if unknown */
43#endif
44 char* plugin; /* Which plugin to use, NULL if unknown */
45 bool no_extension;
46};
47
48struct ext_type {
49 char* extension; /* extension for which the file type is recognized */
50 struct file_type* type;
51};
52
53#endif
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 93b68bc9c8..b9b4b4d1c1 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -2654,3 +2654,39 @@ desc: spoken only, for wall clock announce
2654eng: "" 2654eng: ""
2655voice: "Current time:" 2655voice: "Current time:"
2656new: 2656new:
2657
2658#Filetypes
2659id: LANG_FILETYPES_RESET
2660desc: in the manage settings sub menu
2661eng: "Reset plugin list"
2662new:
2663
2664id: LANG_FILETYPES_RESET_WAIT
2665desc: Filetype reset message
2666eng: "Reset plugins, please wait"
2667new:
2668
2669id: LANG_FILETYPES_EXTENSION_FULL
2670desc: Extension array full
2671eng: "Extension array full"
2672new:
2673
2674id: LANG_FILETYPES_FULL
2675desc: Filetype array full
2676eng: "Filetype array full"
2677new:
2678
2679id: LANG_FILETYPES_PLUGIN_NAME_LONG
2680desc: Viewer plugin name to long
2681eng: "Plugin name to long"
2682new:
2683
2684id: LANG_FILETYPES_STRING_BUFFER_EMPTY
2685desc: Filetype string buffer empty
2686eng: "Filetype string buffer empty"
2687new:
2688
2689id: LANG_ONPLAY_OPEN_WITH
2690desc: Onplay open with
2691eng: "Open with"
2692new:
diff --git a/apps/onplay.c b/apps/onplay.c
index b1b690222b..d864b3b2a9 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -43,11 +43,35 @@
43#include "playlist_viewer.h" 43#include "playlist_viewer.h"
44#include "talk.h" 44#include "talk.h"
45#include "onplay.h" 45#include "onplay.h"
46#include "filetypes.h"
46 47
47static char* selected_file = NULL; 48static char* selected_file = NULL;
48static int selected_file_attr = 0; 49static int selected_file_attr = 0;
49static int onplay_result = ONPLAY_OK; 50static int onplay_result = ONPLAY_OK;
50 51
52static bool list_viewers(void)
53{
54 struct menu_item menu[8];
55 int m, i, result;
56
57 i=filetype_load_menu(menu,sizeof(menu)/sizeof(*menu));
58 if (i)
59 {
60 m = menu_init( menu, i, NULL, NULL, NULL, NULL );
61 result = menu_show(m);
62 if (result >= 0)
63 {
64 menu_exit(m);
65 filetype_load_plugin(menu[result].desc,selected_file);
66 }
67 }
68 else
69 {
70 splash(HZ*2, true, "No viewers found");
71 }
72 return false;
73}
74
51/* For playlist options */ 75/* For playlist options */
52struct playlist_args { 76struct playlist_args {
53 int position; 77 int position;
@@ -625,7 +649,7 @@ bool create_dir(void)
625 649
626int onplay(char* file, int attr) 650int onplay(char* file, int attr)
627{ 651{
628 struct menu_item items[5]; /* increase this if you add entries! */ 652 struct menu_item items[6]; /* increase this if you add entries! */
629 int m, i=0, result; 653 int m, i=0, result;
630 654
631 onplay_result = ONPLAY_OK; 655 onplay_result = ONPLAY_OK;
@@ -635,6 +659,14 @@ int onplay(char* file, int attr)
635 selected_file = file; 659 selected_file = file;
636 selected_file_attr = attr; 660 selected_file_attr = attr;
637 661
662 if (!(attr & ATTR_DIRECTORY))
663 {
664 items[i].desc = str(LANG_ONPLAY_OPEN_WITH);
665 items[i].voice_id = LANG_ONPLAY_OPEN_WITH;
666 items[i].function = list_viewers;
667 i++;
668 }
669
638 if (((attr & TREE_ATTR_MASK) == TREE_ATTR_MPA) || 670 if (((attr & TREE_ATTR_MASK) == TREE_ATTR_MPA) ||
639 (attr & ATTR_DIRECTORY) || 671 (attr & ATTR_DIRECTORY) ||
640 ((attr & TREE_ATTR_MASK) == TREE_ATTR_M3U)) 672 ((attr & TREE_ATTR_MASK) == TREE_ATTR_M3U))
diff --git a/apps/player/icons.h b/apps/player/icons.h
index c96f821cfa..041f09eca6 100644
--- a/apps/player/icons.h
+++ b/apps/player/icons.h
@@ -16,6 +16,9 @@
16 * KIND, either express or implied. 16 * KIND, either express or implied.
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19#ifndef _ICONS_H_
20#define _ICONS_H_
21
19#include <lcd.h> 22#include <lcd.h>
20 23
21/* 24/*
@@ -25,9 +28,11 @@
25#ifdef HAVE_LCD_CHARCELLS 28#ifdef HAVE_LCD_CHARCELLS
26 29
27enum { 30enum {
28 Unknown=0x90, 31 Unknown = 0x90,
29 Plugin = 0x17, 32 Plugin = 0x17,
30 Folder, Mod_Ajz, Language, File, Wps, Playlist, Text, Config, 33 Folder, Mod_Ajz, Language, File, Wps, Playlist, Text, Config,
31}; 34};
32 35
33#endif 36#endif
37
38#endif /* _ICONS_H_ */
diff --git a/apps/plugins/Makefile b/apps/plugins/Makefile
index 940f74f506..367103be67 100644
--- a/apps/plugins/Makefile
+++ b/apps/plugins/Makefile
@@ -53,5 +53,5 @@ $(LINKFILE): $(LDS)
53 $(CC) -DMEMORYSIZE=$(MEM) $(DEFINES) -x c -E -P $< >$@ 53 $(CC) -DMEMORYSIZE=$(MEM) $(DEFINES) -x c -E -P $< >$@
54 54
55clean: 55clean:
56 -rm -f $(ROCKS) $(LINKFILE) 56 -rm -f $(ROCKS) $(LINKFILE) $(OBJDIR)/*.rock
57 $(MAKE) -C lib clean 57 $(MAKE) -C lib clean
diff --git a/apps/recorder/icons.c b/apps/recorder/icons.c
index 1612fc10af..ab5abeaecc 100644
--- a/apps/recorder/icons.c
+++ b/apps/recorder/icons.c
@@ -62,14 +62,9 @@ unsigned char bitmap_icons_6x8[LastIcon][6] =
62 { 0x63, 0x7f, 0x3a, 0x7f, 0x63, 0x00 }, /* Mod or ajz file */ 62 { 0x63, 0x7f, 0x3a, 0x7f, 0x63, 0x00 }, /* Mod or ajz file */
63 { 0x60, 0x70, 0x38, 0x2c, 0x7e, 0x7e }, /* Font file */ 63 { 0x60, 0x70, 0x38, 0x2c, 0x7e, 0x7e }, /* Font file */
64 { 0x3e, 0x2a, 0x3e, 0x2a, 0x2a, 0x3e }, /* Language file */ 64 { 0x3e, 0x2a, 0x3e, 0x2a, 0x2a, 0x3e }, /* Language file */
65 { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }, /* Text file */
66 { 0x4e, 0x51, 0x51, 0x40, 0x55, 0x55 }, /* Config file */ 65 { 0x4e, 0x51, 0x51, 0x40, 0x55, 0x55 }, /* Config file */
67 { 0x0a, 0x0a, 0x5f, 0x4e, 0x24, 0x18 }, /* Plugin file */ 66 { 0x0a, 0x0a, 0x5f, 0x4e, 0x24, 0x18 }, /* Plugin file */
68 { 0x2a, 0x7f, 0x41, 0x41, 0x7f, 0x2a }, /* UCL flash file: chip */
69 { 0x70, 0x70, 0x7f, 0x7f, 0x70, 0x70 }, /* Chip8 game: joystick */
70 { 0x5d, 0x7f, 0x5d, 0x7f, 0x5d, 0x7f }, /* Video file: film strip */
71 { 0xff, 0x81, 0xaf, 0xaa, 0x8c, 0xf8 }, /* Bookmark file */ 67 { 0xff, 0x81, 0xaf, 0xaa, 0x8c, 0xf8 }, /* Bookmark file */
72 { 0x18, 0x24, 0x3c, 0x3c, 0x24, 0x18 }, /* JPEG: eye */
73}; 68};
74 69
75unsigned char bitmap_icons_7x8[][7] = 70unsigned char bitmap_icons_7x8[][7] =
diff --git a/apps/recorder/icons.h b/apps/recorder/icons.h
index 30f0cc1f58..3b4947aca7 100644
--- a/apps/recorder/icons.h
+++ b/apps/recorder/icons.h
@@ -16,6 +16,9 @@
16 * KIND, either express or implied. 16 * KIND, either express or implied.
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19#ifndef _ICONS_H_
20#define _ICONS_H_
21
19#include <lcd.h> 22#include <lcd.h>
20 23
21/* 24/*
@@ -28,9 +31,8 @@ enum icons_6x8 {
28 Box_Filled, Box_Empty, Slider_Horizontal, File, 31 Box_Filled, Box_Empty, Slider_Horizontal, File,
29 Folder, Directory, Playlist, Repeat, 32 Folder, Directory, Playlist, Repeat,
30 Selected, Cursor, Wps, Mod_Ajz, 33 Selected, Cursor, Wps, Mod_Ajz,
31 Font, Language, Text, Config, 34 Font, Language, Config, Plugin,
32 Plugin, Flashfile, Chip8, Video, 35 Bookmark,
33 Bookmark, Jpeg,
34 LastIcon 36 LastIcon
35}; 37};
36 38
@@ -97,3 +99,5 @@ extern void statusbar_icon_lock(void);
97extern void statusbar_time(int hour, int minute); 99extern void statusbar_time(int hour, int minute);
98#endif 100#endif
99#endif /* End HAVE_LCD_BITMAP */ 101#endif /* End HAVE_LCD_BITMAP */
102
103#endif /* _ICONS_H_ */
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index 7150dd239d..46a52ce297 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -43,6 +43,7 @@
43#include "screens.h" 43#include "screens.h"
44#include "talk.h" 44#include "talk.h"
45#include "timefuncs.h" 45#include "timefuncs.h"
46#include "filetypes.h"
46#ifdef HAVE_LCD_BITMAP 47#ifdef HAVE_LCD_BITMAP
47#include "peakmeter.h" 48#include "peakmeter.h"
48#endif 49#endif
@@ -1243,6 +1244,7 @@ static bool manage_settings_menu(void)
1243 { STR(LANG_FIRMWARE), firmware_browse }, 1244 { STR(LANG_FIRMWARE), firmware_browse },
1244 { STR(LANG_RESET), reset_settings }, 1245 { STR(LANG_RESET), reset_settings },
1245 { STR(LANG_SAVE_SETTINGS), settings_save_config }, 1246 { STR(LANG_SAVE_SETTINGS), settings_save_config },
1247 { STR(LANG_FILETYPES_RESET), filetype_reset},
1246 }; 1248 };
1247 1249
1248 m=menu_init( items, sizeof(items) / sizeof(*items), NULL, 1250 m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
diff --git a/apps/tree.c b/apps/tree.c
index 140b226a01..8aa7eb0815 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -56,6 +56,7 @@
56#include "power.h" 56#include "power.h"
57#include "action.h" 57#include "action.h"
58#include "talk.h" 58#include "talk.h"
59#include "filetypes.h"
59 60
60#ifdef HAVE_LCD_BITMAP 61#ifdef HAVE_LCD_BITMAP
61#include "widgets.h" 62#include "widgets.h"
@@ -69,37 +70,24 @@
69extern bool language_changed; 70extern bool language_changed;
70 71
71/* a table for the know file types */ 72/* a table for the know file types */
72static struct 73struct filetype filetypes[] = {
73{
74 char* extension; /* extension for which the file type is recognized */
75 int tree_attr; /* which identifier */
76 int icon; /* the icon which shall be used for it, -1 if unknown */
77 int voiceclip; /* spoken extension */
78 /* To have it extendable, there could be more useful stuff in here,
79 like handler functions, plugin name, etc. */
80} filetypes[] = {
81 { ".mp3", TREE_ATTR_MPA, File, VOICE_EXT_MPA }, 74 { ".mp3", TREE_ATTR_MPA, File, VOICE_EXT_MPA },
82 { ".mp2", TREE_ATTR_MPA, File, VOICE_EXT_MPA }, 75 { ".mp2", TREE_ATTR_MPA, File, VOICE_EXT_MPA },
83 { ".mpa", TREE_ATTR_MPA, File, VOICE_EXT_MPA }, 76 { ".mpa", TREE_ATTR_MPA, File, VOICE_EXT_MPA },
84 { ".m3u", TREE_ATTR_M3U, Playlist, LANG_PLAYINDICES_PLAYLIST }, 77 { ".m3u", TREE_ATTR_M3U, Playlist, LANG_PLAYINDICES_PLAYLIST },
85 { ".cfg", TREE_ATTR_CFG, Config, VOICE_EXT_CFG }, 78 { ".cfg", TREE_ATTR_CFG, Config, VOICE_EXT_CFG },
86 { ".wps", TREE_ATTR_WPS, Wps, VOICE_EXT_WPS }, 79 { ".wps", TREE_ATTR_WPS, Wps, VOICE_EXT_WPS },
87 { ".txt", TREE_ATTR_TXT, Text, VOICE_EXT_TXT },
88 { ".lng", TREE_ATTR_LNG, Language, LANG_LANGUAGE }, 80 { ".lng", TREE_ATTR_LNG, Language, LANG_LANGUAGE },
89 { ".rock",TREE_ATTR_ROCK,Plugin, VOICE_EXT_ROCK }, 81 { ".rock",TREE_ATTR_ROCK,Plugin, VOICE_EXT_ROCK },
90#ifdef HAVE_LCD_BITMAP 82#ifdef HAVE_LCD_BITMAP
91 { ".fnt", TREE_ATTR_FONT,Font, VOICE_EXT_FONT }, 83 { ".fnt", TREE_ATTR_FONT,Font, VOICE_EXT_FONT },
92 { ".ch8", TREE_ATTR_CH8, Chip8, -1 },
93 { ".rvf", TREE_ATTR_RVF, Video, -1 },
94 { ".bmark",TREE_ATTR_BMARK, Bookmark, VOICE_EXT_BMARK }, 84 { ".bmark",TREE_ATTR_BMARK, Bookmark, VOICE_EXT_BMARK },
95#else 85#else
96 { ".bmark", TREE_ATTR_BMARK, -1, VOICE_EXT_BMARK }, 86 { ".bmark", TREE_ATTR_BMARK, -1, VOICE_EXT_BMARK },
97#endif 87#endif
98#ifndef SIMULATOR 88#ifndef SIMULATOR
99#ifdef HAVE_LCD_BITMAP 89#ifdef HAVE_LCD_BITMAP
100 { ".ucl", TREE_ATTR_UCL, Flashfile, VOICE_EXT_UCL },
101 { ".ajz", TREE_ATTR_MOD, Mod_Ajz, VOICE_EXT_AJZ }, 90 { ".ajz", TREE_ATTR_MOD, Mod_Ajz, VOICE_EXT_AJZ },
102 { ".jpg", TREE_ATTR_JPEG, Jpeg, -1 },
103#else 91#else
104 { ".mod", TREE_ATTR_MOD, Mod_Ajz, VOICE_EXT_AJZ }, 92 { ".mod", TREE_ATTR_MOD, Mod_Ajz, VOICE_EXT_AJZ },
105#endif 93#endif
@@ -136,6 +124,7 @@ static bool dirbrowse(char *root, int *dirfilter);
136 124
137void browse_root(void) 125void browse_root(void)
138{ 126{
127 filetype_init();
139#ifndef SIMULATOR 128#ifndef SIMULATOR
140 dirbrowse("/", &global_settings.dirfilter); 129 dirbrowse("/", &global_settings.dirfilter);
141#else 130#else
@@ -145,6 +134,11 @@ void browse_root(void)
145#endif 134#endif
146} 135}
147 136
137void tree_get_filetypes(struct filetype** types, int* count)
138{
139 *types = filetypes;
140 *count = sizeof(filetypes) / sizeof(*filetypes);
141}
148 142
149#ifdef HAVE_LCD_BITMAP 143#ifdef HAVE_LCD_BITMAP
150 144
@@ -359,19 +353,7 @@ struct entry* load_and_sort_directory(char *dirname, int *dirfilter,
359 353
360 /* check for known file types */ 354 /* check for known file types */
361 if ( !(dptr->attr & ATTR_DIRECTORY) && (len > 4) ) 355 if ( !(dptr->attr & ATTR_DIRECTORY) && (len > 4) )
362 { 356 dptr->attr |= filetype_get_attr(entry->d_name);
363 unsigned j;
364 for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++)
365 {
366 if (!strcasecmp(
367 &entry->d_name[len-strlen(filetypes[j].extension)],
368 filetypes[j].extension))
369 {
370 dptr->attr |= filetypes[j].tree_attr;
371 break;
372 }
373 }
374 }
375 357
376 /* memorize/compare details about the boot file */ 358 /* memorize/compare details about the boot file */
377 if ((currdir[1] == 0) && !strcasecmp(entry->d_name, BOOTFILE)) { 359 if ((currdir[1] == 0) && !strcasecmp(entry->d_name, BOOTFILE)) {
@@ -391,7 +373,7 @@ struct entry* load_and_sort_directory(char *dirname, int *dirfilter,
391 ((*dirfilter == SHOW_MUSIC && 373 ((*dirfilter == SHOW_MUSIC &&
392 (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_MPA) && 374 (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_MPA) &&
393 (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_M3U) || 375 (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_M3U) ||
394 (*dirfilter == SHOW_SUPPORTED && !(dptr->attr & TREE_ATTR_MASK)) || 376 (*dirfilter == SHOW_SUPPORTED && !filetype_supported(dptr->attr)) ||
395 (*dirfilter == SHOW_WPS && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_WPS) || 377 (*dirfilter == SHOW_WPS && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_WPS) ||
396 (*dirfilter == SHOW_CFG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_CFG) || 378 (*dirfilter == SHOW_CFG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_CFG) ||
397 (*dirfilter == SHOW_LNG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_LNG) || 379 (*dirfilter == SHOW_LNG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_LNG) ||
@@ -444,12 +426,12 @@ static int recalc_screen_height(void)
444 426
445static int showdir(char *path, int start, int *dirfilter) 427static int showdir(char *path, int start, int *dirfilter)
446{ 428{
447 int icon_type = 0;
448 int i; 429 int i;
449 int tree_max_on_screen; 430 int tree_max_on_screen;
450 bool dir_buffer_full; 431 bool dir_buffer_full;
451 432
452#ifdef HAVE_LCD_BITMAP 433#ifdef HAVE_LCD_BITMAP
434 char* icon;
453 int line_height; 435 int line_height;
454 int fw, fh; 436 int fw, fh;
455 lcd_setfont(FONT_UI); 437 lcd_setfont(FONT_UI);
@@ -457,6 +439,7 @@ static int showdir(char *path, int start, int *dirfilter)
457 tree_max_on_screen = recalc_screen_height(); 439 tree_max_on_screen = recalc_screen_height();
458 line_height = fh; 440 line_height = fh;
459#else 441#else
442 int icon;
460 tree_max_on_screen = TREE_MAX_ON_SCREEN; 443 tree_max_on_screen = TREE_MAX_ON_SCREEN;
461#endif 444#endif
462 445
@@ -536,52 +519,24 @@ static int showdir(char *path, int start, int *dirfilter)
536#endif 519#endif
537 520
538 for ( i=start; i < start+tree_max_on_screen; i++ ) { 521 for ( i=start; i < start+tree_max_on_screen; i++ ) {
539 int len;
540 unsigned j;
541
542 if ( i >= filesindir ) 522 if ( i >= filesindir )
543 break; 523 break;
544 524
545 len = strlen(dircache[i].name); 525 icon = filetype_get_icon(dircache[i].attr);
546
547 if (dircache[i].attr & ATTR_DIRECTORY)
548 {
549 icon_type = Folder;
550 }
551 else
552 {
553 /* search which icon to use */
554 icon_type = -1; /* default to none */
555 for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++)
556 {
557 if ((dircache[i].attr & TREE_ATTR_MASK) == filetypes[j].tree_attr)
558 {
559 icon_type = filetypes[j].icon;
560 break;
561 }
562 }
563
564 if (icon_type == -1)
565 {
566#ifdef HAVE_LCD_BITMAP
567 icon_type = 0;
568#else
569 icon_type = Unknown;
570#endif
571 }
572 }
573 526
574 if (icon_type && global_settings.show_icons) { 527 if (icon && global_settings.show_icons) {
575#ifdef HAVE_LCD_BITMAP 528#ifdef HAVE_LCD_BITMAP
576 int offset=0; 529 int offset=0;
577 if ( line_height > 8 ) 530 if ( line_height > 8 )
578 offset = (line_height - 8) / 2; 531 offset = (line_height - 8) / 2;
579 lcd_bitmap(bitmap_icons_6x8[icon_type], 532 lcd_bitmap(icon,
580 CURSOR_X * 6 + CURSOR_WIDTH, 533 CURSOR_X * 6 + CURSOR_WIDTH,
581 MARGIN_Y+(i-start)*line_height + offset, 534 MARGIN_Y+(i-start)*line_height + offset,
582 6, 8, true); 535 6, 8, true);
583#else 536#else
584 lcd_putc(LINE_X-1, i-start, icon_type); 537 if (icon < 0 )
538 icon = Unknown;
539 lcd_putc(LINE_X-1, i-start, icon);
585#endif 540#endif
586 } 541 }
587 542
@@ -1005,6 +960,9 @@ static bool dirbrowse(char *root, int *dirfilter)
1005 else 960 else
1006 currdir[i-1]=0; 961 currdir[i-1]=0;
1007 962
963 if (*dirfilter > NUM_FILTER_MODES && dirlevel < 1)
964 exit_func = true;
965
1008 dirlevel--; 966 dirlevel--;
1009 if ( dirlevel < MAX_DIR_LEVELS ) { 967 if ( dirlevel < MAX_DIR_LEVELS ) {
1010 dirstart = dirpos[dirlevel]; 968 dirstart = dirpos[dirlevel];
@@ -1018,8 +976,11 @@ static bool dirbrowse(char *root, int *dirfilter)
1018 976
1019 restore = true; 977 restore = true;
1020 } 978 }
1021 if (*dirfilter > NUM_FILTER_MODES) 979 else
1022 exit_func = true; 980 {
981 if (*dirfilter > NUM_FILTER_MODES && dirlevel < 1)
982 exit_func = true;
983 }
1023 break; 984 break;
1024 985
1025#ifdef HAVE_RECORDER_KEYPAD 986#ifdef HAVE_RECORDER_KEYPAD
@@ -1171,11 +1132,6 @@ static bool dirbrowse(char *root, int *dirfilter)
1171 reload_dir = true; 1132 reload_dir = true;
1172 break; 1133 break;
1173 1134
1174 case TREE_ATTR_TXT:
1175 plugin_load("/.rockbox/rocks/viewer.rock",buf);
1176 restore = true;
1177 break;
1178
1179 case TREE_ATTR_LNG: 1135 case TREE_ATTR_LNG:
1180 if(!lang_load(buf)) { 1136 if(!lang_load(buf)) {
1181 set_file(buf, global_settings.lang_file, 1137 set_file(buf, global_settings.lang_file,
@@ -1189,21 +1145,6 @@ static bool dirbrowse(char *root, int *dirfilter)
1189 break; 1145 break;
1190 1146
1191#ifdef HAVE_LCD_BITMAP 1147#ifdef HAVE_LCD_BITMAP
1192 /* chip-8 game */
1193 case TREE_ATTR_CH8:
1194 plugin_load("/.rockbox/rocks/chip8.rock",buf);
1195 break;
1196
1197 /* "movie" animation */
1198 case TREE_ATTR_RVF:
1199 plugin_load("/.rockbox/rocks/video.rock",buf);
1200 break;
1201
1202 /* JPEG image */
1203 case TREE_ATTR_JPEG:
1204 plugin_load("/.rockbox/rocks/jpeg.rock",buf);
1205 break;
1206
1207 case TREE_ATTR_FONT: 1148 case TREE_ATTR_FONT:
1208 font_load(buf); 1149 font_load(buf);
1209 set_file(buf, global_settings.font_file, 1150 set_file(buf, global_settings.font_file,
@@ -1224,11 +1165,6 @@ static bool dirbrowse(char *root, int *dirfilter)
1224 case TREE_ATTR_MOD: 1165 case TREE_ATTR_MOD:
1225 rolo_load(buf); 1166 rolo_load(buf);
1226 break; 1167 break;
1227
1228 /* ucl flash file */
1229 case TREE_ATTR_UCL:
1230 plugin_load("/.rockbox/rocks/rockbox_flash.rock",buf);
1231 break;
1232#endif 1168#endif
1233 1169
1234 /* plugin file */ 1170 /* plugin file */
@@ -1238,6 +1174,19 @@ static bool dirbrowse(char *root, int *dirfilter)
1238 else 1174 else
1239 restore = true; 1175 restore = true;
1240 break; 1176 break;
1177
1178 default:
1179 {
1180 char* plugin = filetype_get_plugin(file);
1181 if (plugin)
1182 {
1183 if (plugin_load(plugin,buf) == PLUGIN_USB_CONNECTED)
1184 reload_root = true;
1185 else
1186 restore = true;
1187 }
1188 break;
1189 }
1241 } 1190 }
1242 1191
1243 if ( play ) { 1192 if ( play ) {
@@ -1389,8 +1338,8 @@ static bool dirbrowse(char *root, int *dirfilter)
1389#endif 1338#endif
1390 restore = true; 1339 restore = true;
1391 } 1340 }
1392 break;
1393#endif 1341#endif
1342 break;
1394 1343
1395 case SYS_USB_CONNECTED: 1344 case SYS_USB_CONNECTED:
1396 status_set_playmode(STATUS_STOP); 1345 status_set_playmode(STATUS_STOP);
diff --git a/apps/tree.h b/apps/tree.h
index 2bd133d3e9..367a4fad00 100644
--- a/apps/tree.h
+++ b/apps/tree.h
@@ -26,23 +26,27 @@ struct entry {
26 char *name; 26 char *name;
27}; 27};
28 28
29struct filetype {
30 char* extension;
31 int tree_attr;
32 int icon;
33 int voiceclip;
34};
35
36
29/* using attribute not used by FAT */ 37/* using attribute not used by FAT */
30#define TREE_ATTR_MPA 0x0100 /* mpeg audio file */ 38#define TREE_ATTR_MPA 0x0100 /* mpeg audio file */
31#define TREE_ATTR_M3U 0x0200 /* playlist */ 39#define TREE_ATTR_M3U 0x0200 /* playlist */
32#define TREE_ATTR_WPS 0x0300 /* wps config file */ 40#define TREE_ATTR_WPS 0x0300 /* wps config file */
33#define TREE_ATTR_MOD 0x0400 /* firmware file */ 41#define TREE_ATTR_MOD 0x0400 /* firmware file */
34#define TREE_ATTR_CFG 0x0500 /* config file */ 42#define TREE_ATTR_CFG 0x0500 /* config file */
35#define TREE_ATTR_TXT 0x0600 /* text file */ 43#define TREE_ATTR_FONT 0x0600 /* font file */
36#define TREE_ATTR_FONT 0x0700 /* font file */ 44#define TREE_ATTR_LNG 0x0700 /* binary lang file */
37#define TREE_ATTR_LNG 0x0800 /* binary lang file */ 45#define TREE_ATTR_ROCK 0x0800 /* binary rockbox plugin */
38#define TREE_ATTR_ROCK 0x0900 /* binary rockbox plugin */ 46#define TREE_ATTR_BMARK 0x0900 /* book mark file */
39#define TREE_ATTR_UCL 0x0A00 /* rockbox flash image */ 47#define TREE_ATTR_MASK 0xFFC0 /* which bits tree.c uses (above) */
40#define TREE_ATTR_CH8 0x0B00 /* chip-8 game */
41#define TREE_ATTR_RVF 0x0C00 /* rockbox video file */
42#define TREE_ATTR_BMARK 0x0D00 /* book mark file */
43#define TREE_ATTR_JPEG 0x0E00 /* JPEG image */
44#define TREE_ATTR_MASK 0xFFC0 /* which bits tree.c uses (above) */
45 48
49void tree_get_filetypes(struct filetype**, int*);
46void tree_init(void); 50void tree_init(void);
47void browse_root(void); 51void browse_root(void);
48void set_current_file(char *path); 52void set_current_file(char *path);
diff --git a/uisimulator/win32/Makefile b/uisimulator/win32/Makefile
index 05acb9c41c..59ef7f5206 100644
--- a/uisimulator/win32/Makefile
+++ b/uisimulator/win32/Makefile
@@ -103,7 +103,7 @@ FIRMSRCS = $(LCDSRSC) id3.c mp3data.c usb.c mpeg.c mp3_playback.c \
103APPS = main.c tree.c menu.c credits.c main_menu.c icons.c language.c \ 103APPS = main.c tree.c menu.c credits.c main_menu.c icons.c language.c \
104 playlist.c wps.c wps-display.c settings.c status.c \ 104 playlist.c wps.c wps-display.c settings.c status.c \
105 screens.c peakmeter.c sleeptimer.c keyboard.c onplay.c\ 105 screens.c peakmeter.c sleeptimer.c keyboard.c onplay.c\
106 misc.c plugin.c playlist_viewer.c bookmark.c 106 misc.c plugin.c playlist_viewer.c bookmark.c filetypes.c
107 107
108MENUS = settings_menu.c sound_menu.c playlist_menu.c 108MENUS = settings_menu.c sound_menu.c playlist_menu.c
109 109
@@ -199,6 +199,9 @@ $(OBJDIR)/tree.o: $(APPDIR)/tree.c
199$(OBJDIR)/onplay.o: $(APPDIR)/onplay.c 199$(OBJDIR)/onplay.o: $(APPDIR)/onplay.c
200 $(CC) $(APPCFLAGS) -c $< -o $@ 200 $(CC) $(APPCFLAGS) -c $< -o $@
201 201
202$(OBJDIR)/filetypes.o: $(APPDIR)/filetypes.c
203 $(CC) $(APPCFLAGS) -c $< -o $@
204
202$(OBJDIR)/playlist.o: $(APPDIR)/playlist.c 205$(OBJDIR)/playlist.o: $(APPDIR)/playlist.c
203 $(CC) $(APPCFLAGS) -c $< -o $@ 206 $(CC) $(APPCFLAGS) -c $< -o $@
204 207
diff --git a/uisimulator/x11/Makefile b/uisimulator/x11/Makefile
index 6fbc413a3c..65f0b8d5a2 100644
--- a/uisimulator/x11/Makefile
+++ b/uisimulator/x11/Makefile
@@ -102,7 +102,7 @@ FIRMSRCS = $(LCDSRSC) id3.c debug.c usb.c mpeg.c mp3_playback.c power.c\
102APPS = main.c tree.c menu.c credits.c main_menu.c language.c\ 102APPS = main.c tree.c menu.c credits.c main_menu.c language.c\
103 playlist.c wps.c wps-display.c settings.c status.c icons.c\ 103 playlist.c wps.c wps-display.c settings.c status.c icons.c\
104 screens.c peakmeter.c sleeptimer.c keyboard.c onplay.c\ 104 screens.c peakmeter.c sleeptimer.c keyboard.c onplay.c\
105 misc.c plugin.c playlist_viewer.c bookmark.c 105 misc.c plugin.c playlist_viewer.c bookmark.c filetypes.c
106 106
107MENUS = settings_menu.c sound_menu.c playlist_menu.c 107MENUS = settings_menu.c sound_menu.c playlist_menu.c
108 108
@@ -142,6 +142,9 @@ $(OBJDIR)/credits.raw: $(DOCSDIR)/CREDITS
142$(OBJDIR)/credits.o: $(APPDIR)/credits.c $(APPDIR)/credits.h $(OBJDIR)/credits.raw 142$(OBJDIR)/credits.o: $(APPDIR)/credits.c $(APPDIR)/credits.h $(OBJDIR)/credits.raw
143 $(CC) $(APPCFLAGS) -c $< -o $@ 143 $(CC) $(APPCFLAGS) -c $< -o $@
144 144
145$(OBJDIR)/filetypes.o: $(APPDIR)/filetypes.c
146 $(CC) $(APPCFLAGS) -c $< -o $@
147
145$(OBJDIR)/menu.o: $(APPDIR)/menu.c 148$(OBJDIR)/menu.o: $(APPDIR)/menu.c
146 $(CC) $(APPCFLAGS) -c $< -o $@ 149 $(CC) $(APPCFLAGS) -c $< -o $@
147 150