1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2004 Henrik Backe
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
32 #include "filetypes.h"
40 /* max plugin name size without extensions and path */
41 #define MAX_PLUGIN_LENGTH 32
43 /* max filetypes (plugins & icons stored here) */
44 #if CONFIG_CODEC == SWCODEC
45 #define MAX_FILETYPES 64
47 #define MAX_FILETYPES 32
50 /* max exttypes (extensions stored here) */
51 #if CONFIG_CODEC == SWCODEC
52 /* Software codecs require more file extensions */
53 #define MAX_EXTTYPES 64
55 #define MAX_EXTTYPES 32
58 /* string buffer length */
59 #define STRING_BUFFER_SIZE 512
61 /* number of bytes for the binary icon */
64 /* mask for dynamic filetype info in attribute */
65 #define FILETYPES_MASK 0xFF00
68 #define ROCK_EXTENSION ".rock"
69 #define VIEWERS_CONFIG ROCKBOX_DIR "/viewers.config"
70 #define VIEWERS_DIR ROCKBOX_DIR "/viewers"
72 /* global variables */
73 static int cnt_filetypes
;
74 static int cnt_exttypes
;
75 static struct ext_type exttypes
[MAX_EXTTYPES
];
76 static struct file_type filetypes
[MAX_FILETYPES
];
77 static int first_soft_exttype
;
78 static int first_soft_filetype
;
79 static char* next_free_string
;
80 static char plugin_name
[sizeof(VIEWERS_DIR
) + 7 + MAX_PLUGIN_LENGTH
];
81 static char string_buffer
[STRING_BUFFER_SIZE
];
84 #ifdef HAVE_LCD_BITMAP
85 static char* string2icon(const char*);
86 static int add_plugin(char*,char*);
88 static int add_plugin(char*);
90 static char* get_string(const char*);
91 static int find_attr_index(int);
92 static bool read_config(const char*);
93 static void rm_whitespaces(char*);
94 static void scan_plugins(void);
96 /* initialize dynamic filetypes (called at boot from tree.c) */
97 void filetype_init(void)
100 const struct filetype
* ftypes
;
102 memset(exttypes
,0,sizeof(exttypes
));
103 memset(filetypes
,0,sizeof(filetypes
));
104 next_free_string
=string_buffer
;
106 /* The special filetype folder must always be stored at index 0 */
107 #ifdef HAVE_LCD_BITMAP
108 if (!filetypes
[0].icon
)
109 filetypes
[0].icon
= bitmap_icons_6x8
[Icon_Folder
];
111 if (!filetypes
[0].icon
)
112 filetypes
[0].icon
= Icon_Folder
;
113 for (i
=1; i
< MAX_FILETYPES
; i
++)
114 filetypes
[i
].icon
= -1;
117 /* register hardcoded filetypes */
118 tree_get_filetypes(&ftypes
, &cnt
);
122 for (i
= 0; i
< cnt
; i
++)
124 ix
= ((ftypes
[i
].tree_attr
& FILETYPES_MASK
) >> 8);
125 if (ix
< MAX_FILETYPES
&& i
< MAX_EXTTYPES
)
127 #ifdef HAVE_LCD_BITMAP
128 if (filetypes
[ix
].icon
== NULL
)
129 filetypes
[ix
].icon
=bitmap_icons_6x8
[ftypes
[i
].icon
];
131 if (filetypes
[ix
].icon
== -1)
132 filetypes
[ix
].icon
=ftypes
[i
].icon
;
134 if (ix
> cnt_filetypes
)
136 exttypes
[cnt_exttypes
].type
=&filetypes
[ix
];
137 exttypes
[cnt_exttypes
].extension
=ftypes
[i
].extension
;
141 first_soft_exttype
=cnt_exttypes
;
143 first_soft_filetype
=cnt_filetypes
;
145 /* register dynamic filetypes */
146 read_config(VIEWERS_CONFIG
);
151 #ifdef HAVE_LCD_BITMAP
152 const unsigned char* filetype_get_icon(int attr
)
154 int filetype_get_icon(int attr
)
159 ix
= find_attr_index(attr
);
163 #ifdef HAVE_LCD_BITMAP
171 return filetypes
[ix
].icon
;
176 char* filetype_get_plugin(const struct entry
* file
)
180 ix
=find_attr_index(file
->attr
);
187 if ((filetypes
[ix
].plugin
== NULL
) ||
188 (strlen(filetypes
[ix
].plugin
) > MAX_PLUGIN_LENGTH
))
191 snprintf(plugin_name
, sizeof(plugin_name
),
192 "%s/%s.rock", ROCKBOX_DIR
, filetypes
[ix
].plugin
);
197 /* check if filetype is supported */
198 bool filetype_supported(int attr
)
202 ix
=find_attr_index(attr
);
204 /* hard filetypes and soft filetypes with plugins is supported */
206 if (filetypes
[ix
].plugin
|| ix
< first_soft_filetype
)
212 /* get the "dynamic" attribute for an extension */
213 int filetype_get_attr(const char* name
)
216 const char *cp
= strrchr(name
,'.');
218 if (!cp
) /* no extension? -> can't be a supported type */
222 for (i
=0; i
< cnt_exttypes
; i
++)
224 if (exttypes
[i
].extension
)
226 if (!strcasecmp(cp
,exttypes
[i
].extension
))
228 return ((((unsigned long)exttypes
[i
].type
-
229 (unsigned long)&filetypes
[0]) /
230 sizeof(struct file_type
)) << 8);
238 /* fill a menu list with viewers (used in onplay.c) */
239 int filetype_load_menu(struct menu_item
* menu
,int max_items
)
245 for (i
=0; i
< cnt_filetypes
; i
++)
247 if (filetypes
[i
].plugin
)
249 cp
=strrchr(filetypes
[i
].plugin
,'/');
251 else cp
=filetypes
[i
].plugin
;
252 menu
[cnt
].desc
= (unsigned char *)cp
;
254 if (cnt
== max_items
)
261 /* start a plugin with an argument (called from onplay.c) */
262 int filetype_load_plugin(const char* plugin
, char* file
)
264 snprintf(plugin_name
,sizeof(plugin_name
),"%s/%s.rock",
266 return plugin_load(plugin_name
,file
);
269 /* get index to filetypes[] from the file attribute */
270 static int find_attr_index(int attr
)
273 ix
= ((attr
& FILETYPES_MASK
) >> 8);
275 if ((attr
& ATTR_DIRECTORY
)==ATTR_DIRECTORY
)
283 if (ix
> cnt_filetypes
)
286 if ((filetypes
[ix
].plugin
== NULL
) &&
287 #ifdef HAVE_LCD_BITMAP
288 (filetypes
[ix
].icon
== NULL
)
290 (filetypes
[ix
].icon
== -1)
299 /* scan the plugin directory and register filetypes */
300 static void scan_plugins(void)
303 struct dirent
*entry
;
311 dir
= opendir(VIEWERS_DIR
);
317 /* exttypes[] full, bail out */
318 if (cnt_exttypes
>= MAX_EXTTYPES
)
320 gui_syncsplash(HZ
, true, str(LANG_FILETYPES_EXTENSION_FULL
));
324 /* filetypes[] full, bail out */
325 if (cnt_filetypes
>= MAX_FILETYPES
)
327 gui_syncsplash(HZ
, true, str(LANG_FILETYPES_FULL
));
331 entry
= readdir(dir
);
336 /* skip directories */
337 if ((entry
->attribute
& ATTR_DIRECTORY
))
340 /* Skip FAT volume ID */
341 if (entry
->attribute
& ATTR_VOLUME_ID
)
344 /* filter out dotfiles and hidden files */
345 if ((entry
->d_name
[0]=='.') ||
346 (entry
->attribute
& ATTR_HIDDEN
)) {
350 /* filter out non rock files */
351 if (strcasecmp((char *)&entry
->d_name
[strlen((char *)entry
->d_name
) -
352 sizeof(ROCK_EXTENSION
) + 1],
357 /* filter out to long filenames */
358 if (strlen((char *)entry
->d_name
) > MAX_PLUGIN_LENGTH
+ 5)
360 gui_syncsplash(HZ
, true, str(LANG_FILETYPES_PLUGIN_NAME_LONG
));
364 dot
=strrchr((char *)entry
->d_name
,'.');
366 dash
=strchr((char *)entry
->d_name
,'-');
368 /* add plugin and extension */
372 ix
=(filetype_get_attr((char *)entry
->d_name
) >> 8);
375 cp
=get_string((char *)entry
->d_name
);
378 exttypes
[cnt_exttypes
].extension
=cp
;
379 exttypes
[cnt_exttypes
].type
=&filetypes
[cnt_filetypes
];
380 #ifdef HAVE_LCD_BITMAP
381 exttypes
[cnt_exttypes
].type
->icon
= bitmap_icons_6x8
[Icon_Plugin
];
383 exttypes
[cnt_exttypes
].type
->icon
= Icon_Plugin
;
388 cp
=get_string((char *)entry
->d_name
);
391 filetypes
[cnt_filetypes
].plugin
=cp
;
403 if (!filetypes
[ix
].plugin
)
405 cp
=get_string((char *)entry
->d_name
);
408 filetypes
[cnt_filetypes
].plugin
=cp
;
417 /* add plugin only */
421 for (i
= first_soft_filetype
; i
< cnt_filetypes
; i
++)
423 if (filetypes
[i
].plugin
)
424 if (!strcasecmp(filetypes
[i
].plugin
, (char *)entry
->d_name
))
433 cp
=get_string((char *)entry
->d_name
);
436 filetypes
[cnt_filetypes
].plugin
=cp
;
437 filetypes
[cnt_filetypes
].no_extension
=true;
449 #ifdef HAVE_LCD_BITMAP
450 static int add_plugin(char *plugin
, char *icon
)
452 static int add_plugin(char *plugin
)
462 /* starting now, Oct 2005, the plugins are given without extension in the
463 viewers.config file */
464 cp
=strrchr(plugin
, '.');
469 for (i
=first_soft_filetype
; i
< cnt_filetypes
; i
++)
471 if (filetypes
[i
].plugin
)
473 if (!strcasecmp(plugin
, filetypes
[i
].plugin
))
475 #ifdef HAVE_LCD_BITMAP
476 if (filetypes
[i
].icon
== NULL
&& icon
)
478 cp
= string2icon(icon
);
480 filetypes
[cnt_filetypes
].icon
= (unsigned char *)cp
;
491 cp
= get_string(plugin
);
494 filetypes
[cnt_filetypes
].plugin
= cp
;
495 #ifdef HAVE_LCD_BITMAP
499 cp
= string2icon(icon
);
501 filetypes
[cnt_filetypes
].icon
= (unsigned char *)cp
;
513 return cnt_filetypes
- 1;
516 /* read config file (or cahe file) */
517 bool read_config(const char* file
)
521 #ifdef HAVE_LCD_BITMAP
533 fd
= open(file
, O_RDONLY
);
537 while (read_line(fd
, buf
, sizeof(buf
)))
539 if (cnt_exttypes
>= MAX_EXTTYPES
)
541 gui_syncsplash(HZ
, true, str(LANG_FILETYPES_EXTENSION_FULL
));
545 if (cnt_filetypes
>= MAX_FILETYPES
)
547 gui_syncsplash(HZ
, true, str(LANG_FILETYPES_FULL
));
554 if (strlen(buf
) == 0)
560 memset(str
,0,sizeof(str
));
567 str
[i
] = strtok_r(cp
, ",", &end
);
570 while (end
&& i
< last
)
580 str
[i
] = strtok_r(NULL
, ",", &end
);
587 /* bail out if no icon and no plugin */
589 #ifdef HAVE_LCD_BITMAP
595 /* bail out if no plugin and icon is incorrect*/
597 #ifdef HAVE_LCD_BITMAP
598 && strlen(str
[icon
]) != ICON_LENGTH
*2
603 /* bail out if no icon and no plugin and no extension*/
605 #ifdef HAVE_LCD_BITMAP
611 /* bail out if we are not able to start plugin from onplay.c ?*/
614 if (strlen(str
[plugin
]) > MAX_PLUGIN_LENGTH
)
616 gui_syncsplash(HZ
, true, str(LANG_FILETYPES_PLUGIN_NAME_LONG
));
623 /* if extension already exist don't add a new one */
624 for (i
=0; i
< cnt_exttypes
; i
++)
626 if (!strcasecmp(str
[extension
],exttypes
[i
].extension
))
628 #ifdef HAVE_LCD_BITMAP
629 ix
=add_plugin(str
[plugin
],NULL
);
632 if (str
[icon
] && filetypes
[ix
].icon
== NULL
)
634 if (exttypes
[i
].type
->icon
== NULL
)
636 cp
= string2icon(str
[icon
]);
638 exttypes
[i
].type
->icon
= (unsigned char *)cp
;
643 ix
=add_plugin(str
[plugin
]);
645 if (exttypes
[i
].type
== NULL
)
647 exttypes
[i
].type
= &filetypes
[ix
];
658 #ifdef HAVE_LCD_BITMAP
659 ix
=add_plugin(str
[plugin
],str
[icon
]);
661 ix
=add_plugin(str
[plugin
]);
665 cp
=get_string(str
[extension
]);
668 exttypes
[cnt_exttypes
].extension
= cp
;
670 exttypes
[cnt_exttypes
].type
= &filetypes
[ix
];
672 filetypes
[i
].no_extension
=false;
686 #ifdef HAVE_LCD_BITMAP
687 ix
=add_plugin(str
[plugin
],str
[icon
]);
689 ix
=add_plugin(str
[plugin
]);
691 filetypes
[ix
].no_extension
=true;
701 #ifdef HAVE_LCD_BITMAP
702 /* convert an ascii hexadecimal icon to a binary icon */
703 static char* string2icon(const char* str
)
705 char tmp
[ICON_LENGTH
*2];
709 if (strlen(str
)!=ICON_LENGTH
*2)
712 if ((sizeof(string_buffer
) +
713 (unsigned long) string_buffer
-
714 (unsigned long) next_free_string
) < ICON_LENGTH
)
716 gui_syncsplash(HZ
, true, str(LANG_FILETYPES_STRING_BUFFER_EMPTY
));
722 if (str
[i
] >= '0' && str
[i
] <= '9')
728 if (str
[i
] >= 'a' && str
[i
] <= 'f')
730 tmp
[i
]=str
[i
]-'a'+10;
734 if (str
[i
] >= 'A' && str
[i
] <= 'F')
736 tmp
[i
]=str
[i
]-'A'+10;
744 for (i
= 0; i
< ICON_LENGTH
; i
++)
745 cp
[i
]=((tmp
[i
*2]<<4) | tmp
[i
*2+1]);
747 next_free_string
=&next_free_string
[ICON_LENGTH
];
752 /* get string from buffer */
753 static char* get_string(const char* str
)
755 unsigned int l
=strlen(str
)+1;
761 if (l
<= (sizeof(string_buffer
) +
762 (unsigned long) string_buffer
-
763 (unsigned long) next_free_string
))
765 strcpy(next_free_string
, str
);
767 next_free_string
=&next_free_string
[l
];
772 gui_syncsplash(HZ
, true, str(LANG_FILETYPES_STRING_BUFFER_EMPTY
));
777 /* remove all white spaces from string */
778 static void rm_whitespaces(char* str
)
785 while (cp
< &str
[strlen(str
)])