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 #define MAX_FILETYPES 32
45 /* max exttypes (extensions stored here) */
46 #define MAX_EXTTYPES 32
48 /* string buffer length */
49 #define STRING_BUFFER_SIZE 512
51 /* number of bytes for the binary icon */
54 /* mask for dynamic filetype info in attribute */
55 #define FILETYPES_MASK 0xFF00
58 #define ROCK_EXTENSION ".rock"
59 #define VIEWERS_CONFIG ROCKBOX_DIR "/viewers.config"
60 #define VIEWERS_DIR ROCKBOX_DIR "/viewers"
62 /* global variables */
63 static int cnt_filetypes
;
64 static int cnt_exttypes
;
65 static struct ext_type exttypes
[MAX_EXTTYPES
];
66 static struct file_type filetypes
[MAX_FILETYPES
];
67 static int first_soft_exttype
;
68 static int first_soft_filetype
;
69 static char* next_free_string
;
70 static char plugin_name
[sizeof(VIEWERS_DIR
) + 7 + MAX_PLUGIN_LENGTH
];
71 static char string_buffer
[STRING_BUFFER_SIZE
];
74 #ifdef HAVE_LCD_BITMAP
75 static char* string2icon(const char*);
76 static int add_plugin(char*,char*);
78 static int add_plugin(char*);
80 static char* get_string(const char*);
81 static int find_attr_index(int);
82 static bool read_config(const char*);
83 static void rm_whitespaces(char*);
84 static void scan_plugins(void);
86 /* initialize dynamic filetypes (called at boot from tree.c) */
87 void filetype_init(void)
90 const struct filetype
* ftypes
;
92 memset(exttypes
,0,sizeof(exttypes
));
93 memset(filetypes
,0,sizeof(filetypes
));
94 next_free_string
=string_buffer
;
96 /* The special filetype folder must always be stored at index 0 */
97 #ifdef HAVE_LCD_BITMAP
98 if (!filetypes
[0].icon
)
99 filetypes
[0].icon
= bitmap_icons_6x8
[Folder
];
101 if (!filetypes
[0].icon
)
102 filetypes
[0].icon
= Folder
;
103 for (i
=1; i
< MAX_FILETYPES
; i
++)
104 filetypes
[i
].icon
= -1;
107 /* register hardcoded filetypes */
108 tree_get_filetypes(&ftypes
, &cnt
);
112 for (i
= 0; i
< cnt
; i
++)
114 ix
= ((ftypes
[i
].tree_attr
& FILETYPES_MASK
) >> 8);
115 if (ix
< MAX_FILETYPES
&& i
< MAX_EXTTYPES
)
117 #ifdef HAVE_LCD_BITMAP
118 if (filetypes
[ix
].icon
== NULL
)
119 filetypes
[ix
].icon
=bitmap_icons_6x8
[ftypes
[i
].icon
];
121 if (filetypes
[ix
].icon
== -1)
122 filetypes
[ix
].icon
=ftypes
[i
].icon
;
124 if (ix
> cnt_filetypes
)
126 exttypes
[cnt_exttypes
].type
=&filetypes
[ix
];
127 exttypes
[cnt_exttypes
].extension
=ftypes
[i
].extension
;
131 first_soft_exttype
=cnt_exttypes
;
133 first_soft_filetype
=cnt_filetypes
;
135 /* register dynamic filetypes */
136 read_config(VIEWERS_CONFIG
);
141 #ifdef HAVE_LCD_BITMAP
142 const char* filetype_get_icon(int attr
)
144 int filetype_get_icon(int attr
)
149 ix
= find_attr_index(attr
);
153 #ifdef HAVE_LCD_BITMAP
161 return filetypes
[ix
].icon
;
166 char* filetype_get_plugin(const struct entry
* file
)
170 ix
=find_attr_index(file
->attr
);
177 if ((filetypes
[ix
].plugin
== NULL
) ||
178 (strlen(filetypes
[ix
].plugin
) > MAX_PLUGIN_LENGTH
))
181 snprintf(plugin_name
, sizeof(plugin_name
),
182 VIEWERS_DIR
"/%s.rock",filetypes
[ix
].plugin
);
187 /* check if filetype is supported */
188 bool filetype_supported(int attr
)
192 ix
=find_attr_index(attr
);
194 /* hard filetypes and soft filetypes with plugins is supported */
196 if (filetypes
[ix
].plugin
|| ix
< first_soft_filetype
)
202 /* get the "dynamic" attribute for an extension */
203 int filetype_get_attr(const char* name
)
207 for (i
=0; i
< cnt_exttypes
; i
++)
209 if (exttypes
[i
].extension
)
211 if (!strcasecmp(&name
[strlen(name
)-
212 strlen(exttypes
[i
].extension
)],
213 exttypes
[i
].extension
))
215 return ((((unsigned long)exttypes
[i
].type
-
216 (unsigned long)&filetypes
[0]) /
217 sizeof(struct file_type
)) << 8);
225 /* fill a menu list with viewers (used in onplay.c) */
226 int filetype_load_menu(struct menu_item
* menu
,int max_items
)
231 for (i
=0; i
< cnt_filetypes
; i
++)
233 if (filetypes
[i
].plugin
)
235 menu
[cnt
].desc
= filetypes
[i
].plugin
;
237 if (cnt
== max_items
)
244 /* start a plugin with an argument (called from onplay.c) */
245 int filetype_load_plugin(const char* plugin
, char* file
)
247 snprintf(plugin_name
,sizeof(plugin_name
),"%s/%s.rock",
249 return plugin_load(plugin_name
,file
);
252 /* get index to filetypes[] from the file attribute */
253 static int find_attr_index(int attr
)
256 ix
= ((attr
& FILETYPES_MASK
) >> 8);
258 if ((attr
& ATTR_DIRECTORY
)==ATTR_DIRECTORY
)
266 if (ix
> cnt_filetypes
)
269 if ((filetypes
[ix
].plugin
== NULL
) &&
270 #ifdef HAVE_LCD_BITMAP
271 (filetypes
[ix
].icon
== NULL
)
273 (filetypes
[ix
].icon
== -1)
282 /* scan the plugin directory and register filetypes */
283 static void scan_plugins(void)
286 struct dirent
*entry
;
294 dir
= opendir(VIEWERS_DIR
);
300 /* exttypes[] full, bail out */
301 if (cnt_exttypes
>= MAX_EXTTYPES
)
303 splash(HZ
,true,str(LANG_FILETYPES_EXTENSION_FULL
));
307 /* filetypes[] full, bail out */
308 if (cnt_filetypes
>= MAX_FILETYPES
)
310 splash(HZ
,true,str(LANG_FILETYPES_FULL
));
314 entry
= readdir(dir
);
319 /* skip directories */
320 if ((entry
->attribute
& ATTR_DIRECTORY
))
323 /* Skip FAT volume ID */
324 if (entry
->attribute
& ATTR_VOLUME_ID
)
327 /* filter out dotfiles and hidden files */
328 if ((entry
->d_name
[0]=='.') ||
329 (entry
->attribute
& ATTR_HIDDEN
)) {
333 /* filter out non rock files */
335 &entry
->d_name
[strlen(entry
->d_name
) - sizeof(ROCK_EXTENSION
) + 1],
340 /* filter out to long filenames */
341 if (strlen(entry
->d_name
) > MAX_PLUGIN_LENGTH
+ 5)
343 splash(HZ
,true,str(LANG_FILETYPES_PLUGIN_NAME_LONG
));
347 dot
=strrchr(entry
->d_name
,'.');
349 dash
=strchr(entry
->d_name
,'-');
351 /* add plugin and extension */
355 ix
=(filetype_get_attr(entry
->d_name
) >> 8);
358 cp
=get_string(entry
->d_name
);
361 exttypes
[cnt_exttypes
].extension
=cp
;
362 exttypes
[cnt_exttypes
].type
=&filetypes
[cnt_filetypes
];
363 #ifdef HAVE_LCD_BITMAP
364 exttypes
[cnt_exttypes
].type
->icon
= bitmap_icons_6x8
[Plugin
];
366 exttypes
[cnt_exttypes
].type
->icon
= Plugin
;
371 cp
=get_string(entry
->d_name
);
374 filetypes
[cnt_filetypes
].plugin
=cp
;
386 if (!filetypes
[ix
].plugin
)
388 cp
=get_string(entry
->d_name
);
391 filetypes
[cnt_filetypes
].plugin
=cp
;
400 /* add plugin only */
404 for (i
= first_soft_filetype
; i
< cnt_filetypes
; i
++)
406 if (filetypes
[i
].plugin
)
407 if (!strcasecmp(filetypes
[i
].plugin
,entry
->d_name
))
416 cp
=get_string(entry
->d_name
);
419 filetypes
[cnt_filetypes
].plugin
=cp
;
420 filetypes
[cnt_filetypes
].no_extension
=true;
432 #ifdef HAVE_LCD_BITMAP
433 static int add_plugin(char *plugin
, char *icon
)
435 static int add_plugin(char *plugin
)
444 cp
=strrchr(plugin
, '.');
448 for (i
=first_soft_filetype
; i
< cnt_filetypes
; i
++)
450 if (filetypes
[i
].plugin
)
452 if (!strcasecmp(plugin
, filetypes
[i
].plugin
))
454 #ifdef HAVE_LCD_BITMAP
455 if (filetypes
[i
].icon
== NULL
&& icon
)
457 cp
= string2icon(icon
);
459 filetypes
[cnt_filetypes
].icon
= cp
;
470 cp
= get_string(plugin
);
473 filetypes
[cnt_filetypes
].plugin
= cp
;
474 #ifdef HAVE_LCD_BITMAP
478 cp
= string2icon(icon
);
480 filetypes
[cnt_filetypes
].icon
= cp
;
492 return cnt_filetypes
- 1;
495 /* read config file (or cahe file) */
496 bool read_config(const char* file
)
500 #ifdef HAVE_LCD_BITMAP
512 fd
= open(file
, O_RDONLY
);
516 while (read_line(fd
, buf
, sizeof(buf
)))
518 if (cnt_exttypes
>= MAX_EXTTYPES
)
520 splash(HZ
,true,str(LANG_FILETYPES_EXTENSION_FULL
));
524 if (cnt_filetypes
>= MAX_FILETYPES
)
526 splash(HZ
,true,str(LANG_FILETYPES_FULL
));
533 if (strlen(buf
) == 0)
539 memset(str
,0,sizeof(str
));
546 str
[i
] = strtok_r(cp
, ",", &end
);
549 while (end
&& i
< last
)
559 str
[i
] = strtok_r(NULL
, ",", &end
);
566 /* bail out if no icon and no plugin */
568 #ifdef HAVE_LCD_BITMAP
574 /* bail out if no plugin and icon is incorrect*/
576 #ifdef HAVE_LCD_BITMAP
577 && strlen(str
[icon
]) != ICON_LENGTH
*2
582 /* bail out if no icon and no plugin and no extension*/
584 #ifdef HAVE_LCD_BITMAP
590 /* bail out if we are not able to start plugin from onplay.c ?*/
593 if (strlen(str
[plugin
]) > MAX_PLUGIN_LENGTH
)
595 splash(HZ
, true, str(LANG_FILETYPES_PLUGIN_NAME_LONG
));
602 /* if extension already exist don't add a new one */
603 for (i
=0; i
< cnt_exttypes
; i
++)
605 if (!strcasecmp(str
[extension
],exttypes
[i
].extension
))
607 #ifdef HAVE_LCD_BITMAP
608 ix
=add_plugin(str
[plugin
],NULL
);
611 if (str
[icon
] && filetypes
[ix
].icon
== NULL
)
613 if (exttypes
[i
].type
->icon
== NULL
)
615 cp
= string2icon(str
[icon
]);
617 exttypes
[i
].type
->icon
= cp
;
622 ix
=add_plugin(str
[plugin
]);
624 if (exttypes
[i
].type
== NULL
)
626 exttypes
[i
].type
= &filetypes
[ix
];
637 #ifdef HAVE_LCD_BITMAP
638 ix
=add_plugin(str
[plugin
],str
[icon
]);
640 ix
=add_plugin(str
[plugin
]);
644 cp
=get_string(str
[extension
]);
647 exttypes
[cnt_exttypes
].extension
= cp
;
649 exttypes
[cnt_exttypes
].type
= &filetypes
[ix
];
651 filetypes
[i
].no_extension
=false;
665 #ifdef HAVE_LCD_BITMAP
666 ix
=add_plugin(str
[plugin
],str
[icon
]);
668 ix
=add_plugin(str
[plugin
]);
670 filetypes
[ix
].no_extension
=true;
680 #ifdef HAVE_LCD_BITMAP
681 /* convert an ascii hexadecimal icon to a binary icon */
682 static char* string2icon(const char* str
)
684 char tmp
[ICON_LENGTH
*2];
688 if (strlen(str
)!=ICON_LENGTH
*2)
691 if ((sizeof(string_buffer
) +
692 (unsigned long) string_buffer
-
693 (unsigned long) next_free_string
) < ICON_LENGTH
)
695 splash(HZ
,true,str(LANG_FILETYPES_STRING_BUFFER_EMPTY
));
701 if (str
[i
] >= '0' && str
[i
] <= '9')
707 if (str
[i
] >= 'a' && str
[i
] <= 'f')
709 tmp
[i
]=str
[i
]-'a'+10;
713 if (str
[i
] >= 'A' && str
[i
] <= 'F')
715 tmp
[i
]=str
[i
]-'A'+10;
723 for (i
= 0; i
< ICON_LENGTH
; i
++)
724 cp
[i
]=((tmp
[i
*2]<<4) | tmp
[i
*2+1]);
726 next_free_string
=&next_free_string
[ICON_LENGTH
];
731 /* get string from buffer */
732 static char* get_string(const char* str
)
734 unsigned int l
=strlen(str
)+1;
740 if (l
<= (sizeof(string_buffer
) +
741 (unsigned long) string_buffer
-
742 (unsigned long) next_free_string
))
744 strcpy(next_free_string
,str
);
746 next_free_string
=&next_free_string
[l
];
751 splash(HZ
,true,str(LANG_FILETYPES_STRING_BUFFER_EMPTY
));
756 /* remove all white spaces from string */
757 static void rm_whitespaces(char* str
)
764 while (cp
< &str
[strlen(str
)])