mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-13 18:17:39 -04:00
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
|
#else
|
||||||
#define MAX_FILETYPES 128
|
#define MAX_FILETYPES 128
|
||||||
#endif
|
#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[] = {
|
static const struct filetype inbuilt_filetypes[] = {
|
||||||
{ "mp3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
{ "mp3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||||
{ "mp2", 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 },
|
{ "rsbs", FILE_ATTR_RSBS, Icon_Wps, VOICE_EXT_RSBS },
|
||||||
#if CONFIG_TUNER
|
#if CONFIG_TUNER
|
||||||
{ "rfms", FILE_ATTR_RFMS, Icon_Wps, VOICE_EXT_RFMS },
|
{ "rfms", FILE_ATTR_RFMS, Icon_Wps, VOICE_EXT_RFMS },
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef BOOTFILE_EXT
|
#ifdef BOOTFILE_EXT
|
||||||
{ BOOTFILE_EXT, FILE_ATTR_MOD, Icon_Firmware, VOICE_EXT_AJZ },
|
{ 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);
|
*count = sizeof(inbuilt_filetypes) / sizeof(*inbuilt_filetypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mask for dynamic filetype info in attribute */
|
|
||||||
#define ROCK_EXTENSION "rock"
|
#define ROCK_EXTENSION "rock"
|
||||||
|
|
||||||
struct file_type {
|
struct file_type {
|
||||||
|
@ -165,8 +170,11 @@ static bool custom_icons_loaded = false;
|
||||||
#ifdef HAVE_LCD_COLOR
|
#ifdef HAVE_LCD_COLOR
|
||||||
static int custom_colors[MAX_FILETYPES+1];
|
static int custom_colors[MAX_FILETYPES+1];
|
||||||
#endif
|
#endif
|
||||||
|
/* index array to filetypes used in open with list. */
|
||||||
|
static int viewers[MAX_VIEWERS];
|
||||||
static int filetype_count = 0;
|
static int filetype_count = 0;
|
||||||
static unsigned char highest_attr = 0;
|
static unsigned char highest_attr = 0;
|
||||||
|
static int viewer_count = 0;
|
||||||
|
|
||||||
static char *filetypes_strdup(char* string)
|
static char *filetypes_strdup(char* string)
|
||||||
{
|
{
|
||||||
|
@ -174,6 +182,20 @@ static char *filetypes_strdup(char* string)
|
||||||
strcpy(buffer, string);
|
strcpy(buffer, string);
|
||||||
return buffer;
|
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_builtin_types(void);
|
||||||
static void read_config(const char* config_file);
|
static void read_config(const char* config_file);
|
||||||
#ifdef HAVE_LCD_COLOR
|
#ifdef HAVE_LCD_COLOR
|
||||||
|
@ -279,7 +301,8 @@ void filetype_init(void)
|
||||||
filetypes[0].plugin = NULL;
|
filetypes[0].plugin = NULL;
|
||||||
filetypes[0].attr = 0;
|
filetypes[0].attr = 0;
|
||||||
filetypes[0].icon = Icon_Folder;
|
filetypes[0].icon = Icon_Folder;
|
||||||
|
|
||||||
|
viewer_count = 0;
|
||||||
filetype_count = 1;
|
filetype_count = 1;
|
||||||
read_builtin_types();
|
read_builtin_types();
|
||||||
read_config(get_user_file_path(VIEWERS_CONFIG, IS_FILE, path, sizeof(path)));
|
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)
|
static void read_config(const char* config_file)
|
||||||
{
|
{
|
||||||
char line[64], *s, *e;
|
char line[64], *s, *e;
|
||||||
char extension[8], plugin[32];
|
char *extension, *plugin;
|
||||||
int fd = open(config_file, O_RDONLY);
|
int fd = open(config_file, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return;
|
return;
|
||||||
/* config file is in the for
|
/* config file is in the format
|
||||||
<extension>,<plugin>,<icon code>
|
<extension>,<plugin>,<icon code>
|
||||||
ignore line if either of the first two are missing */
|
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)
|
if (filetype_count >= MAX_FILETYPES)
|
||||||
{
|
{
|
||||||
|
@ -346,30 +369,31 @@ static void read_config(const char* config_file)
|
||||||
if (!e)
|
if (!e)
|
||||||
continue;
|
continue;
|
||||||
*e = '\0';
|
*e = '\0';
|
||||||
strcpy(extension, s);
|
extension = s;
|
||||||
|
|
||||||
/* get the plugin */
|
/* get the plugin */
|
||||||
s = e+1;
|
s = e+1;
|
||||||
e = strchr(s, ',');
|
e = strchr(s, ',');
|
||||||
if (!e)
|
if (!e)
|
||||||
continue;
|
continue;
|
||||||
*e = '\0';
|
*e = '\0';
|
||||||
|
plugin = s;
|
||||||
strcpy(plugin, s);
|
|
||||||
/* ok, store this plugin/extension, check icon after */
|
/* ok, store this plugin/extension, check icon after */
|
||||||
filetypes[filetype_count].extension = filetypes_strdup(extension);
|
struct file_type *file_type = &filetypes[filetype_count];
|
||||||
filetypes[filetype_count].plugin = filetypes_strdup(plugin);
|
file_type->extension = filetypes_strdup(extension);
|
||||||
filetypes[filetype_count].attr = highest_attr +1;
|
file_type->plugin = filetypes_store_plugin(plugin, filetype_count);
|
||||||
filetypes[filetype_count].icon = Icon_Questionmark;
|
file_type->attr = highest_attr +1;
|
||||||
|
file_type->icon = Icon_Questionmark;
|
||||||
highest_attr++;
|
highest_attr++;
|
||||||
/* get the icon */
|
/* get the icon */
|
||||||
s = e+1;
|
s = e+1;
|
||||||
if (*s == '*')
|
if (*s == '*')
|
||||||
filetypes[filetype_count].icon = atoi(s+1);
|
file_type->icon = atoi(s+1);
|
||||||
else if (*s == '-')
|
else if (*s == '-')
|
||||||
filetypes[filetype_count].icon = Icon_NOICON;
|
file_type->icon = Icon_NOICON;
|
||||||
else if (*s >= '0' && *s <= '9')
|
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++;
|
filetype_count++;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -450,45 +474,40 @@ char* filetype_get_plugin(const struct entry* file)
|
||||||
return plugin_name;
|
return plugin_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool filetype_supported(int attr)
|
bool filetype_supported(int attr)
|
||||||
{
|
{
|
||||||
return find_attr(attr) >= 0;
|
return find_attr(attr) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**** Open With Screen ****/
|
/**** Open With Screen ****/
|
||||||
struct cb_data {
|
struct cb_data {
|
||||||
int *items;
|
|
||||||
const char *current_file;
|
const char *current_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum themable_icons openwith_get_icon(int selected_item, void * data)
|
static enum themable_icons openwith_get_icon(int selected_item, void * data)
|
||||||
{
|
{
|
||||||
struct cb_data *info = (struct cb_data *)data;
|
(void)data;
|
||||||
int *items = info->items;
|
return filetypes[viewers[selected_item]].icon;
|
||||||
return filetypes[items[selected_item]].icon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* openwith_get_name(int selected_item, void * data,
|
static const char* openwith_get_name(int selected_item, void * data,
|
||||||
char * buffer, size_t buffer_len)
|
char * buffer, size_t buffer_len)
|
||||||
{
|
{
|
||||||
(void)buffer; (void)buffer_len;
|
(void)data; (void)buffer; (void)buffer_len;
|
||||||
struct cb_data *info = (struct cb_data *)data;
|
const char *s = strrchr(filetypes[viewers[selected_item]].plugin, '/');
|
||||||
int *items = info->items;
|
|
||||||
const char *s = strrchr(filetypes[items[selected_item]].plugin, '/');
|
|
||||||
if (s)
|
if (s)
|
||||||
return s+1;
|
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)
|
static int openwith_action_callback(int action, struct gui_synclist *lists)
|
||||||
{
|
{
|
||||||
struct cb_data *info = (struct cb_data *)lists->data;
|
struct cb_data *info = (struct cb_data *)lists->data;
|
||||||
int *items = info->items;
|
|
||||||
int i;
|
int i;
|
||||||
if (action == ACTION_STD_OK)
|
if (action == ACTION_STD_OK)
|
||||||
{
|
{
|
||||||
char plugin[MAX_PATH];
|
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",
|
snprintf(plugin, MAX_PATH, "%s/%s.%s",
|
||||||
PLUGIN_DIR, filetypes[i].plugin, ROCK_EXTENSION);
|
PLUGIN_DIR, filetypes[i].plugin, ROCK_EXTENSION);
|
||||||
plugin_load(plugin, info->current_file);
|
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 filetype_list_viewers(const char* current_file)
|
||||||
{
|
{
|
||||||
int i, count = 0;
|
|
||||||
int items[MAX_FILETYPES];
|
|
||||||
struct simplelist_info info;
|
struct simplelist_info info;
|
||||||
struct cb_data data = { items, current_file };
|
struct cb_data data = { 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifndef HAVE_LCD_BITMAP
|
#ifndef HAVE_LCD_BITMAP
|
||||||
if (count == 0)
|
if (viewer_count == 0)
|
||||||
{
|
{
|
||||||
/* FIX: translation! */
|
/* FIX: translation! */
|
||||||
splash(HZ*2, "No viewers found");
|
splash(HZ*2, "No viewers found");
|
||||||
return PLUGIN_OK;
|
return PLUGIN_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#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.action_callback = openwith_action_callback;
|
||||||
info.get_name = openwith_get_name;
|
info.get_name = openwith_get_name;
|
||||||
info.get_icon = global_settings.show_icons?openwith_get_icon:NULL;
|
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;
|
int i;
|
||||||
char plugin_name[MAX_PATH];
|
char plugin_name[MAX_PATH];
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
for (i=0;i<filetype_count;i++)
|
for (i=0;i<filetype_count;i++)
|
||||||
{
|
{
|
||||||
if (filetypes[i].plugin)
|
if (filetypes[i].plugin)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue