From fb00c2190bab443812581473032156eb1e804c30 Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Fri, 21 May 2004 20:08:24 +0000 Subject: Plugin/file type association system. Patch #879411 by Henrik Backe git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4677 a1c6a512-1295-4272-9138-f99709370657 --- apps/filetypes.c | 688 +++++++++++++++++++++++++++++++++++++++++++++ apps/filetypes.h | 53 ++++ apps/lang/english.lang | 36 +++ apps/onplay.c | 34 ++- apps/player/icons.h | 7 +- apps/plugins/Makefile | 2 +- apps/recorder/icons.c | 5 - apps/recorder/icons.h | 10 +- apps/settings_menu.c | 2 + apps/tree.c | 133 +++------ apps/tree.h | 34 ++- uisimulator/win32/Makefile | 5 +- uisimulator/x11/Makefile | 5 +- 13 files changed, 894 insertions(+), 120 deletions(-) create mode 100644 apps/filetypes.c create mode 100644 apps/filetypes.h 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 +#include +#include +#include + +#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 +#include +#include + +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 /* @@ -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 /* @@ -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; jd_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 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 $@ -- cgit v1.2.3