diff --git a/src/factory.c b/src/factory.c index ca281c4d..38ed92d8 100644 --- a/src/factory.c +++ b/src/factory.c @@ -2009,7 +2009,7 @@ int L_Run(lua_State* L) return luaL_error(L, "run: too many nested calls (100)"); // store the current directory (on the stack) - Get_current_directory(saved_directory,MAX_PATH_CHARACTERS); + Get_current_directory(saved_directory, NULL, MAX_PATH_CHARACTERS); #if defined (__AROS__) // Convert path written on Linux/Windows norms to AROS norms : diff --git a/src/filesel.c b/src/filesel.c index cd407084..88abfd15 100644 --- a/src/filesel.c +++ b/src/filesel.c @@ -2,6 +2,7 @@ */ /* Grafx2 - The Ultimate 256-color bitmap paint program + Copyright 2018 Thomas Bernard Copyright 2014 Sergii Pylypenko Copyright 2011 Pawel Góralski Copyright 2009 Franck Charlet @@ -134,7 +135,7 @@ byte Native_filesel(byte load) // -- Fileselector data -T_Fileselector Filelist; +static T_Fileselector Filelist; /// Selector settings to use, for all functions called by Load_or_save T_Selector_settings * Selector; @@ -540,7 +541,7 @@ void Read_list_of_files(T_Fileselector *list, byte selected_format) // Après effacement, il ne reste ni fichier ni répertoire dans la liste // On lit tous les répertoires: - current_path = Get_current_directory(curdir, MAX_PATH_CHARACTERS); + current_path = Get_current_directory(curdir, NULL, MAX_PATH_CHARACTERS); For_each_directory_entry(current_path, &callback_data, Read_dir_callback); @@ -965,7 +966,7 @@ void Display_file_list(T_Fileselector *list, short offset_first,short selector_o { // Name without icon if (current_item->Unicode_short_name) - Print_in_window_utf16(8,95+index*8,current_item->Unicode_short_name,text_color,background_color); + Print_in_window_unicode(8,95+index*8,current_item->Unicode_short_name,text_color,background_color); else Print_in_window(8,95+index*8,current_item->Short_name,text_color,background_color); } @@ -1166,11 +1167,10 @@ void Display_bookmark(T_Dropdown_button * Button, int bookmark_number) void Print_current_directory(void) // -// Affiche Selector->Directory sur 37 caractères +// Shows Selector->Directory on 37 chars // { char converted_name[MAX_PATH_CHARACTERS]; - char temp_name[MAX_DISPLAYABLE_PATH+1]; // Nom tronqué int length; // length du répertoire courant int index; // index de parcours de la chaine complète @@ -1190,34 +1190,60 @@ void Print_current_directory(void) Window_rectangle(10,84,37*8,8,MC_Light); - length=strlen(converted_name); - if (length>MAX_DISPLAYABLE_PATH) - { // Doh! il va falloir tronquer le répertoire (bouh !) + if (Selector->Directory_unicode[0] != 0) + { + length=Unicode_strlen(Selector->Directory_unicode); + if (length>MAX_DISPLAYABLE_PATH) + { // We need to truncate the directory + word temp_name[MAX_DISPLAYABLE_PATH+1]; // truncated name - // On commence par copier bêtement les 3 premiers caractères (e.g. "C:\") - for (index=0;index<3;index++) - temp_name[index]=converted_name[index]; + memcpy(temp_name, Selector->Directory_unicode, 3*2); // first 3 chars "C:\" + Unicode_char_strlcpy(temp_name+3, "...", MAX_DISPLAYABLE_PATH+1-3); - // On y rajoute 3 petits points: - strcpy(temp_name+3,"..."); + // next we look for a place to fit everything ;) + for (index=3;indexDirectory_unicode[index]==PATH_SEPARATOR[0]) && + (length-index<=MAX_DISPLAYABLE_PATH-6) ) + { + // we found the place ! + Unicode_strlcpy(temp_name+6,Selector->Directory_unicode+index, MAX_DISPLAYABLE_PATH+1-6); + break; + } - // Ensuite, on cherche un endroit à partir duquel on pourrait loger tout - // le reste de la chaine (Ouaaaaaah!!! Vachement fort le mec!!) - for (index++;indexDirectory_unicode,MC_Black,MC_Light); + } + else + { + length=strlen(converted_name); + if (length>MAX_DISPLAYABLE_PATH) + { // We need to truncate the directory + char temp_name[MAX_DISPLAYABLE_PATH+1]; // truncated name + + for (index=0;index<3;index++) // copy the first 3 chars "C:\" + temp_name[index]=converted_name[index]; + + // Add ... + strcpy(temp_name+3,"..."); + + // next we look for a place to fit everything ;) + for (index++;indexFile_directory); - Get_current_directory(Selector->Directory,MAX_PATH_CHARACTERS); + Get_current_directory(Selector->Directory, Selector->Directory_unicode, MAX_PATH_CHARACTERS); // Affichage des premiers fichiers visibles: Reload_list_of_files(Selector->Format_filter,file_scroller); @@ -2176,7 +2202,7 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context Extract_filename(previous_directory, Selector->Directory); } - Get_current_directory(Selector->Directory,MAX_PATH_CHARACTERS); + Get_current_directory(Selector->Directory, Selector->Directory_unicode, MAX_PATH_CHARACTERS); // read the new directory Read_list_of_files(&Filelist, Selector->Format_filter); Sort_list_of_files(&Filelist); diff --git a/src/io.c b/src/io.c index 665e7490..3168b8b4 100644 --- a/src/io.c +++ b/src/io.c @@ -545,7 +545,7 @@ void Release_lock_file(const char *file_directory) remove(lock_filename); } -const char * Get_current_directory(char * buf, size_t size) +const char * Get_current_directory(char * buf, word * buf_unicode, size_t size) { #if defined(__MINT__) buf[0] = 'A'+Dgetdrv(); @@ -554,9 +554,34 @@ const char * Get_current_directory(char * buf, size_t size) Dgetpath(buf+3,0); strcat(buf,PATH_SEPARATOR); + if (buf_unicode != NULL) + buf_unicode[0] = 0; // no unicode support + return buf; #else - return getcwd(buf, size); + char * ret = getcwd(buf, size); +#ifdef ENABLE_FILENAMES_ICONV + if (ret != NULL && buf_unicode != NULL) + { + char * input = buf; + size_t inbytesleft = strlen(buf); + char * output = (char *)buf_unicode; + size_t outbytesleft = 2 * (size - 1); + if (cd_utf16 != (iconv_t)-1) + { + size_t r = iconv(cd_utf16, &input, &inbytesleft, &output, &outbytesleft); + if (r != (size_t)-1) + { + output[0] = '\0'; + output[1] = '\0'; + } + } + } +#else + if (buf_unicode != NULL) + buf_unicode[0] = 0; // no unicode support +#endif + return ret; #endif } diff --git a/src/io.h b/src/io.h index fb1f260c..6dd97a01 100644 --- a/src/io.h +++ b/src/io.h @@ -130,7 +130,7 @@ void Release_lock_file(const char *file_directory); /// /// Return the current directory, equivalent to getcwd() -const char * Get_current_directory(char * buf, size_t size); +const char * Get_current_directory(char * buf, word * buf_unicode, size_t size); /// /// Change current directory. return 0 for success, -1 in case of error diff --git a/src/main.c b/src/main.c index 3eea120f..74fd9d3c 100644 --- a/src/main.c +++ b/src/main.c @@ -473,6 +473,17 @@ int Init_program(int argc,char * argv[]) printf("===============================\n"); #endif +#ifdef ENABLE_FILENAMES_ICONV + // iconv is used to convert filenames + cd = iconv_open(TOCODE, FROMCODE); // From UTF8 to ANSI + cd_inv = iconv_open(FROMCODE, TOCODE); // From ANSI to UTF8 +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + cd_utf16 = iconv_open("UTF-16BE", FROMCODE); // From UTF8 to UTF16 +#else + cd_utf16 = iconv_open("UTF-16LE", FROMCODE); // From UTF8 to UTF16 +#endif +#endif /* ENABLE_FILENAMES_ICONV */ + // On crée dès maintenant les descripteurs des listes de pages pour la page // principale et la page de brouillon afin que leurs champs ne soient pas // invalide lors des appels aux multiples fonctions manipulées à @@ -489,15 +500,7 @@ int Init_program(int argc,char * argv[]) // Choose directory for settings (read/write) Set_config_directory(program_directory,Config_directory); // On détermine le répertoire courant: - Get_current_directory(Main.selector.Directory,MAX_PATH_CHARACTERS); - -#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 - cd_utf16 = iconv_open("UTF-16LE", FROMCODE); // From UTF8 to UTF16 -#endif /* ENABLE_FILENAMES_ICONV */ + Get_current_directory(Main.selector.Directory,Main.selector.Directory_unicode,MAX_PATH_CHARACTERS); // On en profite pour le mémoriser dans le répertoire principal: strcpy(Initial_directory,Main.selector.Directory); diff --git a/src/struct.h b/src/struct.h index 32041eba..a86fe26e 100644 --- a/src/struct.h +++ b/src/struct.h @@ -549,6 +549,7 @@ typedef struct T_Selector_settings short Position; ///< Index of the first file/entry to display in list short Offset; ///< Position of the "highlight" bar in the file list char Directory[MAX_PATH_CHARACTERS]; ///< Directory currently browsed + word Directory_unicode[MAX_PATH_CHARACTERS]; ///< Directory currently browsed } T_Selector_settings; /// structure for Main or Spare page global data diff --git a/src/windows.c b/src/windows.c index 60540bbb..81b30ade 100644 --- a/src/windows.c +++ b/src/windows.c @@ -762,7 +762,7 @@ void Print_in_window(short x,short y,const char * str,byte text_color,byte backg } /// Draws a string in a window -void Print_in_window_utf16(short x,short y,const word * str,byte text_color,byte background_color) +void Print_in_window_unicode(short x,short y,const word * str,byte text_color,byte background_color) { short x_pos = x; const word * p = str; diff --git a/src/windows.h b/src/windows.h index 91569587..3631720d 100644 --- a/src/windows.h +++ b/src/windows.h @@ -67,7 +67,7 @@ word Palette_cells_Y(void); void Print_general(short x,short y,const char * str,byte text_color,byte background_color); void Print_in_window(short x,short y,const char * str,byte text_color,byte background_color); -void Print_in_window_utf16(short x,short y,const word * str,byte text_color,byte background_color); +void Print_in_window_unicode(short x,short y,const word * str,byte text_color,byte background_color); void Print_in_window_limited(short x,short y,const char * str,byte size,byte text_color,byte background_color); void Print_char_in_window(short x_pos,short y_pos, unsigned int c,byte text_color,byte background_color); void Print_in_menu(const char * str, short position);