Create index array to filetypes used in the open with list while loading viewers.config.
Reduced stack usage of filetype_list_viewers(). Additionally, do not allocate buffer twice for same plugin name. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28538 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
598f56ecb2
commit
7d3f8c0921
1 changed files with 53 additions and 51 deletions
104
apps/filetypes.c
104
apps/filetypes.c
|
@ -46,8 +46,14 @@
|
|||
#else
|
||||
#define MAX_FILETYPES 128
|
||||
#endif
|
||||
/* max viewer plugins */
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#define MAX_VIEWERS 56
|
||||
#else
|
||||
#define MAX_VIEWERS 24
|
||||
#endif
|
||||
|
||||
/* a table for the know file types */
|
||||
/* a table for the known file types */
|
||||
static const struct filetype inbuilt_filetypes[] = {
|
||||
{ "mp3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||
{ "mp2", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||
|
@ -134,7 +140,7 @@ static const struct filetype inbuilt_filetypes[] = {
|
|||
{ "rsbs", FILE_ATTR_RSBS, Icon_Wps, VOICE_EXT_RSBS },
|
||||
#if CONFIG_TUNER
|
||||
{ "rfms", FILE_ATTR_RFMS, Icon_Wps, VOICE_EXT_RFMS },
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifdef BOOTFILE_EXT
|
||||
{ BOOTFILE_EXT, FILE_ATTR_MOD, Icon_Firmware, VOICE_EXT_AJZ },
|
||||
|
@ -150,7 +156,6 @@ void tree_get_filetypes(const struct filetype** types, int* count)
|
|||
*count = sizeof(inbuilt_filetypes) / sizeof(*inbuilt_filetypes);
|
||||
}
|
||||
|
||||
/* mask for dynamic filetype info in attribute */
|
||||
#define ROCK_EXTENSION "rock"
|
||||
|
||||
struct file_type {
|
||||
|
@ -165,8 +170,11 @@ static bool custom_icons_loaded = false;
|
|||
#ifdef HAVE_LCD_COLOR
|
||||
static int custom_colors[MAX_FILETYPES+1];
|
||||
#endif
|
||||
/* index array to filetypes used in open with list. */
|
||||
static int viewers[MAX_VIEWERS];
|
||||
static int filetype_count = 0;
|
||||
static unsigned char highest_attr = 0;
|
||||
static int viewer_count = 0;
|
||||
|
||||
static char *filetypes_strdup(char* string)
|
||||
{
|
||||
|
@ -174,6 +182,20 @@ static char *filetypes_strdup(char* string)
|
|||
strcpy(buffer, string);
|
||||
return buffer;
|
||||
}
|
||||
static char *filetypes_store_plugin(char *plugin, int n)
|
||||
{
|
||||
int i;
|
||||
/* if the plugin is in the list already, use it. */
|
||||
for (i=0; i<viewer_count; i++)
|
||||
{
|
||||
if (!strcmp(filetypes[viewers[i]].plugin, plugin))
|
||||
return filetypes[viewers[i]].plugin;
|
||||
}
|
||||
/* otherwise, allocate buffer */
|
||||
if (viewer_count < MAX_VIEWERS)
|
||||
viewers[viewer_count++] = n;
|
||||
return filetypes_strdup(plugin);
|
||||
}
|
||||
static void read_builtin_types(void);
|
||||
static void read_config(const char* config_file);
|
||||
#ifdef HAVE_LCD_COLOR
|
||||
|
@ -279,7 +301,8 @@ void filetype_init(void)
|
|||
filetypes[0].plugin = NULL;
|
||||
filetypes[0].attr = 0;
|
||||
filetypes[0].icon = Icon_Folder;
|
||||
|
||||
|
||||
viewer_count = 0;
|
||||
filetype_count = 1;
|
||||
read_builtin_types();
|
||||
read_config(get_user_file_path(VIEWERS_CONFIG, IS_FILE, path, sizeof(path)));
|
||||
|
@ -325,14 +348,14 @@ static void read_builtin_types(void)
|
|||
static void read_config(const char* config_file)
|
||||
{
|
||||
char line[64], *s, *e;
|
||||
char extension[8], plugin[32];
|
||||
char *extension, *plugin;
|
||||
int fd = open(config_file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return;
|
||||
/* config file is in the for
|
||||
/* config file is in the format
|
||||
<extension>,<plugin>,<icon code>
|
||||
ignore line if either of the first two are missing */
|
||||
while (read_line(fd, line, 64) > 0)
|
||||
while (read_line(fd, line, sizeof line) > 0)
|
||||
{
|
||||
if (filetype_count >= MAX_FILETYPES)
|
||||
{
|
||||
|
@ -346,30 +369,31 @@ static void read_config(const char* config_file)
|
|||
if (!e)
|
||||
continue;
|
||||
*e = '\0';
|
||||
strcpy(extension, s);
|
||||
|
||||
extension = s;
|
||||
|
||||
/* get the plugin */
|
||||
s = e+1;
|
||||
e = strchr(s, ',');
|
||||
if (!e)
|
||||
continue;
|
||||
*e = '\0';
|
||||
|
||||
strcpy(plugin, s);
|
||||
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].attr = highest_attr +1;
|
||||
filetypes[filetype_count].icon = Icon_Questionmark;
|
||||
struct file_type *file_type = &filetypes[filetype_count];
|
||||
file_type->extension = filetypes_strdup(extension);
|
||||
file_type->plugin = filetypes_store_plugin(plugin, filetype_count);
|
||||
file_type->attr = highest_attr +1;
|
||||
file_type->icon = Icon_Questionmark;
|
||||
highest_attr++;
|
||||
/* get the icon */
|
||||
s = e+1;
|
||||
if (*s == '*')
|
||||
filetypes[filetype_count].icon = atoi(s+1);
|
||||
file_type->icon = atoi(s+1);
|
||||
else if (*s == '-')
|
||||
filetypes[filetype_count].icon = Icon_NOICON;
|
||||
file_type->icon = Icon_NOICON;
|
||||
else if (*s >= '0' && *s <= '9')
|
||||
filetypes[filetype_count].icon = Icon_Last_Themeable + atoi(s);
|
||||
file_type->icon = Icon_Last_Themeable + atoi(s);
|
||||
filetype_count++;
|
||||
}
|
||||
close(fd);
|
||||
|
@ -450,45 +474,40 @@ char* filetype_get_plugin(const struct entry* file)
|
|||
return plugin_name;
|
||||
}
|
||||
|
||||
bool filetype_supported(int attr)
|
||||
bool filetype_supported(int attr)
|
||||
{
|
||||
return find_attr(attr) >= 0;
|
||||
}
|
||||
|
||||
/**** Open With Screen ****/
|
||||
struct cb_data {
|
||||
int *items;
|
||||
const char *current_file;
|
||||
};
|
||||
|
||||
static enum themable_icons openwith_get_icon(int selected_item, void * data)
|
||||
{
|
||||
struct cb_data *info = (struct cb_data *)data;
|
||||
int *items = info->items;
|
||||
return filetypes[items[selected_item]].icon;
|
||||
(void)data;
|
||||
return filetypes[viewers[selected_item]].icon;
|
||||
}
|
||||
|
||||
static const char* openwith_get_name(int selected_item, void * data,
|
||||
char * buffer, size_t buffer_len)
|
||||
{
|
||||
(void)buffer; (void)buffer_len;
|
||||
struct cb_data *info = (struct cb_data *)data;
|
||||
int *items = info->items;
|
||||
const char *s = strrchr(filetypes[items[selected_item]].plugin, '/');
|
||||
(void)data; (void)buffer; (void)buffer_len;
|
||||
const char *s = strrchr(filetypes[viewers[selected_item]].plugin, '/');
|
||||
if (s)
|
||||
return s+1;
|
||||
else return filetypes[items[selected_item]].plugin;
|
||||
else return filetypes[viewers[selected_item]].plugin;
|
||||
}
|
||||
|
||||
static int openwith_action_callback(int action, struct gui_synclist *lists)
|
||||
{
|
||||
struct cb_data *info = (struct cb_data *)lists->data;
|
||||
int *items = info->items;
|
||||
int i;
|
||||
if (action == ACTION_STD_OK)
|
||||
{
|
||||
char plugin[MAX_PATH];
|
||||
i = items[gui_synclist_get_sel_pos(lists)];
|
||||
i = viewers[gui_synclist_get_sel_pos(lists)];
|
||||
snprintf(plugin, MAX_PATH, "%s/%s.%s",
|
||||
PLUGIN_DIR, filetypes[i].plugin, ROCK_EXTENSION);
|
||||
plugin_load(plugin, info->current_file);
|
||||
|
@ -499,34 +518,17 @@ static int openwith_action_callback(int action, struct gui_synclist *lists)
|
|||
|
||||
int filetype_list_viewers(const char* current_file)
|
||||
{
|
||||
int i, count = 0;
|
||||
int items[MAX_FILETYPES];
|
||||
struct simplelist_info info;
|
||||
struct cb_data data = { items, current_file };
|
||||
for (i=0; i<filetype_count && count < MAX_FILETYPES; i++)
|
||||
{
|
||||
if (filetypes[i].plugin)
|
||||
{
|
||||
int j;
|
||||
for (j=0;j<count;j++) /* check if the plugin is in the list yet */
|
||||
{
|
||||
if (!strcmp(filetypes[i].plugin,filetypes[items[j]].plugin))
|
||||
break;
|
||||
}
|
||||
if (j<count)
|
||||
continue; /* it is so grab the next plugin */
|
||||
items[count++] = i;
|
||||
}
|
||||
}
|
||||
struct cb_data data = { current_file };
|
||||
#ifndef HAVE_LCD_BITMAP
|
||||
if (count == 0)
|
||||
if (viewer_count == 0)
|
||||
{
|
||||
/* FIX: translation! */
|
||||
splash(HZ*2, "No viewers found");
|
||||
return PLUGIN_OK;
|
||||
}
|
||||
#endif
|
||||
simplelist_info_init(&info, str(LANG_ONPLAY_OPEN_WITH), count, &data);
|
||||
simplelist_info_init(&info, str(LANG_ONPLAY_OPEN_WITH), viewer_count, &data);
|
||||
info.action_callback = openwith_action_callback;
|
||||
info.get_name = openwith_get_name;
|
||||
info.get_icon = global_settings.show_icons?openwith_get_icon:NULL;
|
||||
|
@ -538,7 +540,7 @@ int filetype_load_plugin(const char* plugin, char* file)
|
|||
int i;
|
||||
char plugin_name[MAX_PATH];
|
||||
char *s;
|
||||
|
||||
|
||||
for (i=0;i<filetype_count;i++)
|
||||
{
|
||||
if (filetypes[i].plugin)
|
||||
|
|
Loading…
Reference in a new issue