summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2007-03-29 06:16:00 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2007-03-29 06:16:00 +0000
commit21165a3f3db3c777f8522b14f16e570107b0405b (patch)
treea3e2766c1424ded8a2de37ba28f0a709ee3d4ded /apps
parentd71b531c25ad0e02f4124e6e8cb851f59e4bbc65 (diff)
downloadrockbox-21165a3f3db3c777f8522b14f16e570107b0405b.tar.gz
rockbox-21165a3f3db3c777f8522b14f16e570107b0405b.zip
Recode filetypes.c to remove its need for a static string buffer.
Functional changes: - filetypes.c handles the open with menu now instead of onplay.c - automatic plugin registration no longer works (did anyone know about you could do this?) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12959 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/filetypes.c905
-rw-r--r--apps/filetypes.h40
-rw-r--r--apps/gui/icon.h2
-rw-r--r--apps/main.c3
-rw-r--r--apps/onplay.c21
-rw-r--r--apps/settings.h6
-rw-r--r--apps/tree.c1
7 files changed, 238 insertions, 740 deletions
diff --git a/apps/filetypes.c b/apps/filetypes.c
index 49ce1c72aa..d374b559ce 100644
--- a/apps/filetypes.c
+++ b/apps/filetypes.c
@@ -7,7 +7,7 @@
*
* $Id$
*
- * Copyright (C) 2004 Henrik Backe
+ * Copyright (C) 2007 Jonathan Gordon
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
@@ -21,6 +21,8 @@
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
+#include "string.h"
+#include <ctype.h>
#include "sprintf.h"
#include "settings.h"
@@ -36,791 +38,308 @@
#include "file.h"
#include "icons.h"
#include "splash.h"
-
-/* max plugin name size without extensions and path */
-#define MAX_PLUGIN_LENGTH 32
+#include "buffer.h"
/* max filetypes (plugins & icons stored here) */
#if CONFIG_CODEC == SWCODEC
-#define MAX_FILETYPES 64
+#define MAX_FILETYPES 72
#else
#define MAX_FILETYPES 48
#endif
-/* max exttypes (extensions stored here) */
-#if CONFIG_CODEC == SWCODEC
-/* Software codecs require more file extensions */
-#define MAX_EXTTYPES 64
-#else
-#define MAX_EXTTYPES 32
-#endif
-
-/* string buffer length */
-#define STRING_BUFFER_SIZE 548
-
/* number of bytes for the binary icon */
#define ICON_LENGTH 6
/* mask for dynamic filetype info in attribute */
#define FILETYPES_MASK 0xFF00
-
-/* filenames */
-#define ROCK_EXTENSION ".rock"
-#define VIEWERS_CONFIG ROCKBOX_DIR "/viewers.config"
-#define VIEWERS_DIR ROCKBOX_DIR "/viewers"
-
-/* global variables */
-static int cnt_filetypes;
-static int cnt_exttypes;
-static struct ext_type exttypes [MAX_EXTTYPES];
+#define ROCK_EXTENSION "rock"
+
+struct file_type {
+ ICON_NO_CONST icon; /* the icon which shall be used for it, NOICON if unknown */
+ bool viewer; /* true if the rock is in viewers, false if in rocks */
+ unsigned char attr; /* FILETYPES_MASK >> 8 */
+ char* plugin; /* Which plugin to use, NULL if unknown, or builtin */
+ char* extension; /* NULL for none */
+};
static struct file_type filetypes[MAX_FILETYPES];
-static int first_soft_exttype;
-static int first_soft_filetype;
-static char* next_free_string;
-static char plugin_name[sizeof(VIEWERS_DIR) + 7 + MAX_PLUGIN_LENGTH];
-static char string_buffer[STRING_BUFFER_SIZE];
+static int filetype_count = 0;
+static unsigned char heighest_attr = 0;
-/* prototypes */
-#ifdef HAVE_LCD_BITMAP
-static char* string2icon(const char*);
-static int add_plugin(char*,char*);
-#else
-static int add_plugin(char*);
-#endif
-static char* get_string(const char*);
-static int find_attr_index(int);
-static bool read_config(const char*);
-static void rm_whitespaces(char*);
-static void scan_plugins(void);
-
-/* initialize dynamic filetypes (called at boot from tree.c) */
-void filetype_init(void)
+static char *filetypes_strdup(char* string)
{
- int cnt,i,ix;
- const struct filetype* ftypes;
-
- memset(exttypes,0,sizeof(exttypes));
- memset(filetypes,0,sizeof(filetypes));
- next_free_string=string_buffer;
-
-/* The special filetype folder must always be stored at index 0 */
-#ifdef HAVE_LCD_BITMAP
- if (!filetypes[0].icon)
- filetypes[0].icon = bitmap_icons_6x8[Icon_Folder];
-#else
- if (!filetypes[0].icon)
- filetypes[0].icon = Icon_Folder;
- for (i=1; i < MAX_FILETYPES; i++)
- filetypes[i].icon = -1;
-#endif
-
- /* register hardcoded filetypes */
- tree_get_filetypes(&ftypes, &cnt);
- cnt_exttypes=0;
- cnt_filetypes=0;
-
- for (i = 0; i < cnt ; i++)
- {
- ix = ((ftypes[i].tree_attr & FILETYPES_MASK) >> 8);
- if (ix < MAX_FILETYPES && i < MAX_EXTTYPES)
- {
-#ifdef HAVE_LCD_BITMAP
- if (filetypes[ix].icon == NULL)
- filetypes[ix].icon=bitmap_icons_6x8[ftypes[i].icon];
-#else
- if (filetypes[ix].icon == -1)
- filetypes[ix].icon=ftypes[i].icon;
-#endif
- if (ix > cnt_filetypes)
- cnt_filetypes=ix;
- exttypes[cnt_exttypes].type=&filetypes[ix];
- exttypes[cnt_exttypes].extension=ftypes[i].extension;
- cnt_exttypes++;
- }
- }
- first_soft_exttype=cnt_exttypes;
- cnt_filetypes++;
- first_soft_filetype=cnt_filetypes;
-
- /* register dynamic filetypes */
- read_config(VIEWERS_CONFIG);
- scan_plugins();
+ char *buffer = (char*)buffer_alloc(strlen(string)+1);
+ strcpy(buffer, string);
+ return buffer;
}
+static void read_builtin_types(void);
+static void read_config(char* config_file);
-/* get icon */
-#ifdef HAVE_LCD_BITMAP
-const unsigned char* filetype_get_icon(int attr)
-#else
-int filetype_get_icon(int attr)
-#endif
+void filetype_init(void)
{
- int ix;
-
- ix = find_attr_index(attr);
-
- if (ix < 0)
- {
+ /* set the directory item first */
+ filetypes[0].extension = NULL;
+ filetypes[0].plugin = NULL;
+ filetypes[0].attr = 0;
+ filetypes[0].icon =
#ifdef HAVE_LCD_BITMAP
- return NULL;
+ (ICON_NO_CONST)&bitmap_icons_6x8[Icon_Folder];
#else
- return Icon_Unknown;
+ (ICON_NO_CONST)Icon_Folder;
#endif
- }
- else
- {
- return filetypes[ix].icon;
- }
-}
-
-/* get plugin */
-char* filetype_get_plugin(const struct entry* file)
-{
- int ix;
-
- ix=find_attr_index(file->attr);
-
- if (ix < 0)
- {
- return NULL;
- }
-
- if ((filetypes[ix].plugin == NULL) ||
- (strlen(filetypes[ix].plugin) > MAX_PLUGIN_LENGTH))
- return NULL;
-
- snprintf(plugin_name, sizeof(plugin_name),
- "%s/%s.rock", ROCKBOX_DIR, filetypes[ix].plugin);
-
- return plugin_name;
-}
-
-/* check if filetype is supported */
-bool filetype_supported(int attr)
-{
- int ix;
-
- ix=find_attr_index(attr);
-
- /* hard filetypes and soft filetypes with plugins is supported */
- if (ix > 0)
- if (filetypes[ix].plugin || ix < first_soft_filetype)
- return true;
-
- return false;
-}
-
-/* get the "dynamic" attribute for an extension */
-int filetype_get_attr(const char* name)
-{
- int i;
- const char *cp = strrchr(name,'.');
-
- if (!cp) /* no extension? -> can't be a supported type */
- return 0;
- cp++;
-
- for (i=0; i < cnt_exttypes; i++)
- {
- if (exttypes[i].extension)
- {
- if (!strcasecmp(cp,exttypes[i].extension))
- {
- return ((((unsigned long)exttypes[i].type -
- (unsigned long)&filetypes[0]) /
- sizeof(struct file_type)) << 8);
- }
- }
- }
-
- return 0;
-}
-
-/* fill a menu list with viewers (used in onplay.c) */
-int filetype_load_menu(struct menu_item* menu,int max_items)
-{
- int i;
- char *cp;
- int cnt=0;
-
- for (i=0; i < cnt_filetypes; i++)
- {
- if (filetypes[i].plugin)
- {
- int j;
- for (j=0;j<cnt;j++) /* check if the plugin is in the list yet */
- {
- if (!strcmp(menu[j].desc,filetypes[i].plugin))
- break;
- }
- if (j<cnt) continue; /* it is so grab the next plugin */
- cp=strrchr(filetypes[i].plugin,'/');
- if (cp) cp++;
- else cp=filetypes[i].plugin;
- menu[cnt].desc = (unsigned char *)cp;
- cnt++;
- if (cnt == max_items)
- break;
- }
- }
- return cnt;
+ filetype_count = 1;
+ read_builtin_types();
+ read_config(VIEWERS_CONFIG);
}
-/* start a plugin with an argument (called from onplay.c) */
-int filetype_load_plugin(const char* plugin, char* file)
+/* remove all white spaces from string */
+static void rm_whitespaces(char* str)
{
- int fd;
- snprintf(plugin_name,sizeof(plugin_name),"%s/%s.rock",
- VIEWERS_DIR,plugin);
- if ((fd = open(plugin_name,O_RDONLY))>=0)
+ char *s = str;
+ while (*str)
{
- close(fd);
- return plugin_load(plugin_name,file);
- }
- else
- {
- snprintf(plugin_name,sizeof(plugin_name),"%s/%s.rock",
- PLUGIN_DIR,plugin);
- if ((fd = open(plugin_name,O_RDONLY))>=0)
+ if (!isspace(*str))
{
- close(fd);
- return plugin_load(plugin_name,file);
+ *s = *str;
+ s++;
}
+ str++;
}
- return PLUGIN_ERROR;
+ *s = '\0';
}
-/* get index to filetypes[] from the file attribute */
-static int find_attr_index(int attr)
+static void read_builtin_types(void)
{
- int ix;
- ix = ((attr & FILETYPES_MASK) >> 8);
-
- if ((attr & ATTR_DIRECTORY)==ATTR_DIRECTORY)
- {
- ix=0;
- }
- else
+ const struct filetype *types;
+ int count, i;
+ tree_get_filetypes(&types, &count);
+ for(i=0; i<count && (filetype_count < MAX_FILETYPES); i++)
{
- if (ix==0)
- ix=-1;
- if (ix > cnt_filetypes)
- ix=-1;
- else
- if ((filetypes[ix].plugin == NULL) &&
+ filetypes[filetype_count].extension = types[i].extension;
+ filetypes[filetype_count].plugin = NULL;
+ filetypes[filetype_count].attr = types[i].tree_attr>>8;
+ if (filetypes[filetype_count].attr > heighest_attr)
+ heighest_attr = filetypes[filetype_count].attr;
+ filetypes[filetype_count].icon =
#ifdef HAVE_LCD_BITMAP
- (filetypes[ix].icon == NULL)
+ (ICON_NO_CONST)&bitmap_icons_6x8[types[i].icon];
#else
- (filetypes[ix].icon == -1)
+ (ICON_NO_CONST)Icon_Folder;
#endif
- )
- ix=-1;
+ filetype_count++;
}
-
- return ix;
}
-/* scan the plugin directory and register filetypes */
-static void scan_plugins(void)
+static void read_config(char* config_file)
{
- DIR *dir;
- struct dirent *entry;
- char* cp;
- char* dot;
- char* dash;
- int ix;
- int i;
- bool found;
-
- dir = opendir(VIEWERS_DIR);
- if(!dir)
+ char line[64], *s, *e;
+ char extension[8], plugin[32];
+#ifdef HAVE_LCD_BITMAP
+ char icon[ICON_LENGTH];
+ int good_icon;
+#endif
+ bool viewer;
+ int fd = open(config_file, O_RDONLY);
+ if (fd < 0)
return;
-
- while (true)
+ /* config file is in the for
+ <extension>,<plugin>,<icon code>
+ ignore line if either of the first two are missing */
+ while (read_line(fd, line, 64) > 0)
{
- /* exttypes[] full, bail out */
- if (cnt_exttypes >= MAX_EXTTYPES)
- {
- gui_syncsplash(HZ, str(LANG_FILETYPES_EXTENSION_FULL));
- break;
- }
-
- /* filetypes[] full, bail out */
- if (cnt_filetypes >= MAX_FILETYPES)
+ if (filetype_count >= MAX_FILETYPES)
{
gui_syncsplash(HZ, str(LANG_FILETYPES_FULL));
break;
}
-
- entry = readdir(dir);
-
- if (!entry)
- break;
-
- /* skip directories */
- if ((entry->attribute & ATTR_DIRECTORY))
- continue;
-
- /* Skip FAT volume ID */
- if (entry->attribute & ATTR_VOLUME_ID)
+ rm_whitespaces(line);
+ /* get the extention */
+ s = line;
+ e = strchr(s, ',');
+ if (!e)
continue;
-
- /* filter out dotfiles and hidden files */
- if ((entry->d_name[0]=='.') ||
- (entry->attribute & ATTR_HIDDEN)) {
+ *e = '\0';
+ strcpy(extension, s);
+
+ /* get the plugin */
+ s = e+1;
+ e = strchr(s, '/');
+ if (!e)
continue;
- }
-
- /* filter out non rock files */
- if (strcasecmp((char *)&entry->d_name[strlen((char *)entry->d_name) -
- sizeof(ROCK_EXTENSION) + 1],
- ROCK_EXTENSION)) {
+ *e = '\0';
+ if (!strcasecmp("viewers", s))
+ viewer = true;
+ else
+ viewer = false;
+ s = e+1;
+ e = strchr(s, ',');
+ if (!e)
continue;
- }
-
- /* filter out to long filenames */
- if (strlen((char *)entry->d_name) > MAX_PLUGIN_LENGTH + 5)
+ *e = '\0';
+ strcpy(plugin, s);
+ /* ok, store this plugin/extension, check icon after */
+ filetypes[filetype_count].extension = filetypes_strdup(extension);
+ filetypes[filetype_count].plugin = filetypes_strdup(plugin);
+ filetypes[filetype_count].viewer = viewer;
+ filetypes[filetype_count].attr = heighest_attr +1;
+ heighest_attr++;
+ /* get the icon */
+#ifdef HAVE_LCD_BITMAP
+ s = e+1;
+ good_icon = 1;
+ if (strlen(s) == 12)
{
- gui_syncsplash(HZ, str(LANG_FILETYPES_PLUGIN_NAME_LONG));
- continue;
- }
-
- dot=strrchr((char *)entry->d_name,'.');
- *dot='\0';
- dash=strchr((char *)entry->d_name,'-');
-
- /* add plugin and extension */
- if (dash)
- {
- *dash='\0';
- ix=(filetype_get_attr((char *)entry->d_name) >> 8);
- if (!ix)
+ int i, j;
+ char val[2];
+ for (i = 0; good_icon && i < ICON_LENGTH; i++)
{
- cp=get_string((char *)entry->d_name);
- if (cp)
+ for (j=0; good_icon && j<2; j++)
{
- exttypes[cnt_exttypes].extension=cp;
- exttypes[cnt_exttypes].type=&filetypes[cnt_filetypes];
-#ifdef HAVE_LCD_BITMAP
- exttypes[cnt_exttypes].type->icon = bitmap_icons_6x8[Icon_Plugin];
-#else
- exttypes[cnt_exttypes].type->icon = Icon_Plugin;
-#endif
- cnt_exttypes++;
-
- *dash='-';
- cp=get_string((char *)entry->d_name);
- if (cp)
+ val[j] = tolower(s[i*2+j]);
+ if (val[j] >= 'a' && val[j] <= 'f')
{
- filetypes[cnt_filetypes].plugin=cp;
- cnt_filetypes++;
+ val[j] = val[j] - 'a' + 10;
}
- else
- break;
- }
- else
- break;
- }
- else
- {
- *dash='-';
- if (!filetypes[ix].plugin)
- {
- cp=get_string((char *)entry->d_name);
- if (cp)
+ else if (val[j] >= '0' && val[j] <= '9')
{
- filetypes[cnt_filetypes].plugin=cp;
- cnt_filetypes++;
+ val[j] = val[j] - '0';
}
- else
- break;
+ else
+ good_icon = 0;
}
+ icon[i]=((val[0]<<4) | val[1]);
}
- *dash='-';
}
- /* add plugin only */
- else
+ if (good_icon)
{
- found=false;
- for (i = first_soft_filetype; i < cnt_filetypes; i++)
- {
- if (filetypes[i].plugin)
- if (!strcasecmp(filetypes[i].plugin, (char *)entry->d_name))
- {
- found=true;
- break;
- }
- }
-
- if (!found)
- {
- cp=get_string((char *)entry->d_name);
- if (cp)
- {
- filetypes[cnt_filetypes].plugin=cp;
- filetypes[cnt_filetypes].no_extension=true;
- cnt_filetypes++;
- }
- else
- break;
- }
+ filetypes[filetype_count].icon =
+ (ICON_NO_CONST)buffer_alloc(ICON_LENGTH);
+ memcpy(filetypes[filetype_count].icon, icon, ICON_LENGTH);
}
- *dot='.';
+ else
+ filetypes[filetype_count].icon = NOICON;
+#else
+ filetypes[filetype_count].icon = Icon_Unknown;
+#endif
+ filetype_count++;
}
- closedir(dir);
}
-#ifdef HAVE_LCD_BITMAP
-static int add_plugin(char *plugin, char *icon)
-#else
-static int add_plugin(char *plugin)
-#endif
+int filetype_get_attr(const char* file)
{
- char *cp;
+ char *extension = strrchr(file, '.');
int i;
-
- if (!plugin)
+ if (!extension)
return 0;
-
-#if 0
- /* starting now, Oct 2005, the plugins are given without extension in the
- viewers.config file */
- cp=strrchr(plugin, '.');
- if (cp)
- *cp='\0';
-#endif
-
- for (i=first_soft_filetype; i < cnt_filetypes; i++)
+ extension++;
+ for (i=0; i<filetype_count; i++)
{
- if (filetypes[i].plugin)
- {
- if (!strcasecmp(plugin, filetypes[i].plugin))
- {
-#ifdef HAVE_LCD_BITMAP
- if (filetypes[i].icon == NULL && icon)
- {
- cp = string2icon(icon);
- if (cp)
- filetypes[cnt_filetypes].icon = (unsigned char *)cp;
- else
- return 0;
- }
-#endif
- return i;
- }
- }
+ if (filetypes[i].extension &&
+ !strcasecmp(extension, filetypes[i].extension))
+ return (filetypes[i].attr<<8)&TREE_ATTR_MASK;
}
+ return 0;
+}
- /* new plugin */
- cp = get_string(plugin);
- if (cp)
- {
- filetypes[cnt_filetypes].plugin = cp;
-#ifdef HAVE_LCD_BITMAP
- /* add icon */
- if (icon)
- {
- cp = string2icon(icon);
- if (cp)
- filetypes[cnt_filetypes].icon = (unsigned char *)cp;
- else
- return 0;
- }
-#endif
- }
- else
- {
+static int find_attr(int attr)
+{
+ int i;
+ /* skip the directory item */
+ if ((attr & ATTR_DIRECTORY)==ATTR_DIRECTORY)
return 0;
+ for (i=1; i<filetype_count; i++)
+ {
+ if ((attr>>8) == filetypes[i].attr)
+ return i;
}
-
- cnt_filetypes++;
- return cnt_filetypes - 1;
+ return -1;
}
-/* read config file (or cahe file) */
-static bool read_config(const char* file)
+ICON filetype_get_icon(int attr)
{
- enum {extension,
- plugin,
-#ifdef HAVE_LCD_BITMAP
- icon,
-#endif
- last};
+ int index = find_attr(attr);
+ if (index < 0)
+ return NOICON;
+ return (ICON)filetypes[index].icon;
+}
- int i,ix;
- int fd;
- char* end;
- char* cp;
- char* str[last];
- char buf[80];
+char* filetype_get_plugin(const struct entry* file)
+{
+ static char plugin_name[MAX_PATH];
+ int index = find_attr(file->attr);
+ if (index < 0)
+ return NULL;
+ snprintf(plugin_name, MAX_PATH, "%s/%s.%s",
+ filetypes[index].viewer? VIEWERS_DIR: PLUGIN_DIR,
+ filetypes[index].plugin, ROCK_EXTENSION);
+ return plugin_name;
+}
- fd = open(file, O_RDONLY);
- if (fd < 0)
- return false;
+bool filetype_supported(int attr)
+{
+ return find_attr(attr) >= 0;
+}
- while (read_line(fd, buf, sizeof(buf)))
+int filetype_list_viewers(const char* current_file)
+{
+ int i, count = 0;
+ char *strings[MAX_FILETYPES/2];
+ struct menu_callback_with_desc cb_and_desc =
+ { NULL, ID2P(LANG_ONPLAY_OPEN_WITH), Icon_Plugin };
+ struct menu_item_ex menu;
+
+ for (i=0; i<filetype_count && count < (MAX_FILETYPES/2); i++)
{
- if (cnt_exttypes >= MAX_EXTTYPES)
- {
- gui_syncsplash(HZ, str(LANG_FILETYPES_EXTENSION_FULL));
- break;
- }
-
- if (cnt_filetypes >= MAX_FILETYPES)
- {
- gui_syncsplash(HZ, str(LANG_FILETYPES_FULL));
- break;
- }
-
- /* parse buffer */
- rm_whitespaces(buf);
-
- if (strlen(buf) == 0)
- continue;
-
- if (buf[0] == '#')
- continue;
-
- memset(str,0,sizeof(str));
- i=0;
- cp=buf;
- while (*cp==',') {
- cp++;
- i++;
- }
- str[i] = strtok_r(cp, ",", &end);
- i++;
-
- while (end && i < last)
- {
- if (end)
- {
- cp=end;
- while (*cp==',') {
- cp++;
- i++;
- }
- }
- str[i] = strtok_r(NULL, ",", &end);
- if (str[i])
- if (!strlen(str[i]))
- str[i]=NULL;
- i++;
- }
-
- /* bail out if no icon and no plugin */
- if (!str[plugin]
-#ifdef HAVE_LCD_BITMAP
- && !str[icon]
-#endif
- )
- continue;
-
- /* bail out if no plugin and icon is incorrect*/
- if (!str[plugin]
-#ifdef HAVE_LCD_BITMAP
- && strlen(str[icon]) != ICON_LENGTH*2
-#endif
- )
- continue;
-
- /* bail out if no icon and no plugin and no extension*/
- if (!str[plugin] &&
-#ifdef HAVE_LCD_BITMAP
- !str[icon] &&
-#endif
- !str[extension])
- continue;
-
- /* bail out if we are not able to start plugin from onplay.c ?*/
- if (str[plugin])
- {
- if (strlen(str[plugin]) > MAX_PLUGIN_LENGTH)
- {
- gui_syncsplash(HZ, str(LANG_FILETYPES_PLUGIN_NAME_LONG));
- str[plugin] = NULL;
- continue;
- }
- }
-
- ix=0;
- /* if extension already exist don't add a new one */
- for (i=0; i < cnt_exttypes; i++)
- {
- if (!strcasecmp(str[extension],exttypes[i].extension))
- {
-#ifdef HAVE_LCD_BITMAP
- ix=add_plugin(str[plugin],NULL);
- if (ix)
- {
- if (str[icon] && filetypes[ix].icon == NULL)
- {
- if (exttypes[i].type->icon == NULL)
- {
- cp = string2icon(str[icon]);
- if (cp)
- exttypes[i].type->icon = (unsigned char *)cp;
- }
- }
- }
-#else
- ix=add_plugin(str[plugin]);
-#endif
- if (exttypes[i].type == NULL)
- {
- exttypes[i].type = &filetypes[ix];
- }
- break;
- }
- }
- if (ix)
- continue;
-
- /* add extension */
- if (str[extension])
+ if (filetypes[i].plugin)
{
-#ifdef HAVE_LCD_BITMAP
- ix=add_plugin(str[plugin],str[icon]);
-#else
- ix=add_plugin(str[plugin]);
-#endif
- if (ix)
+ int j;
+ for (j=0;j<count;j++) /* check if the plugin is in the list yet */
{
- cp=get_string(str[extension]);
- if (cp)
- {
- exttypes[cnt_exttypes].extension = cp;
-
- exttypes[cnt_exttypes].type = &filetypes[ix];
- cnt_exttypes++;
- filetypes[i].no_extension=false;
- }
- else
- {
+ if (!strcmp(strings[j], filetypes[i].plugin))
break;
- }
- }
- else
- {
- break;
}
+ if (j<count)
+ continue; /* it is so grab the next plugin */
+ strings[count] = filetypes[i].plugin;
+ count++;
}
- else
- {
-#ifdef HAVE_LCD_BITMAP
- ix=add_plugin(str[plugin],str[icon]);
-#else
- ix=add_plugin(str[plugin]);
-#endif
- filetypes[ix].no_extension=true;
- if (!i)
- break;
- }
- }
- close(fd);
-
- return true;
-}
-
-#ifdef HAVE_LCD_BITMAP
-/* convert an ascii hexadecimal icon to a binary icon */
-static char* string2icon(const char* str)
-{
- char tmp[ICON_LENGTH*2];
- char *cp;
- int i;
-
- if (strlen(str)!=ICON_LENGTH*2)
- return NULL;
-
- if ((sizeof(string_buffer) +
- (unsigned long) string_buffer -
- (unsigned long) next_free_string) < ICON_LENGTH)
- {
- gui_syncsplash(HZ, str(LANG_FILETYPES_STRING_BUFFER_EMPTY));
- return NULL;
}
-
- for (i=0; i<12; i++)
+#ifndef HAVE_LCD_BITMAP
+ if (count == 0)
{
- if (str[i] >= '0' && str[i] <= '9')
- {
- tmp[i]=str[i]-'0';
- continue;
- }
-
- if (str[i] >= 'a' && str[i] <= 'f')
- {
- tmp[i]=str[i]-'a'+10;
- continue;
- }
-
- if (str[i] >= 'A' && str[i] <= 'F')
- {
- tmp[i]=str[i]-'A'+10;
- continue;
- }
-
- return NULL;
+ /* FIX: translation! */
+ gui_syncsplash(HZ*2, (unsigned char *)"No viewers found");
+ return PLUGIN_OK;
}
-
- cp=next_free_string;
- for (i = 0; i < ICON_LENGTH; i++)
- cp[i]=((tmp[i*2]<<4) | tmp[i*2+1]);
-
- next_free_string=&next_free_string[ICON_LENGTH];
- return cp;
-}
#endif
+ menu.flags = MT_RETURN_ID|MENU_HAS_DESC|MENU_ITEM_COUNT(count);
+ menu.strings = (const char**)strings;
+ menu.callback_and_desc = &cb_and_desc;
+ i = do_menu(&menu, NULL);
+ if (i >= 0)
+ return filetype_load_plugin(strings[i], (void*)current_file);
+ return i;
+}
-/* get string from buffer */
-static char* get_string(const char* str)
+int filetype_load_plugin(const char* plugin, char* file)
{
- unsigned int l=strlen(str)+1;
- char* cp;
-
- if (!str)
- return NULL;
-
- if (l <= (sizeof(string_buffer) +
- (unsigned long) string_buffer -
- (unsigned long) next_free_string))
+ int fd;
+ char plugin_name[MAX_PATH];
+ snprintf(plugin_name, sizeof(plugin_name), "%s/%s.%s",
+ VIEWERS_DIR, plugin, ROCK_EXTENSION);
+ if ((fd = open(plugin_name,O_RDONLY))>=0)
{
- strcpy(next_free_string, str);
- cp=next_free_string;
- next_free_string=&next_free_string[l];
- return cp;
+ close(fd);
+ return plugin_load(plugin_name,file);
}
else
- {
- gui_syncsplash(HZ, str(LANG_FILETYPES_STRING_BUFFER_EMPTY));
- return NULL;
- }
-}
-
-/* remove all white spaces from string */
-static void rm_whitespaces(char* str)
-{
- char *cp, *free;
-
- cp=str;
- free=cp;
-
- while (cp < &str[strlen(str)])
- {
- switch (*cp)
+ {
+ snprintf(plugin_name, sizeof(plugin_name), "%s/%s.%s",
+ PLUGIN_DIR, plugin, ROCK_EXTENSION);
+ if ((fd = open(plugin_name,O_RDONLY))>=0)
{
- case ' ' :
- case '\t' :
- case '\r' :
- break;
-
- default:
- *free=*cp;
- free++;
- break;
+ close(fd);
+ return plugin_load(plugin_name,file);
}
- cp++;
}
-
- *free='\0';
+ return PLUGIN_ERROR;
}
diff --git a/apps/filetypes.h b/apps/filetypes.h
index 7416c93b00..d2556c1d95 100644
--- a/apps/filetypes.h
+++ b/apps/filetypes.h
@@ -22,32 +22,24 @@
#include <stdbool.h>
#include <tree.h>
#include <menu.h>
-
-int filetype_get_attr(const char*);
-#ifdef HAVE_LCD_BITMAP
-const unsigned char* filetype_get_icon(int);
-#else
-int filetype_get_icon(int);
-#endif
-char* filetype_get_plugin(const struct entry*);
+/* init the filetypes structs.
+ uses audio buffer for storage, so call early in init... */
void filetype_init(void);
-bool filetype_supported(int);
-int filetype_load_menu(struct menu_item*, int);
-int filetype_load_plugin(const char*, char*);
-struct file_type {
-#ifdef HAVE_LCD_BITMAP
- const unsigned char* icon; /* the icon which shall be used for it, NULL if unknown */
-#else
- int icon; /* the icon which shall be used for it, -1 if unknown */
-#endif
- char* plugin; /* Which plugin to use, NULL if unknown */
- bool no_extension;
-};
+/* Return the attribute (TREE_ATTR_*) of the file */
+int filetype_get_attr(const char* file);
+ICON filetype_get_icon(int attr);
+/* return the plugin filename associated with the file */
+char* filetype_get_plugin(const struct entry* file);
+
+/* returns true if the attr is supported */
+bool filetype_supported(int attr);
+
+/* List avialable viewers */
+int filetype_list_viewers(const char* current_file);
+
+/* start a plugin with file as the argument (called from onplay.c) */
+int filetype_load_plugin(const char* plugin, char* file);
-struct ext_type {
- char* extension; /* extension for which the file type is recognized */
- struct file_type* type;
-};
#endif
diff --git a/apps/gui/icon.h b/apps/gui/icon.h
index 9ceda9e933..c717bbc6ea 100644
--- a/apps/gui/icon.h
+++ b/apps/gui/icon.h
@@ -24,9 +24,11 @@
* char-based displays and bitmap displays */
#ifdef HAVE_LCD_BITMAP
typedef const unsigned char * ICON;
+typedef unsigned char * ICON_NO_CONST;
#define NOICON NULL
#else
typedef long ICON;
+#define ICON_NO_CONST ICON
#define NOICON -1
#endif
diff --git a/apps/main.c b/apps/main.c
index c1f818be7f..27698e35e0 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -29,6 +29,7 @@
#include "kernel.h"
#include "button.h"
#include "tree.h"
+#include "filetypes.h"
#include "panic.h"
#include "menu.h"
#include "system.h"
@@ -258,6 +259,7 @@ static void init(void)
#endif
sleep(HZ/2);
tree_init();
+ filetype_init();
playlist_init();
#if CONFIG_CODEC != SWCODEC
@@ -490,6 +492,7 @@ static void init(void)
status_init();
playlist_init();
tree_init();
+ filetype_init();
scrobbler_init();
cuesheet_init();
diff --git a/apps/onplay.c b/apps/onplay.c
index fe70873c56..fb3ed24cfb 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -125,28 +125,9 @@ static bool bookmark_menu(void)
static bool list_viewers(void)
{
- struct menu_item menu[16];
- int m, i, result;
- int ret = 0;
-
- i=filetype_load_menu(menu,sizeof(menu)/sizeof(*menu));
- if (i)
- {
- m = menu_init( menu, i, NULL, NULL, NULL, NULL );
- result = menu_show(m);
- menu_exit(m);
- if (result >= 0)
- ret = filetype_load_plugin((char *)menu[result].desc,selected_file);
- }
- else
- {
- /* FIX: translation! */
- gui_syncsplash(HZ*2, (unsigned char *)"No viewers found");
- }
-
+ int ret = filetype_list_viewers(selected_file);
if (ret == PLUGIN_USB_CONNECTED)
onplay_result = ONPLAY_RELOAD_DIR;
-
return false;
}
diff --git a/apps/settings.h b/apps/settings.h
index f9e08152af..9921feaba7 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -56,14 +56,16 @@
#define WPS_DIR ROCKBOX_DIR "/wps"
#define THEME_DIR ROCKBOX_DIR "/themes"
#define PLUGIN_DIR ROCKBOX_DIR "/rocks"
+#define VIEWERS_DIR ROCKBOX_DIR "/viewers"
#define BACKDROP_DIR ROCKBOX_DIR "/backdrops"
#define REC_BASE_DIR "/recordings"
#define EQS_DIR ROCKBOX_DIR "/eqs"
#define CODECS_DIR ROCKBOX_DIR"/codecs"
#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
-#define CONFIGFILE ROCKBOX_DIR "/config.cfg"
-#define FIXEDSETTINGSFILE ROCKBOX_DIR "/fixed.cfg"
+#define VIEWERS_CONFIG ROCKBOX_DIR "/viewers.config"
+#define CONFIGFILE ROCKBOX_DIR "/config.cfg"
+#define FIXEDSETTINGSFILE ROCKBOX_DIR "/fixed.cfg"
#define MAX_FILENAME 32
diff --git a/apps/tree.c b/apps/tree.c
index 14ab8f2577..2b5dba3e18 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -259,7 +259,6 @@ void browse_root(void)
{
gui_sync_wps_screen_init();
- filetype_init();
check_rockboxdir();
strcpy(tc.currdir, "/");