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 256
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*);
77 static char* get_string(const char*);
78 static int find_attr_index(int);
79 static bool read_config(const char*);
80 static void rm_whitespaces(char*);
81 static void scan_plugins(void);
83 /* initialize dynamic filetypes (called at boot from tree.c) */
84 void filetype_init(void)
87 const struct filetype
* ftypes
;
89 memset(exttypes
,0,sizeof(exttypes
));
90 memset(filetypes
,0,sizeof(filetypes
));
91 next_free_string
=string_buffer
;
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
];
98 if (!filetypes
[0].icon
)
99 filetypes
[0].icon
= Folder
;
100 for (i
=1; i
< MAX_FILETYPES
; i
++)
101 filetypes
[i
].icon
= -1;
104 /* register hardcoded filetypes */
105 tree_get_filetypes(&ftypes
, &cnt
);
109 for (i
= 0; i
< cnt
; i
++)
111 ix
= ((ftypes
[i
].tree_attr
& FILETYPES_MASK
) >> 8);
112 if (ix
< MAX_FILETYPES
&& i
< MAX_EXTTYPES
)
114 #ifdef HAVE_LCD_BITMAP
115 if (filetypes
[ix
].icon
== NULL
)
116 filetypes
[ix
].icon
=bitmap_icons_6x8
[ftypes
[i
].icon
];
118 if (filetypes
[ix
].icon
== -1)
119 filetypes
[ix
].icon
=ftypes
[i
].icon
;
121 if (ix
> cnt_filetypes
)
123 exttypes
[cnt_exttypes
].type
=&filetypes
[ix
];
124 exttypes
[cnt_exttypes
].extension
=ftypes
[i
].extension
;
128 first_soft_exttype
=cnt_exttypes
;
130 first_soft_filetype
=cnt_filetypes
;
132 /* register dynamic filetypes */
133 read_config(VIEWERS_CONFIG
);
138 #ifdef HAVE_LCD_BITMAP
139 const char* filetype_get_icon(int attr
)
141 int filetype_get_icon(int attr
)
146 ix
= find_attr_index(attr
);
150 #ifdef HAVE_LCD_BITMAP
158 return filetypes
[ix
].icon
;
163 char* filetype_get_plugin(const struct entry
* file
)
167 ix
=find_attr_index(file
->attr
);
174 if ((filetypes
[ix
].plugin
== NULL
) ||
175 (strlen(filetypes
[ix
].plugin
) > MAX_PLUGIN_LENGTH
))
178 snprintf(plugin_name
, sizeof(plugin_name
),
179 VIEWERS_DIR
"/%s.rock",filetypes
[ix
].plugin
);
184 /* check if filetype is supported */
185 bool filetype_supported(int attr
)
189 ix
=find_attr_index(attr
);
191 /* hard filetypes and soft filetypes with plugins is supported */
193 if (filetypes
[ix
].plugin
|| ix
< first_soft_filetype
)
199 /* get the "dynamic" attribute for an extension */
200 int filetype_get_attr(const char* name
)
204 for (i
=0; i
< cnt_exttypes
; i
++)
206 if (exttypes
[i
].extension
)
208 if (!strcasecmp(&name
[strlen(name
)-
209 strlen(exttypes
[i
].extension
)],
210 exttypes
[i
].extension
))
212 return ((((unsigned int)exttypes
[i
].type
-
213 (unsigned int)&filetypes
[0]) /
214 sizeof(struct file_type
)) << 8);
222 /* fill a menu list with viewers (used in onplay.c) */
223 int filetype_load_menu(struct menu_item
* menu
,int max_items
)
228 for (i
=0; i
< cnt_filetypes
; i
++)
230 if (filetypes
[i
].plugin
)
232 menu
[cnt
].desc
= filetypes
[i
].plugin
;
234 if (cnt
== max_items
)
241 /* start a plugin with an argument (called from onplay.c) */
242 int filetype_load_plugin(const char* plugin
, char* file
)
244 snprintf(plugin_name
,sizeof(plugin_name
),"%s/%s.rock",
246 return plugin_load(plugin_name
,file
);
249 /* get index to filetypes[] from the file attribute */
250 static int find_attr_index(int attr
)
253 ix
= ((attr
& FILETYPES_MASK
) >> 8);
255 if ((attr
& ATTR_DIRECTORY
)==ATTR_DIRECTORY
)
263 if (ix
> cnt_filetypes
)
266 if ((filetypes
[ix
].plugin
== NULL
) &&
267 #ifdef HAVE_LCD_BITMAP
268 (filetypes
[ix
].icon
== NULL
)
270 (filetypes
[ix
].icon
== -1)
279 /* scan the plugin directory and register filetypes */
280 static void scan_plugins(void)
283 struct dirent
*entry
;
291 dir
= opendir(VIEWERS_DIR
);
297 /* exttypes[] full, bail out */
298 if (cnt_exttypes
>= MAX_EXTTYPES
)
300 splash(HZ
,true,str(LANG_FILETYPES_EXTENSION_FULL
));
304 /* filetypes[] full, bail out */
305 if (cnt_filetypes
>= MAX_FILETYPES
)
307 splash(HZ
,true,str(LANG_FILETYPES_FULL
));
311 entry
= readdir(dir
);
316 /* skip directories */
317 if ((entry
->attribute
& ATTR_DIRECTORY
))
320 /* Skip FAT volume ID */
321 if (entry
->attribute
& ATTR_VOLUME_ID
)
324 /* filter out dotfiles and hidden files */
325 if ((entry
->d_name
[0]=='.') ||
326 (entry
->attribute
& ATTR_HIDDEN
)) {
330 /* filter out non rock files */
332 &entry
->d_name
[strlen(entry
->d_name
) - sizeof(ROCK_EXTENSION
) + 1],
337 /* filter out to long filenames */
338 if (strlen(entry
->d_name
) > MAX_PLUGIN_LENGTH
+ 5)
340 splash(HZ
,true,str(LANG_FILETYPES_PLUGIN_NAME_LONG
));
344 dot
=strrchr(entry
->d_name
,'.');
346 dash
=strchr(entry
->d_name
,'-');
348 /* add plugin and extension */
352 ix
=(filetype_get_attr(entry
->d_name
) >> 8);
355 cp
=get_string(entry
->d_name
);
358 exttypes
[cnt_exttypes
].extension
=cp
;
359 exttypes
[cnt_exttypes
].type
=&filetypes
[cnt_filetypes
];
360 #ifdef HAVE_LCD_BITMAP
361 exttypes
[cnt_exttypes
].type
->icon
= bitmap_icons_6x8
[Plugin
];
363 exttypes
[cnt_exttypes
].type
->icon
= Plugin
;
368 cp
=get_string(entry
->d_name
);
371 filetypes
[cnt_filetypes
].plugin
=cp
;
383 if (!filetypes
[ix
].plugin
)
385 cp
=get_string(entry
->d_name
);
388 filetypes
[cnt_filetypes
].plugin
=cp
;
397 /* add plugin only */
401 for (i
= first_soft_filetype
; i
< cnt_filetypes
; i
++)
403 if (filetypes
[i
].plugin
)
404 if (!strcasecmp(filetypes
[i
].plugin
,entry
->d_name
))
413 cp
=get_string(entry
->d_name
);
416 filetypes
[cnt_filetypes
].plugin
=cp
;
417 filetypes
[cnt_filetypes
].no_extension
=true;
429 /* read config file (or cahe file) */
430 bool read_config(const char* file
)
434 #ifdef HAVE_LCD_BITMAP
446 fd
= open(file
, O_RDONLY
);
450 while (read_line(fd
, buf
, sizeof(buf
)))
452 if (cnt_exttypes
>= MAX_EXTTYPES
)
454 splash(HZ
,true,str(LANG_FILETYPES_EXTENSION_FULL
));
458 if (cnt_filetypes
>= MAX_FILETYPES
)
460 splash(HZ
,true,str(LANG_FILETYPES_FULL
));
467 if (strlen(buf
) == 0)
473 memset(str
,0,sizeof(str
));
480 str
[i
] = strtok_r(cp
, ",", &end
);
483 while (end
&& i
< last
)
493 str
[i
] = strtok_r(NULL
, ",", &end
);
497 /* bail out if no icon and no plugin */
498 if ((!str
[plugin
] || !strlen(str
[plugin
])) &&
499 #ifdef HAVE_LCD_BITMAP
500 (!str
[icon
] || !strlen(str
[icon
])) &&
502 strlen(str
[extension
]))
505 /* bail out if no plugin and icon is incorrect*/
506 if ((!str
[plugin
] || !strlen(str
[plugin
])) &&
507 #ifdef HAVE_LCD_BITMAP
508 (strlen(str
[icon
]) != ICON_LENGTH
*2) &&
510 strlen(str
[extension
]))
513 /* bail out if no icon and no plugin and no extension*/
514 if ((!str
[plugin
] || !strlen(str
[plugin
])) &&
515 #ifdef HAVE_LCD_BITMAP
516 (!str
[icon
] || !strlen(str
[icon
])) &&
518 (!str
[extension
] || !strlen(str
[extension
])))
524 if (strlen(str
[extension
]))
526 cp
=get_string(str
[extension
]);
529 exttypes
[cnt_exttypes
].type
= &filetypes
[cnt_filetypes
];
530 exttypes
[cnt_exttypes
].extension
= cp
;
536 #ifdef HAVE_LCD_BITMAP
540 cp
= string2icon(str
[icon
]);
542 filetypes
[cnt_filetypes
].icon
= cp
;
550 /* are we able to start plugin from onplay.c ?*/
553 if (strlen(str
[plugin
]) > MAX_PLUGIN_LENGTH
)
555 splash(HZ
, true, str(LANG_FILETYPES_PLUGIN_NAME_LONG
));
563 if (strlen(str
[plugin
]))
565 cp
=strrchr(str
[plugin
], '.');
569 cp
= get_string(str
[plugin
]);
571 filetypes
[cnt_filetypes
].plugin
= cp
;
577 if (filetypes
[cnt_filetypes
].plugin
)
585 #ifdef HAVE_LCD_BITMAP
586 /* convert an ascii hexadecimal icon to a binary icon */
587 static char* string2icon(const char* str
)
589 char tmp
[ICON_LENGTH
*2];
593 if (strlen(str
)!=ICON_LENGTH
*2)
596 if ((sizeof(string_buffer
) +
597 (unsigned int) string_buffer
-
598 (unsigned int) next_free_string
) < ICON_LENGTH
)
600 splash(HZ
,true,str(LANG_FILETYPES_STRING_BUFFER_EMPTY
));
606 if (str
[i
] >= '0' && str
[i
] <= '9')
612 if (str
[i
] >= 'a' && str
[i
] <= 'f')
614 tmp
[i
]=str
[i
]-'a'+10;
618 if (str
[i
] >= 'A' && str
[i
] <= 'F')
620 tmp
[i
]=str
[i
]-'A'+10;
628 for (i
= 0; i
< ICON_LENGTH
; i
++)
629 cp
[i
]=((tmp
[i
*2]<<4) | tmp
[i
*2+1]);
631 next_free_string
=&next_free_string
[ICON_LENGTH
];
636 /* get string from buffer */
637 static char* get_string(const char* str
)
639 unsigned int l
=strlen(str
)+1;
645 if (l
<= (sizeof(string_buffer
) +
646 (unsigned int) string_buffer
-
647 (unsigned int) next_free_string
))
649 strcpy(next_free_string
,str
);
651 next_free_string
=&next_free_string
[l
];
656 splash(HZ
,true,str(LANG_FILETYPES_STRING_BUFFER_EMPTY
));
661 /* remove all white spaces from string */
662 static void rm_whitespaces(char* str
)
669 while (cp
< &str
[strlen(str
)])