summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/filetypes.c688
-rw-r--r--apps/filetypes.h53
-rw-r--r--apps/lang/english.lang36
-rw-r--r--apps/onplay.c34
-rw-r--r--apps/player/icons.h7
-rw-r--r--apps/plugins/Makefile2
-rw-r--r--apps/recorder/icons.c5
-rw-r--r--apps/recorder/icons.h10
-rw-r--r--apps/settings_menu.c2
-rw-r--r--apps/tree.c133
-rw-r--r--apps/tree.h34
-rw-r--r--uisimulator/win32/Makefile5
-rw-r--r--uisimulator/x11/Makefile5
13 files changed, 894 insertions, 120 deletions
diff --git a/apps/filetypes.c b/apps/filetypes.c
new file mode 100644
index 0000000000..f7eb33b74a
--- /dev/null
+++ b/apps/filetypes.c
@@ -0,0 +1,688 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ *
+ * $Id$
+ *
+ * Copyright (C) 2004 Henrik Backe
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "sprintf.h"
+#include "settings.h"
+#include "debug.h"
+#include "lang.h"
+#include "language.h"
+#include "kernel.h"
+#include "plugin.h"
+#include "filetypes.h"
+#include "screens.h"
+#include "icons.h"
+#include "dir.h"
+#include "file.h"
+#include "icons.h"
+
+/* max plugin name size without extensions and path */
+#define MAX_PLUGIN_LENGTH 32
+
+/* max filetypes (plugins & icons stored here) */
+#define MAX_FILETYPES 32
+
+/* max exttypes (extensions stored here) */
+#define MAX_EXTTYPES 32
+
+/* string buffer length */
+#define STRING_BUFFER_SIZE 256
+
+/* 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];
+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];
+
+/* prototypes */
+#ifdef HAVE_LCD_BITMAP
+static char* string2icon(char*);
+#endif
+static char* get_string(char*);
+static int find_attr_index(int);
+static bool read_config(char*);
+static void rm_whitespaces(char*);
+static void scan_plugins(void);
+
+/* initialize dynamic filetypes (called at boot from tree.c) */
+void filetype_init(void)
+{
+ int cnt,i,ix;
+ 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[Folder];
+#else
+ if (!filetypes[0].icon)
+ filetypes[0].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();
+}
+
+/* get icon */
+#ifdef HAVE_LCD_BITMAP
+char* filetype_get_icon(int attr)
+#else
+int filetype_get_icon(int attr)
+#endif
+{
+ int ix;
+
+ ix = find_attr_index(attr);
+
+ if (ix < 0)
+ {
+#ifdef HAVE_LCD_BITMAP
+ return NULL;
+#else
+ return -1;
+#endif
+ }
+ else
+ {
+ return filetypes[ix].icon;
+ }
+}
+
+/* get plugin */
+char* filetype_get_plugin(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),
+ VIEWERS_DIR "/%s.rock",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(char* name)
+{
+ int i;
+
+ for (i=0; i < cnt_exttypes; i++)
+ {
+ if (exttypes[i].extension)
+ {
+ if (!strcasecmp(&name[strlen(name)-
+ strlen(exttypes[i].extension)],
+ exttypes[i].extension))
+ {
+ return ((((unsigned int)exttypes[i].type -
+ (unsigned int)&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;
+ int cnt=0;
+ char* dash;
+
+ for (i=0; i < cnt_filetypes; i++)
+ {
+ if (filetypes[i].plugin)
+ {
+ menu[cnt].desc = filetypes[i].plugin;
+ cnt++;
+ if (cnt == max_items)
+ break;
+ }
+ }
+ return cnt;
+}
+
+/* start a plugin with an argument (called from onplay.c) */
+void filetype_load_plugin(char* plugin, char* file)
+{
+ snprintf(plugin_name,sizeof(plugin_name),"%s/%s.rock",
+ VIEWERS_DIR,plugin);
+ plugin_load(plugin_name,file);
+}
+
+/* get index to filetypes[] from the file attribute */
+static int find_attr_index(int attr)
+{
+ int ix;
+ ix = ((attr & FILETYPES_MASK) >> 8);
+
+ if ((attr & ATTR_DIRECTORY)==ATTR_DIRECTORY)
+ {
+ ix=0;
+ }
+ else
+ {
+ if (ix==0)
+ ix=-1;
+ if (ix > cnt_filetypes)
+ ix=-1;
+ else
+ if ((filetypes[ix].plugin == NULL) &&
+#ifdef HAVE_LCD_BITMAP
+ (filetypes[ix].icon == NULL)
+#else
+ (filetypes[ix].icon == -1)
+#endif
+ )
+ ix=-1;
+ }
+
+ return ix;
+}
+
+/* scan the plugin directory and register filetypes */
+static void scan_plugins(void)
+{
+ DIR *dir;
+ struct dirent *entry;
+ char* cp;
+ char* dot;
+ char* dash;
+ int ix;
+ int i;
+ bool found;
+
+ dir = opendir(VIEWERS_DIR);
+ if(!dir)
+ return;
+
+ while (true)
+ {
+ /* exttypes[] full, bail out */
+ if (cnt_exttypes >= MAX_EXTTYPES)
+ {
+ splash(HZ,true,str(LANG_FILETYPES_EXTENSION_FULL));
+ break;
+ }
+
+ /* filetypes[] full, bail out */
+ if (cnt_filetypes >= MAX_FILETYPES)
+ {
+ splash(HZ,true,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)
+ continue;
+
+ /* filter out dotfiles and hidden files */
+ if ((entry->d_name[0]=='.') ||
+ (entry->attribute & ATTR_HIDDEN)) {
+ continue;
+ }
+
+ /* filter out non rock files */
+ if (!strcasecmp(
+ &entry->d_name[strlen(entry->d_name) - sizeof(ROCK_EXTENSION) -1],
+ ROCK_EXTENSION)) {
+ continue;
+ }
+
+ /* filter out to long filenames */
+ if (strlen(entry->d_name) > MAX_PLUGIN_LENGTH + 5)
+ {
+ splash(HZ,true,str(LANG_FILETYPES_PLUGIN_NAME_LONG));
+ continue;
+ }
+
+ dot=strrchr(entry->d_name,'.');
+ *dot='\0';
+ dash=strchr(entry->d_name,'-');
+
+ /* add plugin and extension */
+ if (dash)
+ {
+ *dash='\0';
+ ix=(filetype_get_attr(entry->d_name) >> 8);
+ if (!ix)
+ {
+ cp=get_string(entry->d_name);
+ if (cp)
+ {
+ exttypes[cnt_exttypes].extension=cp;
+ exttypes[cnt_exttypes].type=&filetypes[cnt_filetypes];
+#ifdef HAVE_LCD_BITMAP
+ exttypes[cnt_exttypes].type->icon = bitmap_icons_6x8[Plugin];
+#else
+ exttypes[cnt_exttypes].type->icon = Plugin;
+#endif
+ cnt_exttypes++;
+
+ *dash='-';
+ cp=get_string(entry->d_name);
+ if (cp)
+ {
+ filetypes[cnt_filetypes].plugin=cp;
+ cnt_filetypes++;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ else
+ {
+ *dash='-';
+ if (!filetypes[ix].plugin)
+ {
+ cp=get_string(entry->d_name);
+ if (cp)
+ {
+ filetypes[cnt_filetypes].plugin=cp;
+ cnt_filetypes++;
+ }
+ else
+ break;
+ }
+ }
+ *dash='-';
+ }
+ /* add plugin only */
+ else
+ {
+ found=false;
+ for (i = first_soft_filetype; i < cnt_filetypes; i++)
+ {
+ if (filetypes[i].plugin)
+ if (!strcasecmp(filetypes[i].plugin,entry->d_name))
+ {
+ found=true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ cp=get_string(entry->d_name);
+ if (cp)
+ {
+ filetypes[cnt_filetypes].plugin=cp;
+ filetypes[cnt_filetypes].no_extension=true;
+ cnt_filetypes++;
+ }
+ else
+ break;
+ }
+ }
+ *dot='.';
+ }
+ closedir(dir);
+}
+
+/* read config file (or cahe file) */
+bool read_config(char* file)
+{
+ enum {extension,
+ plugin,
+#ifdef HAVE_LCD_BITMAP
+ icon,
+#endif
+ last};
+
+ int i;
+ int fd;
+ char* end;
+ char* cp;
+ char* str[last];
+ char buf[80];
+
+ fd = open(file, O_RDONLY);
+ if (fd < 0)
+ return false;
+
+ while (read_line(fd, buf, sizeof(buf)))
+ {
+ if (cnt_exttypes >= MAX_EXTTYPES)
+ {
+ splash(HZ,true,str(LANG_FILETYPES_EXTENSION_FULL));
+ break;
+ }
+
+ if (cnt_filetypes >= MAX_FILETYPES)
+ {
+ splash(HZ,true,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);
+ i++;
+ }
+
+ /* bail out if no icon and no plugin */
+ if ((!str[plugin] || !strlen(str[plugin])) &&
+#ifdef HAVE_LCD_BITMAP
+ (!str[icon] || !strlen(str[icon])) &&
+#endif
+ strlen(str[extension]))
+ continue;
+
+ /* bail out if no plugin and icon is incorrect*/
+ if ((!str[plugin] || !strlen(str[plugin])) &&
+#ifdef HAVE_LCD_BITMAP
+ (strlen(str[icon]) != ICON_LENGTH*2) &&
+#endif
+ strlen(str[extension]))
+ continue;
+
+ /* bail out if no icon and no plugin and no extension*/
+ if ((!str[plugin] || !strlen(str[plugin])) &&
+#ifdef HAVE_LCD_BITMAP
+ (!str[icon] || !strlen(str[icon])) &&
+#endif
+ (!str[extension] || !strlen(str[extension])))
+ continue;
+
+ /* add extension */
+ if (str[extension])
+ {
+ if (strlen(str[extension]))
+ {
+ cp=get_string(str[extension]);
+ if (cp)
+ {
+ exttypes[cnt_exttypes].type = &filetypes[cnt_filetypes];
+ exttypes[cnt_exttypes].extension = cp;
+ cnt_exttypes++;
+ }
+ else
+ break;
+
+#ifdef HAVE_LCD_BITMAP
+ /* add icon */
+ if (str[icon])
+ {
+ cp = string2icon(str[icon]);
+ if (cp)
+ filetypes[cnt_filetypes].icon = cp;
+ else
+ break;
+ }
+#endif
+ }
+ }
+
+ /* are we able to start plugin from onplay.c ?*/
+ if (str[plugin])
+ {
+ if (strlen(str[plugin]) > MAX_PLUGIN_LENGTH)
+ {
+ splash(HZ, true, str(LANG_FILETYPES_PLUGIN_NAME_LONG));
+ str[plugin] = NULL;
+ }
+ }
+
+ /* add plugin */
+ if (str[plugin])
+ {
+ if (strlen(str[plugin]))
+ {
+ cp=strrchr(str[plugin], '.');
+ if (cp)
+ *cp='\0';
+
+ cp = get_string(str[plugin]);
+ if (cp)
+ filetypes[cnt_filetypes].plugin = cp;
+ else
+ break;
+ }
+ }
+
+ if (filetypes[cnt_filetypes].plugin)
+ cnt_filetypes++;
+ }
+ close(fd);
+
+ return true;
+}
+
+#ifdef HAVE_LCD_BITMAP
+/* convert an ascii hexadecimal icon to a binary icon */
+static char* string2icon(char* str)
+{
+ char tmp[ICON_LENGTH*2];
+ char *cp;
+ int i;
+
+ if (strlen(str)!=ICON_LENGTH*2)
+ return NULL;
+
+ if ((sizeof(string_buffer) +
+ (unsigned int) string_buffer -
+ (unsigned int) next_free_string) < ICON_LENGTH)
+ {
+ splash(HZ,true,str(LANG_FILETYPES_STRING_BUFFER_EMPTY));
+ return NULL;
+ }
+
+ for (i=0; i<12; i++)
+ {
+ 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;
+ }
+
+ 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
+
+/* get string from buffer */
+static char* get_string(char* str)
+{
+ unsigned int l=strlen(str)+1;
+ char* cp;
+
+ if (!str)
+ return NULL;
+
+ if (l <= (sizeof(string_buffer) +
+ (unsigned int) string_buffer -
+ (unsigned int) next_free_string))
+ {
+ strcpy(next_free_string,str);
+ cp=next_free_string;
+ next_free_string=&next_free_string[l];
+ return cp;
+ }
+ else
+ {
+ splash(HZ,true,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)
+ {
+ case ' ' :
+ case '\t' :
+ case '\r' :
+ break;
+
+ default:
+ *free=*cp;
+ free++;
+ break;
+ }
+ cp++;
+ }
+
+ *free='\0';
+}
diff --git a/apps/filetypes.h b/apps/filetypes.h
new file mode 100644
index 0000000000..30bb71a38e
--- /dev/null
+++ b/apps/filetypes.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:
+ *
+ * Copyright (C) 2002 Henrik Backe
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _FILEHANDLE_H_
+#define _FILEHANDLE_H_
+
+#include <stdbool.h>
+#include <tree.h>
+#include <menu.h>
+
+int filetype_get_attr(char*);
+#ifdef HAVE_LCD_BITMAP
+char* filetype_get_icon(int);
+#else
+int filetype_get_icon(int);
+#endif
+char* filetype_get_plugin(struct entry*);
+void filetype_init(void);
+bool filetype_supported(int);
+int filetype_load_menu(struct menu_item*, int);
+void filetype_load_plugin(char*,char*);
+
+struct file_type {
+#ifdef HAVE_LCD_BITMAP
+ 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;
+};
+
+struct ext_type {
+ char* extension; /* extension for which the file type is recognized */
+ struct file_type* type;
+};
+
+#endif
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 93b68bc9c8..b9b4b4d1c1 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -2654,3 +2654,39 @@ desc: spoken only, for wall clock announce
eng: ""
voice: "Current time:"
new:
+
+#Filetypes
+id: LANG_FILETYPES_RESET
+desc: in the manage settings sub menu
+eng: "Reset plugin list"
+new:
+
+id: LANG_FILETYPES_RESET_WAIT
+desc: Filetype reset message
+eng: "Reset plugins, please wait"
+new:
+
+id: LANG_FILETYPES_EXTENSION_FULL
+desc: Extension array full
+eng: "Extension array full"
+new:
+
+id: LANG_FILETYPES_FULL
+desc: Filetype array full
+eng: "Filetype array full"
+new:
+
+id: LANG_FILETYPES_PLUGIN_NAME_LONG
+desc: Viewer plugin name to long
+eng: "Plugin name to long"
+new:
+
+id: LANG_FILETYPES_STRING_BUFFER_EMPTY
+desc: Filetype string buffer empty
+eng: "Filetype string buffer empty"
+new:
+
+id: LANG_ONPLAY_OPEN_WITH
+desc: Onplay open with
+eng: "Open with"
+new:
diff --git a/apps/onplay.c b/apps/onplay.c
index b1b690222b..d864b3b2a9 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -43,11 +43,35 @@
#include "playlist_viewer.h"
#include "talk.h"
#include "onplay.h"
+#include "filetypes.h"
static char* selected_file = NULL;
static int selected_file_attr = 0;
static int onplay_result = ONPLAY_OK;
+static bool list_viewers(void)
+{
+ struct menu_item menu[8];
+ int m, i, result;
+
+ i=filetype_load_menu(menu,sizeof(menu)/sizeof(*menu));
+ if (i)
+ {
+ m = menu_init( menu, i, NULL, NULL, NULL, NULL );
+ result = menu_show(m);
+ if (result >= 0)
+ {
+ menu_exit(m);
+ filetype_load_plugin(menu[result].desc,selected_file);
+ }
+ }
+ else
+ {
+ splash(HZ*2, true, "No viewers found");
+ }
+ return false;
+}
+
/* For playlist options */
struct playlist_args {
int position;
@@ -625,7 +649,7 @@ bool create_dir(void)
int onplay(char* file, int attr)
{
- struct menu_item items[5]; /* increase this if you add entries! */
+ struct menu_item items[6]; /* increase this if you add entries! */
int m, i=0, result;
onplay_result = ONPLAY_OK;
@@ -635,6 +659,14 @@ int onplay(char* file, int attr)
selected_file = file;
selected_file_attr = attr;
+ if (!(attr & ATTR_DIRECTORY))
+ {
+ items[i].desc = str(LANG_ONPLAY_OPEN_WITH);
+ items[i].voice_id = LANG_ONPLAY_OPEN_WITH;
+ items[i].function = list_viewers;
+ i++;
+ }
+
if (((attr & TREE_ATTR_MASK) == TREE_ATTR_MPA) ||
(attr & ATTR_DIRECTORY) ||
((attr & TREE_ATTR_MASK) == TREE_ATTR_M3U))
diff --git a/apps/player/icons.h b/apps/player/icons.h
index c96f821cfa..041f09eca6 100644
--- a/apps/player/icons.h
+++ b/apps/player/icons.h
@@ -16,6 +16,9 @@
* KIND, either express or implied.
*
****************************************************************************/
+#ifndef _ICONS_H_
+#define _ICONS_H_
+
#include <lcd.h>
/*
@@ -25,9 +28,11 @@
#ifdef HAVE_LCD_CHARCELLS
enum {
- Unknown=0x90,
+ Unknown = 0x90,
Plugin = 0x17,
Folder, Mod_Ajz, Language, File, Wps, Playlist, Text, Config,
};
#endif
+
+#endif /* _ICONS_H_ */
diff --git a/apps/plugins/Makefile b/apps/plugins/Makefile
index 940f74f506..367103be67 100644
--- a/apps/plugins/Makefile
+++ b/apps/plugins/Makefile
@@ -53,5 +53,5 @@ $(LINKFILE): $(LDS)
$(CC) -DMEMORYSIZE=$(MEM) $(DEFINES) -x c -E -P $< >$@
clean:
- -rm -f $(ROCKS) $(LINKFILE)
+ -rm -f $(ROCKS) $(LINKFILE) $(OBJDIR)/*.rock
$(MAKE) -C lib clean
diff --git a/apps/recorder/icons.c b/apps/recorder/icons.c
index 1612fc10af..ab5abeaecc 100644
--- a/apps/recorder/icons.c
+++ b/apps/recorder/icons.c
@@ -62,14 +62,9 @@ unsigned char bitmap_icons_6x8[LastIcon][6] =
{ 0x63, 0x7f, 0x3a, 0x7f, 0x63, 0x00 }, /* Mod or ajz file */
{ 0x60, 0x70, 0x38, 0x2c, 0x7e, 0x7e }, /* Font file */
{ 0x3e, 0x2a, 0x3e, 0x2a, 0x2a, 0x3e }, /* Language file */
- { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }, /* Text file */
{ 0x4e, 0x51, 0x51, 0x40, 0x55, 0x55 }, /* Config file */
{ 0x0a, 0x0a, 0x5f, 0x4e, 0x24, 0x18 }, /* Plugin file */
- { 0x2a, 0x7f, 0x41, 0x41, 0x7f, 0x2a }, /* UCL flash file: chip */
- { 0x70, 0x70, 0x7f, 0x7f, 0x70, 0x70 }, /* Chip8 game: joystick */
- { 0x5d, 0x7f, 0x5d, 0x7f, 0x5d, 0x7f }, /* Video file: film strip */
{ 0xff, 0x81, 0xaf, 0xaa, 0x8c, 0xf8 }, /* Bookmark file */
- { 0x18, 0x24, 0x3c, 0x3c, 0x24, 0x18 }, /* JPEG: eye */
};
unsigned char bitmap_icons_7x8[][7] =
diff --git a/apps/recorder/icons.h b/apps/recorder/icons.h
index 30f0cc1f58..3b4947aca7 100644
--- a/apps/recorder/icons.h
+++ b/apps/recorder/icons.h
@@ -16,6 +16,9 @@
* KIND, either express or implied.
*
****************************************************************************/
+#ifndef _ICONS_H_
+#define _ICONS_H_
+
#include <lcd.h>
/*
@@ -28,9 +31,8 @@ enum icons_6x8 {
Box_Filled, Box_Empty, Slider_Horizontal, File,
Folder, Directory, Playlist, Repeat,
Selected, Cursor, Wps, Mod_Ajz,
- Font, Language, Text, Config,
- Plugin, Flashfile, Chip8, Video,
- Bookmark, Jpeg,
+ Font, Language, Config, Plugin,
+ Bookmark,
LastIcon
};
@@ -97,3 +99,5 @@ extern void statusbar_icon_lock(void);
extern void statusbar_time(int hour, int minute);
#endif
#endif /* End HAVE_LCD_BITMAP */
+
+#endif /* _ICONS_H_ */
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index 7150dd239d..46a52ce297 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -43,6 +43,7 @@
#include "screens.h"
#include "talk.h"
#include "timefuncs.h"
+#include "filetypes.h"
#ifdef HAVE_LCD_BITMAP
#include "peakmeter.h"
#endif
@@ -1243,6 +1244,7 @@ static bool manage_settings_menu(void)
{ STR(LANG_FIRMWARE), firmware_browse },
{ STR(LANG_RESET), reset_settings },
{ STR(LANG_SAVE_SETTINGS), settings_save_config },
+ { STR(LANG_FILETYPES_RESET), filetype_reset},
};
m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
diff --git a/apps/tree.c b/apps/tree.c
index 140b226a01..8aa7eb0815 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -56,6 +56,7 @@
#include "power.h"
#include "action.h"
#include "talk.h"
+#include "filetypes.h"
#ifdef HAVE_LCD_BITMAP
#include "widgets.h"
@@ -69,37 +70,24 @@
extern bool language_changed;
/* a table for the know file types */
-static struct
-{
- char* extension; /* extension for which the file type is recognized */
- int tree_attr; /* which identifier */
- int icon; /* the icon which shall be used for it, -1 if unknown */
- int voiceclip; /* spoken extension */
- /* To have it extendable, there could be more useful stuff in here,
- like handler functions, plugin name, etc. */
-} filetypes[] = {
+struct filetype filetypes[] = {
{ ".mp3", TREE_ATTR_MPA, File, VOICE_EXT_MPA },
{ ".mp2", TREE_ATTR_MPA, File, VOICE_EXT_MPA },
{ ".mpa", TREE_ATTR_MPA, File, VOICE_EXT_MPA },
{ ".m3u", TREE_ATTR_M3U, Playlist, LANG_PLAYINDICES_PLAYLIST },
{ ".cfg", TREE_ATTR_CFG, Config, VOICE_EXT_CFG },
{ ".wps", TREE_ATTR_WPS, Wps, VOICE_EXT_WPS },
- { ".txt", TREE_ATTR_TXT, Text, VOICE_EXT_TXT },
{ ".lng", TREE_ATTR_LNG, Language, LANG_LANGUAGE },
{ ".rock",TREE_ATTR_ROCK,Plugin, VOICE_EXT_ROCK },
#ifdef HAVE_LCD_BITMAP
{ ".fnt", TREE_ATTR_FONT,Font, VOICE_EXT_FONT },
- { ".ch8", TREE_ATTR_CH8, Chip8, -1 },
- { ".rvf", TREE_ATTR_RVF, Video, -1 },
{ ".bmark",TREE_ATTR_BMARK, Bookmark, VOICE_EXT_BMARK },
#else
- { ".bmark", TREE_ATTR_BMARK, -1, VOICE_EXT_BMARK },
+ { ".bmark", TREE_ATTR_BMARK, -1, VOICE_EXT_BMARK },
#endif
#ifndef SIMULATOR
#ifdef HAVE_LCD_BITMAP
- { ".ucl", TREE_ATTR_UCL, Flashfile, VOICE_EXT_UCL },
{ ".ajz", TREE_ATTR_MOD, Mod_Ajz, VOICE_EXT_AJZ },
- { ".jpg", TREE_ATTR_JPEG, Jpeg, -1 },
#else
{ ".mod", TREE_ATTR_MOD, Mod_Ajz, VOICE_EXT_AJZ },
#endif
@@ -136,6 +124,7 @@ static bool dirbrowse(char *root, int *dirfilter);
void browse_root(void)
{
+ filetype_init();
#ifndef SIMULATOR
dirbrowse("/", &global_settings.dirfilter);
#else
@@ -145,6 +134,11 @@ void browse_root(void)
#endif
}
+void tree_get_filetypes(struct filetype** types, int* count)
+{
+ *types = filetypes;
+ *count = sizeof(filetypes) / sizeof(*filetypes);
+}
#ifdef HAVE_LCD_BITMAP
@@ -359,19 +353,7 @@ struct entry* load_and_sort_directory(char *dirname, int *dirfilter,
/* check for known file types */
if ( !(dptr->attr & ATTR_DIRECTORY) && (len > 4) )
- {
- unsigned j;
- for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++)
- {
- if (!strcasecmp(
- &entry->d_name[len-strlen(filetypes[j].extension)],
- filetypes[j].extension))
- {
- dptr->attr |= filetypes[j].tree_attr;
- break;
- }
- }
- }
+ dptr->attr |= filetype_get_attr(entry->d_name);
/* memorize/compare details about the boot file */
if ((currdir[1] == 0) && !strcasecmp(entry->d_name, BOOTFILE)) {
@@ -391,7 +373,7 @@ struct entry* load_and_sort_directory(char *dirname, int *dirfilter,
((*dirfilter == SHOW_MUSIC &&
(dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_MPA) &&
(dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_M3U) ||
- (*dirfilter == SHOW_SUPPORTED && !(dptr->attr & TREE_ATTR_MASK)) ||
+ (*dirfilter == SHOW_SUPPORTED && !filetype_supported(dptr->attr)) ||
(*dirfilter == SHOW_WPS && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_WPS) ||
(*dirfilter == SHOW_CFG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_CFG) ||
(*dirfilter == SHOW_LNG && (dptr->attr & TREE_ATTR_MASK) != TREE_ATTR_LNG) ||
@@ -444,12 +426,12 @@ static int recalc_screen_height(void)
static int showdir(char *path, int start, int *dirfilter)
{
- int icon_type = 0;
int i;
int tree_max_on_screen;
bool dir_buffer_full;
#ifdef HAVE_LCD_BITMAP
+ char* icon;
int line_height;
int fw, fh;
lcd_setfont(FONT_UI);
@@ -457,6 +439,7 @@ static int showdir(char *path, int start, int *dirfilter)
tree_max_on_screen = recalc_screen_height();
line_height = fh;
#else
+ int icon;
tree_max_on_screen = TREE_MAX_ON_SCREEN;
#endif
@@ -536,52 +519,24 @@ static int showdir(char *path, int start, int *dirfilter)
#endif
for ( i=start; i < start+tree_max_on_screen; i++ ) {
- int len;
- unsigned j;
-
if ( i >= filesindir )
break;
- len = strlen(dircache[i].name);
-
- if (dircache[i].attr & ATTR_DIRECTORY)
- {
- icon_type = Folder;
- }
- else
- {
- /* search which icon to use */
- icon_type = -1; /* default to none */
- for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++)
- {
- if ((dircache[i].attr & TREE_ATTR_MASK) == filetypes[j].tree_attr)
- {
- icon_type = filetypes[j].icon;
- break;
- }
- }
-
- if (icon_type == -1)
- {
-#ifdef HAVE_LCD_BITMAP
- icon_type = 0;
-#else
- icon_type = Unknown;
-#endif
- }
- }
+ icon = filetype_get_icon(dircache[i].attr);
- if (icon_type && global_settings.show_icons) {
+ if (icon && global_settings.show_icons) {
#ifdef HAVE_LCD_BITMAP
int offset=0;
if ( line_height > 8 )
offset = (line_height - 8) / 2;
- lcd_bitmap(bitmap_icons_6x8[icon_type],
+ lcd_bitmap(icon,
CURSOR_X * 6 + CURSOR_WIDTH,
MARGIN_Y+(i-start)*line_height + offset,
6, 8, true);
#else
- lcd_putc(LINE_X-1, i-start, icon_type);
+ if (icon < 0 )
+ icon = Unknown;
+ lcd_putc(LINE_X-1, i-start, icon);
#endif
}
@@ -1005,6 +960,9 @@ static bool dirbrowse(char *root, int *dirfilter)
else
currdir[i-1]=0;
+ if (*dirfilter > NUM_FILTER_MODES && dirlevel < 1)
+ exit_func = true;
+
dirlevel--;
if ( dirlevel < MAX_DIR_LEVELS ) {
dirstart = dirpos[dirlevel];
@@ -1018,8 +976,11 @@ static bool dirbrowse(char *root, int *dirfilter)
restore = true;
}
- if (*dirfilter > NUM_FILTER_MODES)
- exit_func = true;
+ else
+ {
+ if (*dirfilter > NUM_FILTER_MODES && dirlevel < 1)
+ exit_func = true;
+ }
break;
#ifdef HAVE_RECORDER_KEYPAD
@@ -1171,11 +1132,6 @@ static bool dirbrowse(char *root, int *dirfilter)
reload_dir = true;
break;
- case TREE_ATTR_TXT:
- plugin_load("/.rockbox/rocks/viewer.rock",buf);
- restore = true;
- break;
-
case TREE_ATTR_LNG:
if(!lang_load(buf)) {
set_file(buf, global_settings.lang_file,
@@ -1189,21 +1145,6 @@ static bool dirbrowse(char *root, int *dirfilter)
break;
#ifdef HAVE_LCD_BITMAP
- /* chip-8 game */
- case TREE_ATTR_CH8:
- plugin_load("/.rockbox/rocks/chip8.rock",buf);
- break;
-
- /* "movie" animation */
- case TREE_ATTR_RVF:
- plugin_load("/.rockbox/rocks/video.rock",buf);
- break;
-
- /* JPEG image */
- case TREE_ATTR_JPEG:
- plugin_load("/.rockbox/rocks/jpeg.rock",buf);
- break;
-
case TREE_ATTR_FONT:
font_load(buf);
set_file(buf, global_settings.font_file,
@@ -1224,11 +1165,6 @@ static bool dirbrowse(char *root, int *dirfilter)
case TREE_ATTR_MOD:
rolo_load(buf);
break;
-
- /* ucl flash file */
- case TREE_ATTR_UCL:
- plugin_load("/.rockbox/rocks/rockbox_flash.rock",buf);
- break;
#endif
/* plugin file */
@@ -1238,6 +1174,19 @@ static bool dirbrowse(char *root, int *dirfilter)
else
restore = true;
break;
+
+ default:
+ {
+ char* plugin = filetype_get_plugin(file);
+ if (plugin)
+ {
+ if (plugin_load(plugin,buf) == PLUGIN_USB_CONNECTED)
+ reload_root = true;
+ else
+ restore = true;
+ }
+ break;
+ }
}
if ( play ) {
@@ -1389,8 +1338,8 @@ static bool dirbrowse(char *root, int *dirfilter)
#endif
restore = true;
}
- break;
#endif
+ break;
case SYS_USB_CONNECTED:
status_set_playmode(STATUS_STOP);
diff --git a/apps/tree.h b/apps/tree.h
index 2bd133d3e9..367a4fad00 100644
--- a/apps/tree.h
+++ b/apps/tree.h
@@ -26,23 +26,27 @@ struct entry {
char *name;
};
+struct filetype {
+ char* extension;
+ int tree_attr;
+ int icon;
+ int voiceclip;
+};
+
+
/* using attribute not used by FAT */
-#define TREE_ATTR_MPA 0x0100 /* mpeg audio file */
-#define TREE_ATTR_M3U 0x0200 /* playlist */
-#define TREE_ATTR_WPS 0x0300 /* wps config file */
-#define TREE_ATTR_MOD 0x0400 /* firmware file */
-#define TREE_ATTR_CFG 0x0500 /* config file */
-#define TREE_ATTR_TXT 0x0600 /* text file */
-#define TREE_ATTR_FONT 0x0700 /* font file */
-#define TREE_ATTR_LNG 0x0800 /* binary lang file */
-#define TREE_ATTR_ROCK 0x0900 /* binary rockbox plugin */
-#define TREE_ATTR_UCL 0x0A00 /* rockbox flash image */
-#define TREE_ATTR_CH8 0x0B00 /* chip-8 game */
-#define TREE_ATTR_RVF 0x0C00 /* rockbox video file */
-#define TREE_ATTR_BMARK 0x0D00 /* book mark file */
-#define TREE_ATTR_JPEG 0x0E00 /* JPEG image */
-#define TREE_ATTR_MASK 0xFFC0 /* which bits tree.c uses (above) */
+#define TREE_ATTR_MPA 0x0100 /* mpeg audio file */
+#define TREE_ATTR_M3U 0x0200 /* playlist */
+#define TREE_ATTR_WPS 0x0300 /* wps config file */
+#define TREE_ATTR_MOD 0x0400 /* firmware file */
+#define TREE_ATTR_CFG 0x0500 /* config file */
+#define TREE_ATTR_FONT 0x0600 /* font file */
+#define TREE_ATTR_LNG 0x0700 /* binary lang file */
+#define TREE_ATTR_ROCK 0x0800 /* binary rockbox plugin */
+#define TREE_ATTR_BMARK 0x0900 /* book mark file */
+#define TREE_ATTR_MASK 0xFFC0 /* which bits tree.c uses (above) */
+void tree_get_filetypes(struct filetype**, int*);
void tree_init(void);
void browse_root(void);
void set_current_file(char *path);
diff --git a/uisimulator/win32/Makefile b/uisimulator/win32/Makefile
index 05acb9c41c..59ef7f5206 100644
--- a/uisimulator/win32/Makefile
+++ b/uisimulator/win32/Makefile
@@ -103,7 +103,7 @@ FIRMSRCS = $(LCDSRSC) id3.c mp3data.c usb.c mpeg.c mp3_playback.c \
APPS = main.c tree.c menu.c credits.c main_menu.c icons.c language.c \
playlist.c wps.c wps-display.c settings.c status.c \
screens.c peakmeter.c sleeptimer.c keyboard.c onplay.c\
- misc.c plugin.c playlist_viewer.c bookmark.c
+ misc.c plugin.c playlist_viewer.c bookmark.c filetypes.c
MENUS = settings_menu.c sound_menu.c playlist_menu.c
@@ -199,6 +199,9 @@ $(OBJDIR)/tree.o: $(APPDIR)/tree.c
$(OBJDIR)/onplay.o: $(APPDIR)/onplay.c
$(CC) $(APPCFLAGS) -c $< -o $@
+$(OBJDIR)/filetypes.o: $(APPDIR)/filetypes.c
+ $(CC) $(APPCFLAGS) -c $< -o $@
+
$(OBJDIR)/playlist.o: $(APPDIR)/playlist.c
$(CC) $(APPCFLAGS) -c $< -o $@
diff --git a/uisimulator/x11/Makefile b/uisimulator/x11/Makefile
index 6fbc413a3c..65f0b8d5a2 100644
--- a/uisimulator/x11/Makefile
+++ b/uisimulator/x11/Makefile
@@ -102,7 +102,7 @@ FIRMSRCS = $(LCDSRSC) id3.c debug.c usb.c mpeg.c mp3_playback.c power.c\
APPS = main.c tree.c menu.c credits.c main_menu.c language.c\
playlist.c wps.c wps-display.c settings.c status.c icons.c\
screens.c peakmeter.c sleeptimer.c keyboard.c onplay.c\
- misc.c plugin.c playlist_viewer.c bookmark.c
+ misc.c plugin.c playlist_viewer.c bookmark.c filetypes.c
MENUS = settings_menu.c sound_menu.c playlist_menu.c
@@ -142,6 +142,9 @@ $(OBJDIR)/credits.raw: $(DOCSDIR)/CREDITS
$(OBJDIR)/credits.o: $(APPDIR)/credits.c $(APPDIR)/credits.h $(OBJDIR)/credits.raw
$(CC) $(APPCFLAGS) -c $< -o $@
+$(OBJDIR)/filetypes.o: $(APPDIR)/filetypes.c
+ $(CC) $(APPCFLAGS) -c $< -o $@
+
$(OBJDIR)/menu.o: $(APPDIR)/menu.c
$(CC) $(APPCFLAGS) -c $< -o $@