Use iconv to convert filenames from UTF-8.

Patch by miniupnp, with some C89 adjustments.
Enabled for Haiku and the generic Linux/*BSD part of the Makefile.
Please adjust as needed.

Fixes #10 for codepages for which we have a font.


git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@2172 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Adrien Destugues 2016-12-02 19:43:23 +00:00
parent 0ce386bb19
commit 0eaf3fce96
6 changed files with 117 additions and 13 deletions

View File

@ -200,7 +200,8 @@ endif
LUALOPT = -llua LUALOPT = -llua
endif endif
COPT = -W -Wall -c -g $(shell sdl-config --cflags) $(TTFCOPT) -I/boot/common/include $(LUACOPT) COPT = -W -Wall -c -g $(shell sdl-config --cflags) $(TTFCOPT) -I/boot/common/include $(LUACOPT)
LOPT = $(shell sdl-config --libs) -lSDL_image -lpng -ljpeg -lz $(TTFLOPT) -lfreetype -lbe $(LUALOPT) COPT += -DENABLE_FILENAMES_ICONV
LOPT = $(shell sdl-config --libs) -lSDL_image -lpng -ljpeg -lz $(TTFLOPT) -lfreetype -lbe $(LUALOPT) -liconv
CC = gcc CC = gcc
#Append the gcc kind to the objdir (gcc2 or gcc4) to avoid conflicts when switching from one to other. #Append the gcc kind to the objdir (gcc2 or gcc4) to avoid conflicts when switching from one to other.
OBJKIND = $(shell gcc -dumpversion) OBJKIND = $(shell gcc -dumpversion)
@ -364,6 +365,8 @@ endif
CC = gcc CC = gcc
OBJDIR = ../obj/unix OBJDIR = ../obj/unix
FCLOPT = -lfontconfig FCLOPT = -lfontconfig
# enable UTF8 filename translation
COPT += -DENABLE_FILENAMES_ICONV
endif endif
endif endif
endif endif

View File

@ -230,6 +230,21 @@ char * Format_filename(const char * fname, word max_length, int type)
int c; int c;
int other_cursor; int other_cursor;
int pos_last_dot; int pos_last_dot;
#ifdef ENABLE_FILENAMES_ICONV
/* convert file name from UTF8 to ANSI */
char converted_fname[MAX_PATH_CHARACTERS];
{
char * input = (char *)fname;
size_t inbytesleft = strlen(fname);
char * output = converted_fname;
size_t outbytesleft = sizeof(converted_fname)-1;
if(cd != (iconv_t)-1 && (ssize_t)iconv(cd, &input, &inbytesleft, &output, &outbytesleft) >= 0)
{
*output = '\0';
fname = converted_fname;
}
}
#endif /* ENABLE_FILENAMES_ICONV */
// safety // safety
if (max_length>40) if (max_length>40)
@ -1064,19 +1079,34 @@ void Print_current_directory(void)
// Affiche Selector->Directory sur 37 caractères // Affiche Selector->Directory sur 37 caractères
// //
{ {
char converted_name[MAX_PATH_CHARACTERS];
char temp_name[MAX_DISPLAYABLE_PATH+1]; // Nom tronqué char temp_name[MAX_DISPLAYABLE_PATH+1]; // Nom tronqué
int length; // length du répertoire courant int length; // length du répertoire courant
int index; // index de parcours de la chaine complète int index; // index de parcours de la chaine complète
strncpy(converted_name,Selector->Directory,sizeof(converted_name));
converted_name[sizeof(converted_name)-1] = '\0';
#ifdef ENABLE_FILENAMES_ICONV
{
/* convert file name from UTF8 to ANSI */
char * input = Selector->Directory;
size_t inbytesleft = strlen(input);
char * output = converted_name;
size_t outbytesleft = sizeof(converted_name)-1;
if(cd != (iconv_t)-1 && (ssize_t)iconv(cd, &input, &inbytesleft, &output, &outbytesleft) >= 0)
*output = '\0';
}
#endif /* ENABLE_FILENAMES_ICONV */
Window_rectangle(10,84,37*8,8,MC_Light); Window_rectangle(10,84,37*8,8,MC_Light);
length=strlen(Selector->Directory); length=strlen(converted_name);
if (length>MAX_DISPLAYABLE_PATH) if (length>MAX_DISPLAYABLE_PATH)
{ // Doh! il va falloir tronquer le répertoire (bouh !) { // Doh! il va falloir tronquer le répertoire (bouh !)
// On commence par copier bêtement les 3 premiers caractères (e.g. "C:\") // On commence par copier bêtement les 3 premiers caractères (e.g. "C:\")
for (index=0;index<3;index++) for (index=0;index<3;index++)
temp_name[index]=Selector->Directory[index]; temp_name[index]=converted_name[index];
// On y rajoute 3 petits points: // On y rajoute 3 petits points:
strcpy(temp_name+3,"..."); strcpy(temp_name+3,"...");
@ -1084,12 +1114,12 @@ void Print_current_directory(void)
// Ensuite, on cherche un endroit à partir duquel on pourrait loger tout // Ensuite, on cherche un endroit à partir duquel on pourrait loger tout
// le reste de la chaine (Ouaaaaaah!!! Vachement fort le mec!!) // le reste de la chaine (Ouaaaaaah!!! Vachement fort le mec!!)
for (index++;index<length;index++) for (index++;index<length;index++)
if ( (Selector->Directory[index]==PATH_SEPARATOR[0]) && if ( (converted_name[index]==PATH_SEPARATOR[0]) &&
(length-index<=MAX_DISPLAYABLE_PATH-6) ) (length-index<=MAX_DISPLAYABLE_PATH-6) )
{ {
// Ouf: on vient de trouver un endroit dans la chaîne à partir duquel // Ouf: on vient de trouver un endroit dans la chaîne à partir duquel
// on peut faire la copie: // on peut faire la copie:
strcpy(temp_name+6,Selector->Directory+index); strcpy(temp_name+6,converted_name+index);
break; break;
} }
@ -1097,7 +1127,7 @@ void Print_current_directory(void)
Print_in_window(10,84,temp_name,MC_Black,MC_Light); Print_in_window(10,84,temp_name,MC_Black,MC_Light);
} }
else // Ahhh! La chaîne peut loger tranquillement dans la fenêtre else // Ahhh! La chaîne peut loger tranquillement dans la fenêtre
Print_in_window(10,84,Selector->Directory,MC_Black,MC_Light); Print_in_window(10,84,converted_name,MC_Black,MC_Light);
Update_window_area(10,84,37*8,8); Update_window_area(10,84,37*8,8);
} }
@ -1107,8 +1137,20 @@ void Print_current_directory(void)
// //
void Print_filename_in_fileselector(void) void Print_filename_in_fileselector(void)
{ {
char filename[32];
strncpy(filename, Selector_filename, sizeof(filename));
#ifdef ENABLE_FILENAMES_ICONV
{
char * input = (char *)Selector_filename;
size_t inbytesleft = strlen(Selector_filename);
char * output = filename;
size_t outbytesleft = sizeof(filename)-1;
if(cd != (iconv_t)-1 && (ssize_t)iconv(cd, &input, &inbytesleft, &output, &outbytesleft) >= 0)
*output = '\0';
}
#endif /* ENABLE_FILENAMES_ICONV */
Window_rectangle(82,48,27*8,8,MC_Light); Window_rectangle(82,48,27*8,8,MC_Light);
Print_in_window_limited(82,48,Selector_filename,27,MC_Black,MC_Light); Print_in_window_limited(82,48,filename,27,MC_Black,MC_Light);
Update_window_area(82,48,27*8,8); Update_window_area(82,48,27*8,8);
} }
@ -1721,6 +1763,8 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context
} }
break; break;
case 8 : // Saisie du nom de fichier case 8 : // Saisie du nom de fichier
{
char filename_ansi[256];
// Save the filename // Save the filename
strcpy(save_filename, Selector_filename); strcpy(save_filename, Selector_filename);
@ -1734,8 +1778,31 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context
// current name is a highlighted directory // current name is a highlighted directory
Selector_filename[0]='\0'; Selector_filename[0]='\0';
} }
if (Readline(82,48,Selector_filename,27,INPUT_TYPE_FILENAME)) strncpy(filename_ansi, Selector_filename, sizeof(filename_ansi));
#ifdef ENABLE_FILENAMES_ICONV
{ /* convert from UTF8 to ANSI */
char * input = (char *)Selector_filename;
size_t inbytesleft = strlen(input);
char * output = filename_ansi;
size_t outbytesleft = sizeof(filename_ansi)-1;
if(cd != (iconv_t)-1 && (ssize_t)iconv(cd, &input, &inbytesleft, &output, &outbytesleft) >= 0)
*output = '\0';
}
#endif /* ENABLE_FILENAMES_ICONV */
if (Readline(82,48,filename_ansi,27,INPUT_TYPE_FILENAME))
{ {
#ifdef ENABLE_FILENAMES_ICONV
/* convert back from ANSI to UTF8 */
char * input = (char *)filename_ansi;
size_t inbytesleft = strlen(input);
char * output = Selector_filename;
size_t outbytesleft = sizeof(Selector_filename)-1;
if(cd_inv != (iconv_t)-1 && (ssize_t)iconv(cd_inv, &input, &inbytesleft, &output, &outbytesleft) >= 0)
*output = '\0';
else
#endif /* ENABLE_FILENAMES_ICONV */
strncpy(Selector_filename, filename_ansi, sizeof(Selector_filename));
// On regarde s'il faut rajouter une extension. C'est-à-dire s'il // On regarde s'il faut rajouter une extension. C'est-à-dire s'il
// n'y a pas de '.' dans le nom du fichier. // n'y a pas de '.' dans le nom du fichier.
for(temp=0,dummy=0; ((Selector_filename[temp]) && (!dummy)); temp++) for(temp=0,dummy=0; ((Selector_filename[temp]) && (!dummy)); temp++)
@ -1792,6 +1859,7 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context
} }
Display_cursor(); Display_cursor();
break; break;
}
case 9 : // Volume Select case 9 : // Volume Select
Hide_cursor(); Hide_cursor();
// Comme on tombe sur un disque qu'on connait pas, on se place en // Comme on tombe sur un disque qu'on connait pas, on se place en

