Revert change 13001, since it causes the metadata to be re-read for partially buffere...
[kugel-rb.git] / apps / filetypes.c
blobca6578aa23605df0dd271307576792068d009405
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * $Id$
10 * Copyright (C) 2007 Jonathan Gordon
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 ****************************************************************************/
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <stdbool.h>
24 #include "string.h"
25 #include <ctype.h>
27 #include "sprintf.h"
28 #include "settings.h"
29 #include "debug.h"
30 #include "lang.h"
31 #include "language.h"
32 #include "kernel.h"
33 #include "plugin.h"
34 #include "filetypes.h"
35 #include "screens.h"
36 #include "icons.h"
37 #include "dir.h"
38 #include "file.h"
39 #include "icons.h"
40 #include "splash.h"
41 #include "buffer.h"
43 /* max filetypes (plugins & icons stored here) */
44 #if CONFIG_CODEC == SWCODEC
45 #define MAX_FILETYPES 72
46 #else
47 #define MAX_FILETYPES 48
48 #endif
50 /* number of bytes for the binary icon */
51 #define ICON_LENGTH 6
53 /* mask for dynamic filetype info in attribute */
54 #define FILETYPES_MASK 0xFF00
55 #define ROCK_EXTENSION "rock"
57 struct file_type {
58 ICON_NO_CONST icon; /* the icon which shall be used for it, NOICON if unknown */
59 bool viewer; /* true if the rock is in viewers, false if in rocks */
60 unsigned char attr; /* FILETYPES_MASK >> 8 */
61 char* plugin; /* Which plugin to use, NULL if unknown, or builtin */
62 char* extension; /* NULL for none */
64 static struct file_type filetypes[MAX_FILETYPES];
65 static int filetype_count = 0;
66 static unsigned char heighest_attr = 0;
68 static char *filetypes_strdup(char* string)
70 char *buffer = (char*)buffer_alloc(strlen(string)+1);
71 strcpy(buffer, string);
72 return buffer;
74 static void read_builtin_types(void);
75 static void read_config(char* config_file);
77 void filetype_init(void)
79 /* set the directory item first */
80 filetypes[0].extension = NULL;
81 filetypes[0].plugin = NULL;
82 filetypes[0].attr = 0;
83 filetypes[0].icon =
84 #ifdef HAVE_LCD_BITMAP
85 (ICON_NO_CONST)&bitmap_icons_6x8[Icon_Folder];
86 #else
87 (ICON_NO_CONST)Icon_Folder;
88 #endif
89 filetype_count = 1;
90 read_builtin_types();
91 read_config(VIEWERS_CONFIG);
94 /* remove all white spaces from string */
95 static void rm_whitespaces(char* str)
97 char *s = str;
98 while (*str)
100 if (!isspace(*str))
102 *s = *str;
103 s++;
105 str++;
107 *s = '\0';
110 static void read_builtin_types(void)
112 const struct filetype *types;
113 int count, i;
114 tree_get_filetypes(&types, &count);
115 for(i=0; i<count && (filetype_count < MAX_FILETYPES); i++)
117 filetypes[filetype_count].extension = types[i].extension;
118 filetypes[filetype_count].plugin = NULL;
119 filetypes[filetype_count].attr = types[i].tree_attr>>8;
120 if (filetypes[filetype_count].attr > heighest_attr)
121 heighest_attr = filetypes[filetype_count].attr;
122 filetypes[filetype_count].icon =
123 #ifdef HAVE_LCD_BITMAP
124 (ICON_NO_CONST)&bitmap_icons_6x8[types[i].icon];
125 #else
126 (ICON_NO_CONST)types[i].icon;
127 #endif
128 filetype_count++;
132 static void read_config(char* config_file)
134 char line[64], *s, *e;
135 char extension[8], plugin[32];
136 #ifdef HAVE_LCD_BITMAP
137 char icon[ICON_LENGTH];
138 int good_icon;
139 #endif
140 bool viewer;
141 int fd = open(config_file, O_RDONLY);
142 if (fd < 0)
143 return;
144 /* config file is in the for
145 <extension>,<plugin>,<icon code>
146 ignore line if either of the first two are missing */
147 while (read_line(fd, line, 64) > 0)
149 if (filetype_count >= MAX_FILETYPES)
151 gui_syncsplash(HZ, str(LANG_FILETYPES_FULL));
152 break;
154 rm_whitespaces(line);
155 /* get the extention */
156 s = line;
157 e = strchr(s, ',');
158 if (!e)
159 continue;
160 *e = '\0';
161 strcpy(extension, s);
163 /* get the plugin */
164 s = e+1;
165 e = strchr(s, '/');
166 if (!e)
167 continue;
168 *e = '\0';
169 if (!strcasecmp("viewers", s))
170 viewer = true;
171 else
172 viewer = false;
173 s = e+1;
174 e = strchr(s, ',');
175 if (!e)
176 continue;
177 *e = '\0';
178 strcpy(plugin, s);
179 /* ok, store this plugin/extension, check icon after */
180 filetypes[filetype_count].extension = filetypes_strdup(extension);
181 filetypes[filetype_count].plugin = filetypes_strdup(plugin);
182 filetypes[filetype_count].viewer = viewer;
183 filetypes[filetype_count].attr = heighest_attr +1;
184 heighest_attr++;
185 /* get the icon */
186 #ifdef HAVE_LCD_BITMAP
187 s = e+1;
188 good_icon = 1;
189 if (strlen(s) == 12)
191 int i, j;
192 char val[2];
193 for (i = 0; good_icon && i < ICON_LENGTH; i++)
195 for (j=0; good_icon && j<2; j++)
197 val[j] = tolower(s[i*2+j]);
198 if (val[j] >= 'a' && val[j] <= 'f')
200 val[j] = val[j] - 'a' + 10;
202 else if (val[j] >= '0' && val[j] <= '9')
204 val[j] = val[j] - '0';
206 else
207 good_icon = 0;
209 icon[i]=((val[0]<<4) | val[1]);
212 if (good_icon)
214 filetypes[filetype_count].icon =
215 (ICON_NO_CONST)buffer_alloc(ICON_LENGTH);
216 memcpy(filetypes[filetype_count].icon, icon, ICON_LENGTH);
218 else
219 filetypes[filetype_count].icon = NOICON;
220 #else
221 filetypes[filetype_count].icon = Icon_Unknown;
222 #endif
223 filetype_count++;
227 int filetype_get_attr(const char* file)
229 char *extension = strrchr(file, '.');
230 int i;
231 if (!extension)
232 return 0;
233 extension++;
234 for (i=0; i<filetype_count; i++)
236 if (filetypes[i].extension &&
237 !strcasecmp(extension, filetypes[i].extension))
238 return (filetypes[i].attr<<8)&TREE_ATTR_MASK;
240 return 0;
243 static int find_attr(int attr)
245 int i;
246 /* skip the directory item */
247 if ((attr & ATTR_DIRECTORY)==ATTR_DIRECTORY)
248 return 0;
249 for (i=1; i<filetype_count; i++)
251 if ((attr>>8) == filetypes[i].attr)
252 return i;
254 return -1;
257 ICON filetype_get_icon(int attr)
259 int index = find_attr(attr);
260 if (index < 0)
261 return NOICON;
262 return (ICON)filetypes[index].icon;
265 char* filetype_get_plugin(const struct entry* file)
267 static char plugin_name[MAX_PATH];
268 int index = find_attr(file->attr);
269 if (index < 0)
270 return NULL;
271 snprintf(plugin_name, MAX_PATH, "%s/%s.%s",
272 filetypes[index].viewer? VIEWERS_DIR: PLUGIN_DIR,
273 filetypes[index].plugin, ROCK_EXTENSION);
274 return plugin_name;
277 bool filetype_supported(int attr)
279 return find_attr(attr) >= 0;
282 int filetype_list_viewers(const char* current_file)
284 int i, count = 0;
285 char *strings[MAX_FILETYPES/2];
286 struct menu_callback_with_desc cb_and_desc =
287 { NULL, ID2P(LANG_ONPLAY_OPEN_WITH), Icon_Plugin };
288 struct menu_item_ex menu;
290 for (i=0; i<filetype_count && count < (MAX_FILETYPES/2); i++)
292 if (filetypes[i].plugin)
294 int j;
295 for (j=0;j<count;j++) /* check if the plugin is in the list yet */
297 if (!strcmp(strings[j], filetypes[i].plugin))
298 break;
300 if (j<count)
301 continue; /* it is so grab the next plugin */
302 strings[count] = filetypes[i].plugin;
303 count++;
306 #ifndef HAVE_LCD_BITMAP
307 if (count == 0)
309 /* FIX: translation! */
310 gui_syncsplash(HZ*2, (unsigned char *)"No viewers found");
311 return PLUGIN_OK;
313 #endif
314 menu.flags = MT_RETURN_ID|MENU_HAS_DESC|MENU_ITEM_COUNT(count);
315 menu.strings = (const char**)strings;
316 menu.callback_and_desc = &cb_and_desc;
317 i = do_menu(&menu, NULL);
318 if (i >= 0)
319 return filetype_load_plugin(strings[i], (void*)current_file);
320 return i;
323 int filetype_load_plugin(const char* plugin, char* file)
325 int fd;
326 char plugin_name[MAX_PATH];
327 snprintf(plugin_name, sizeof(plugin_name), "%s/%s.%s",
328 VIEWERS_DIR, plugin, ROCK_EXTENSION);
329 if ((fd = open(plugin_name,O_RDONLY))>=0)
331 close(fd);
332 return plugin_load(plugin_name,file);
334 else
336 snprintf(plugin_name, sizeof(plugin_name), "%s/%s.%s",
337 PLUGIN_DIR, plugin, ROCK_EXTENSION);
338 if ((fd = open(plugin_name,O_RDONLY))>=0)
340 close(fd);
341 return plugin_load(plugin_name,file);
344 return PLUGIN_ERROR;