mirror of
				https://github.com/Rockbox/rockbox.git
				synced 2025-10-26 23:36:37 -04:00 
			
		
		
		
	git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11737 a1c6a512-1295-4272-9138-f99709370657
		
			
				
	
	
		
			826 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			826 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /***************************************************************************
 | |
|  *             __________               __   ___.
 | |
|  *   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"
 | |
| #include "splash.h"
 | |
| 
 | |
| /* max plugin name size without extensions and path */
 | |
| #define MAX_PLUGIN_LENGTH 32
 | |
| 
 | |
| /* max filetypes (plugins & icons stored here) */
 | |
| #if CONFIG_CODEC == SWCODEC
 | |
| #define MAX_FILETYPES 64
 | |
| #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];
 | |
| 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(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)
 | |
| {
 | |
|     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();
 | |
| }
 | |
| 
 | |
| /* get icon */
 | |
| #ifdef HAVE_LCD_BITMAP
 | |
| const unsigned 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 Icon_Unknown;
 | |
| #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;
 | |
| }
 | |
| 
 | |
| /* start a plugin with an argument (called from onplay.c) */
 | |
| int filetype_load_plugin(const char* plugin, char* file)
 | |
| {
 | |
|     int fd;
 | |
|     snprintf(plugin_name,sizeof(plugin_name),"%s/%s.rock",
 | |
|              VIEWERS_DIR,plugin);
 | |
|     if ((fd = open(plugin_name,O_RDONLY))>=0)
 | |
|     {
 | |
|         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)
 | |
|         {
 | |
|             close(fd);
 | |
|             return plugin_load(plugin_name,file);
 | |
|         }
 | |
|     }
 | |
|     return PLUGIN_ERROR;
 | |
| }
 | |
| 
 | |
| /* 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)
 | |
|         {
 | |
|             gui_syncsplash(HZ, true, str(LANG_FILETYPES_EXTENSION_FULL));
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         /* filetypes[] full, bail out */
 | |
|         if (cnt_filetypes >= MAX_FILETYPES)
 | |
|         {
 | |
|             gui_syncsplash(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((char *)&entry->d_name[strlen((char *)entry->d_name) -
 | |
|                                               sizeof(ROCK_EXTENSION) + 1],
 | |
|                        ROCK_EXTENSION)) {
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         /* filter out to long filenames */
 | |
|         if (strlen((char *)entry->d_name) > MAX_PLUGIN_LENGTH + 5)
 | |
|         {
 | |
|             gui_syncsplash(HZ, true, 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)
 | |
|             {
 | |
|                 cp=get_string((char *)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[Icon_Plugin];
 | |
| #else
 | |
|                     exttypes[cnt_exttypes].type->icon = Icon_Plugin;
 | |
| #endif
 | |
|                     cnt_exttypes++;
 | |
| 
 | |
|                     *dash='-';
 | |
|                     cp=get_string((char *)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((char *)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, (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;
 | |
|             }
 | |
|         }
 | |
|         *dot='.';
 | |
|     }
 | |
|     closedir(dir);
 | |
| }
 | |
| 
 | |
| #ifdef HAVE_LCD_BITMAP
 | |
| static int add_plugin(char *plugin, char *icon)
 | |
| #else
 | |
| static int add_plugin(char *plugin)
 | |
| #endif
 | |
| {
 | |
|     char *cp;
 | |
|     int i;
 | |
| 
 | |
|     if (!plugin)
 | |
|         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++)
 | |
|     {
 | |
|         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;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* 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
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
|     cnt_filetypes++;
 | |
|     return cnt_filetypes - 1;
 | |
| }
 | |
| 
 | |
| /* read config file (or cahe file) */
 | |
| static bool read_config(const char* file)
 | |
| {
 | |
|     enum {extension,
 | |
|           plugin,
 | |
| #ifdef HAVE_LCD_BITMAP
 | |
|           icon,
 | |
| #endif
 | |
|           last};
 | |
| 
 | |
|     int   i,ix;
 | |
|     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)
 | |
|         {
 | |
|             gui_syncsplash(HZ, true, str(LANG_FILETYPES_EXTENSION_FULL));
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         if (cnt_filetypes >= MAX_FILETYPES)
 | |
|         {
 | |
|             gui_syncsplash(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);
 | |
|             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, true, 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])
 | |
|         {
 | |
| #ifdef HAVE_LCD_BITMAP
 | |
|             ix=add_plugin(str[plugin],str[icon]);
 | |
| #else
 | |
|             ix=add_plugin(str[plugin]);
 | |
| #endif
 | |
|             if (ix)
 | |
|             {
 | |
|                 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
 | |
|                 {
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
|         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, 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(const char* str)
 | |
| {
 | |
|     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))
 | |
|     {
 | |
|         strcpy(next_free_string, str);
 | |
|         cp=next_free_string;
 | |
|         next_free_string=&next_free_string[l];
 | |
|         return cp;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         gui_syncsplash(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';
 | |
| }
 |