View File

@ -854,6 +854,18 @@ GFX2_GLOBAL signed char File_error;
/// Current line number when reading/writing gfx2.ini /// Current line number when reading/writing gfx2.ini
GFX2_GLOBAL int Line_number_in_INI_file; GFX2_GLOBAL int Line_number_in_INI_file;
// -- For iconv
#ifdef ENABLE_FILENAMES_ICONV
#include <iconv.h>
#define TOCODE "CP1252"
#define FROMCODE "UTF-8"
GFX2_GLOBAL iconv_t cd;
GFX2_GLOBAL iconv_t cd_inv;
#endif /* ENABLE_FILENAMES_ICONV */
// -- Specific to SDL // -- Specific to SDL
/// Pointer to the program's screen. /// Pointer to the program's screen.

View File

@ -469,6 +469,13 @@ int Init_program(int argc,char * argv[])
getcwd(Main_selector.Directory,MAX_PATH_CHARACTERS); getcwd(Main_selector.Directory,MAX_PATH_CHARACTERS);
#endif #endif
#ifdef ENABLE_FILENAMES_ICONV
// Initialisation de iconv
// utilisé pour convertir les noms de fichiers
cd = iconv_open(TOCODE, FROMCODE); // From UTF8 to ANSI
cd_inv = iconv_open(FROMCODE, TOCODE); // From ANSI to UTF8
#endif /* ENABLE_FILENAMES_ICONV */
// On en profite pour le mémoriser dans le répertoire principal: // On en profite pour le mémoriser dans le répertoire principal:
strcpy(Initial_directory,Main_selector.Directory); strcpy(Initial_directory,Main_selector.Directory);

