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"
39 /* max plugin name size without extensions and path */
40 #define MAX_PLUGIN_LENGTH 32
42 /* max filetypes (plugins & icons stored here) */
43 #if CONFIG_CODEC == SWCODEC
44 #define MAX_FILETYPES 64
46 #define MAX_FILETYPES 32
49 /* max exttypes (extensions stored here) */
50 #if CONFIG_CODEC == SWCODEC
51 /* Software codecs require more file extensions */
52 #define MAX_EXTTYPES 64
54 #define MAX_EXTTYPES 32
57 /* string buffer length */
58 #define STRING_BUFFER_SIZE 512
60 /* number of bytes for the binary icon */
63 /* mask for dynamic filetype info in attribute */
64 #define FILETYPES_MASK 0xFF00
67 #define ROCK_EXTENSION ".rock"
68 #define VIEWERS_CONFIG ROCKBOX_DIR "/viewers.config"
69 #define VIEWERS_DIR ROCKBOX_DIR "/viewers"
71 /* global variables */
72 static int cnt_filetypes
;
73 static int cnt_exttypes
;
74 static struct ext_type exttypes
[MAX_EXTTYPES
];
75 static struct file_type filetypes
[MAX_FILETYPES
];
76 static int first_soft_exttype
;
77 static int first_soft_filetype
;
78 static char* next_free_string
;
79 static char plugin_name
[sizeof(VIEWERS_DIR
) + 7 + MAX_PLUGIN_LENGTH
];
80 static char string_buffer
[STRING_BUFFER_SIZE
];
83 #ifdef HAVE_LCD_BITMAP
84 static char* string2icon(const char*);
85 static int add_plugin(char*,char*);
87 static int add_plugin(char*);
89 static char* get_string(const char*);
90 static int find_attr_index(int);
91 static bool read_config(const char*);
92 static void rm_whitespaces(char*);
93 static void scan_plugins(void);
95 /* initialize dynamic filetypes (called at boot from tree.c) */
96 void filetype_init(void)
99 const struct filetype
* ftypes
;
101 memset(exttypes
,0,sizeof(exttypes
));
102 memset(filetypes
,0,sizeof(filetypes
));
103 next_free_string
=string_buffer
;
105 /* The special filetype folder must always be stored at index 0 */
106 #ifdef HAVE_LCD_BITMAP
107 if (!filetypes
[0].icon
)
108 filetypes
[0].icon
= bitmap_icons_6x8
[Icon_Folder
];
110 if (!filetypes
[0].icon
)
111 filetypes
[0].icon
= Icon_Folder
;
112 for (i
=1; i
< MAX_FILETYPES
; i
++)
113 filetypes
[i
].icon
= -1;
116 /* register hardcoded filetypes */
117 tree_get_filetypes(&ftypes
, &cnt
);
121 for (i
= 0; i
< cnt
; i
++)
123 ix
= ((ftypes
[i
].tree_attr
& FILETYPES_MASK
) >> 8);
124 if (ix
< MAX_FILETYPES
&& i
< MAX_EXTTYPES
)
126 #ifdef HAVE_LCD_BITMAP
127 if (filetypes
[ix
].icon
== NULL
)
128 filetypes
[ix
].icon
=bitmap_icons_6x8
[ftypes
[i
].icon
];
130 if (filetypes
[ix
].icon
== -1)
131 filetypes
[ix
].icon
=ftypes
[i
].icon
;
133 if (ix
> cnt_filetypes
)
135 exttypes
[cnt_exttypes
].type
=&filetypes
[ix
];
136 exttypes
[cnt_exttypes
].extension
=ftypes
[i
].extension
;
140 first_soft_exttype
=cnt_exttypes
;
142 first_soft_filetype
=cnt_filetypes
;
144 /* register dynamic filetypes */
145 read_config(VIEWERS_CONFIG
);
150 #ifdef HAVE_LCD_BITMAP
151 const char* filetype_get_icon(int attr
)
153 int filetype_get_icon(int attr
)
158 ix
= find_attr_index(attr
);
162 #ifdef HAVE_LCD_BITMAP
170 return filetypes
[ix
].icon
;
175 char* filetype_get_plugin(const struct entry
* file
)
179 ix
=find_attr_index(file
->attr
);
186 if ((filetypes
[ix
].plugin
== NULL
) ||
187 (strlen(filetypes
[ix
].plugin
) > MAX_PLUGIN_LENGTH
))
190 snprintf(plugin_name
, sizeof(plugin_name
),
191 "%s/%s.rock", ROCKBOX_DIR
, filetypes
[ix
].plugin
);
196 /* check if filetype is supported */
197 bool filetype_supported(int attr
)
201 ix
=find_attr_index(attr
);
203 /* hard filetypes and soft filetypes with plugins is supported */
205 if (filetypes
[ix
].plugin
|| ix
< first_soft_filetype
)
211 /* get the "dynamic" attribute for an extension */
212 int filetype_get_attr(const char* name
)
215 const char *cp
= strrchr(name
,'.');
217 if (!cp
) /* no extension? -> can't be a supported type */
221 for (i
=0; i
< cnt_exttypes
; i
++)
223 if (exttypes
[i
].extension
)
225 if (!strcasecmp(cp
,exttypes
[i
].extension
))
227 return ((((unsigned long)exttypes
[i
].type
-
228 (unsigned long)&filetypes
[0]) /
229 sizeof(struct file_type
)) << 8);
237 /* fill a menu list with viewers (used in onplay.c) */
238 int filetype_load_menu(struct menu_item
* menu
,int max_items
)
244 for (i
=0; i
< cnt_filetypes
; i
++)
246 if (filetypes
[i
].plugin
)
248 cp
=strrchr(filetypes
[i
].plugin
,'/');
250 else cp
=filetypes
[i
].plugin
;
253 if (cnt
== max_items
)
260 /* start a plugin with an argument (called from onplay.c) */
261 int filetype_load_plugin(const char* plugin
, char* file
)
263 snprintf(plugin_name
,sizeof(plugin_name
),"%s/%s.rock",
265 return plugin_load(plugin_name
,file
);
268 /* get index to filetypes[] from the file attribute */
269 static int find_attr_index(int attr
)
272 ix
= ((attr
& FILETYPES_MASK
) >> 8);
274 if ((attr
& ATTR_DIRECTORY
)==ATTR_DIRECTORY
)
282 if (ix
> cnt_filetypes
)
285 if ((filetypes
[ix
].plugin
== NULL
) &&
286 #ifdef HAVE_LCD_BITMAP
287 (filetypes
[ix
].icon
== NULL
)
289 (filetypes
[ix
].icon
== -1)
298 /* scan the plugin directory and register filetypes */
299 static void scan_plugins(void)
302 struct dirent
*entry
;
310 dir
= opendir(VIEWERS_DIR
);
316 /* exttypes[] full, bail out */
317 if (cnt_exttypes
>= MAX_EXTTYPES
)
319 splash(HZ
,true,str(LANG_FILETYPES_EXTENSION_FULL
));
323 /* filetypes[] full, bail out */
324 if (cnt_filetypes
>= MAX_FILETYPES
)
326 splash(HZ
,true,str(LANG_FILETYPES_FULL
));
330 entry
= readdir(dir
);
335 /* skip directories */
336 if ((entry
->attribute
& ATTR_DIRECTORY
))
339 /* Skip FAT volume ID */
340 if (entry
->attribute
& ATTR_VOLUME_ID
)
343 /* filter out dotfiles and hidden files */
344 if ((entry
->d_name
[0]=='.') ||
345 (entry
->attribute
& ATTR_HIDDEN
)) {
349 /* filter out non rock files */
351 &entry
->d_name
[strlen(entry
->d_name
) - sizeof(ROCK_EXTENSION
) + 1],
356 /* filter out to long filenames */
357 if (strlen(entry
->d_name
) > MAX_PLUGIN_LENGTH
+ 5)
359 splash(HZ
,true,str(LANG_FILETYPES_PLUGIN_NAME_LONG
));
363 dot
=strrchr(entry
->d_name
,'.');
365 dash
=strchr(entry
->d_name
,'-');
367 /* add plugin and extension */
371 ix
=(filetype_get_attr(entry
->d_name
) >> 8);
374 cp
=get_string(entry
->d_name
);
377 exttypes
[cnt_exttypes
].extension
=cp
;
378 exttypes
[cnt_exttypes
].type
=&filetypes
[cnt_filetypes
];
379 #ifdef HAVE_LCD_BITMAP
380 exttypes
[cnt_exttypes
].type
->icon
= bitmap_icons_6x8
[Icon_Plugin
];
382 exttypes
[cnt_exttypes
].type
->icon
= Icon_Plugin
;
387 cp
=get_string(entry
->d_name
);
390 filetypes
[cnt_filetypes
].plugin
=cp
;
402 if (!filetypes
[ix
].plugin
)
404 cp
=get_string(entry
->d_name
);
407 filetypes
[cnt_filetypes
].plugin
=cp
;
416 /* add plugin only */
420 for (i
= first_soft_filetype
; i
< cnt_filetypes
; i
++)
422 if (filetypes
[i
].plugin
)
423 if (!strcasecmp(filetypes
[i
].plugin
,entry
->d_name
))
432 cp
=get_string(entry
->d_name
);
435 filetypes
[cnt_filetypes
].plugin
=cp
;
436 filetypes
[cnt_filetypes
].no_extension
=true;
448 #ifdef HAVE_LCD_BITMAP
449 static int add_plugin(char *plugin
, char *icon
)
451 static int add_plugin(char *plugin
)
461 /* starting now, Oct 2005, the plugins are given without extension in the
462 viewers.config file */
463 cp
=strrchr(plugin
, '.');
468 for (i
=first_soft_filetype
; i
< cnt_filetypes
; i
++)
470 if (filetypes
[i
].plugin
)
472 if (!strcasecmp(plugin
, filetypes
[i
].plugin
))
474 #ifdef HAVE_LCD_BITMAP
475 if (filetypes
[i
].icon
== NULL
&& icon
)
477 cp
= string2icon(icon
);
479 filetypes
[cnt_filetypes
].icon
= cp
;
490 cp
= get_string(plugin
);
493 filetypes
[cnt_filetypes
].plugin
= cp
;
494 #ifdef HAVE_LCD_BITMAP
498 cp
= string2icon(icon
);
500 filetypes
[cnt_filetypes
].icon
= cp
;
512 return cnt_filetypes
- 1;
515 /* read config file (or cahe file) */
516 bool read_config(const char* file
)
520 #ifdef HAVE_LCD_BITMAP
532 fd
= open(file
, O_RDONLY
);
536 while (read_line(fd
, buf
, sizeof(buf
)))
538 if (cnt_exttypes
>= MAX_EXTTYPES
)
540 splash(HZ
,true,str(LANG_FILETYPES_EXTENSION_FULL
));
544 if (cnt_filetypes
>= MAX_FILETYPES
)
546 splash(HZ
,true,str(LANG_FILETYPES_FULL
));
553 if (strlen(buf
) == 0)
559 memset(str
,0,sizeof(str
));
566 str
[i
] = strtok_r(cp
, ",", &end
);
569 while (end
&& i
< last
)
579 str
[i
] = strtok_r(NULL
, ",", &end
);
586 /* bail out if no icon and no plugin */
588 #ifdef HAVE_LCD_BITMAP
594 /* bail out if no plugin and icon is incorrect*/
596 #ifdef HAVE_LCD_BITMAP
597 && strlen(str
[icon
]) != ICON_LENGTH
*2
602 /* bail out if no icon and no plugin and no extension*/
604 #ifdef HAVE_LCD_BITMAP
610 /* bail out if we are not able to start plugin from onplay.c ?*/
613 if (strlen(str
[plugin
]) > MAX_PLUGIN_LENGTH
)
615 splash(HZ
, true, str(LANG_FILETYPES_PLUGIN_NAME_LONG
));
622 /* if extension already exist don't add a new one */
623 for (i
=0; i
< cnt_exttypes
; i
++)
625 if (!strcasecmp(str
[extension
],exttypes
[i
].extension
))
627 #ifdef HAVE_LCD_BITMAP
628 ix
=add_plugin(str
[plugin
],NULL
);
631 if (str
[icon
] && filetypes
[ix
].icon
== NULL
)
633 if (exttypes
[i
].type
->icon
== NULL
)
635 cp
= string2icon(str
[icon
]);
637 exttypes
[i
].type
->icon
= cp
;
642 ix
=add_plugin(str
[plugin
]);
644 if (exttypes
[i
].type
== NULL
)
646 exttypes
[i
].type
= &filetypes
[ix
];
657 #ifdef HAVE_LCD_BITMAP
658 ix
=add_plugin(str
[plugin
],str
[icon
]);
660 ix
=add_plugin(str
[plugin
]);
664 cp
=get_string(str
[extension
]);
667 exttypes
[cnt_exttypes
].extension
= cp
;
669 exttypes
[cnt_exttypes
].type
= &filetypes
[ix
];
671 filetypes
[i
].no_extension
=false;
685 #ifdef HAVE_LCD_BITMAP
686 ix
=add_plugin(str
[plugin
],str
[icon
]);
688 ix
=add_plugin(str
[plugin
]);
690 filetypes
[ix
].no_extension
=true;
700 #ifdef HAVE_LCD_BITMAP
701 /* convert an ascii hexadecimal icon to a binary icon */
702 static char* string2icon(const char* str
)
704 char tmp
[ICON_LENGTH
*2];
708 if (strlen(str
)!=ICON_LENGTH
*2)
711 if ((sizeof(string_buffer
) +
712 (unsigned long) string_buffer
-
713 (unsigned long) next_free_string
) < ICON_LENGTH
)
715 splash(HZ
,true,str(LANG_FILETYPES_STRING_BUFFER_EMPTY
));
721 if (str
[i
] >= '0' && str
[i
] <= '9')
727 if (str
[i
] >= 'a' && str
[i
] <= 'f')
729 tmp
[i
]=str
[i
]-'a'+10;
733 if (str
[i
] >= 'A' && str
[i
] <= 'F')
735 tmp
[i
]=str
[i
]-'A'+10;
743 for (i
= 0; i
< ICON_LENGTH
; i
++)
744 cp
[i
]=((tmp
[i
*2]<<4) | tmp
[i
*2+1]);
746 next_free_string
=&next_free_string
[ICON_LENGTH
];
751 /* get string from buffer */
752 static char* get_string(const char* str
)
754 unsigned int l
=strlen(str
)+1;
760 if (l
<= (sizeof(string_buffer
) +
761 (unsigned long) string_buffer
-
762 (unsigned long) next_free_string
))
764 strcpy(next_free_string
,str
);
766 next_free_string
=&next_free_string
[l
];
771 splash(HZ
,true,str(LANG_FILETYPES_STRING_BUFFER_EMPTY
));
776 /* remove all white spaces from string */
777 static void rm_whitespaces(char* str
)
784 while (cp
< &str
[strlen(str
)])