View File

@ -335,11 +335,12 @@ void Init_text(void)
#ifdef USE_FC #ifdef USE_FC
{ {
FcStrList* dirs; FcStrList* dirs;
FcChar8 * fdir;
dirs = FcConfigGetFontDirs(NULL); dirs = FcConfigGetFontDirs(NULL);
char* fdir = FcStrListNext(dirs); fdir = FcStrListNext(dirs);
while(fdir != NULL) while(fdir != NULL)
{ {
For_each_file(fdir,Add_font); For_each_file((char *)fdir,Add_font);
fdir = FcStrListNext(dirs); fdir = FcStrListNext(dirs);
} }

View File

@ -799,10 +799,23 @@ void Print_filename(void)
// Determine maximum size, in characters // Determine maximum size, in characters
max_size = 12 + (Screen_width / Menu_factor_X - 320) / 8; max_size = 12 + (Screen_width / Menu_factor_X - 320) / 8;
string_size = strlen(Main_backups->Pages->Filename);
// Partial copy of the name // Partial copy of the name
strncpy(display_string, Main_backups->Pages->Filename, max_size); {
#ifdef ENABLE_FILENAMES_ICONV
char * input = Main_backups->Pages->Filename;
size_t inbytesleft = strlen(input);
char * output = display_string;
size_t outbytesleft = sizeof(display_string)-1;
if(cd != (iconv_t)-1 && (ssize_t)iconv(cd, &input, &inbytesleft, &output, &outbytesleft) >= 0)
*output = '\0';
else
#endif /* ENABLE_FILENAMES_ICONV */
{
strncpy(display_string, Main_backups->Pages->Filename, sizeof(display_string)-1);
display_string[sizeof(display_string)-1] = '\0';
}
}
string_size = strlen(display_string);
display_string[max_size]='\0'; display_string[max_size]='\0';
if (string_size > max_size) if (string_size > max_size)