Unicode support in keyboard editable field for filename

This commit is contained in:
Thomas Bernard 2018-02-15 14:17:53 +01:00
parent 9fb6d650b5
commit 689aebf264
8 changed files with 196 additions and 62 deletions

View File

@ -1901,11 +1901,17 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context
T_Fileselector_item * current_item; T_Fileselector_item * current_item;
current_item = Get_item_by_index(&Filelist, Selector->Position + Selector->Offset); current_item = Get_item_by_index(&Filelist, Selector->Position + Selector->Offset);
if (current_item->Type != 0 && !FILENAME_COMPARE(current_item->Full_name,Selector_filename)) if (current_item->Type != 0 && !FILENAME_COMPARE(current_item->Full_name,Selector_filename))
{
// current name is a highlighted directory // current name is a highlighted directory
Selector_filename[0]='\0'; Selector_filename[0]='\0';
Selector_filename_unicode[0]=0;
}
} }
strncpy(filename_ansi, Selector_filename, sizeof(filename_ansi)); strncpy(filename_ansi, Selector_filename, sizeof(filename_ansi));
Unicode_strlcpy(filename_unicode, Selector_filename_unicode, sizeof(filename_unicode)/sizeof(word)); if (Selector_filename_unicode[0] == 0 && strlen(Selector_filename) > 0)
Unicode_char_strlcpy(filename_unicode, Selector_filename, sizeof(filename_unicode)/sizeof(word));
else
Unicode_strlcpy(filename_unicode, Selector_filename_unicode, sizeof(filename_unicode)/sizeof(word));
#ifdef ENABLE_FILENAMES_ICONV #ifdef ENABLE_FILENAMES_ICONV
{ /* convert from UTF8 to ANSI */ { /* convert from UTF8 to ANSI */
char * input = (char *)Selector_filename; char * input = (char *)Selector_filename;
@ -1916,20 +1922,22 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context
*output = '\0'; *output = '\0';
} }
#endif /* ENABLE_FILENAMES_ICONV */ #endif /* ENABLE_FILENAMES_ICONV */
if (Readline(82,48,filename_ansi,27,INPUT_TYPE_FILENAME)) if (Readline_ex_unicode(82,48,filename_ansi,filename_unicode,27,sizeof(filename_ansi)-1,INPUT_TYPE_FILENAME,0))
{ {
#ifdef ENABLE_FILENAMES_ICONV #ifdef ENABLE_FILENAMES_ICONV
/* convert back from ANSI to UTF8 */ /* convert back from UTF16 to UTF8 */
char * input = (char *)filename_ansi; char * input = (char *)filename_unicode;
size_t inbytesleft = strlen(input); size_t inbytesleft = 2 * Unicode_strlen(filename_unicode);
char * output = Selector_filename; char * output = Selector_filename;
size_t outbytesleft = sizeof(Selector_filename)-1; size_t outbytesleft = sizeof(Selector_filename)-1;
if(cd_inv != (iconv_t)-1 && (ssize_t)iconv(cd_inv, &input, &inbytesleft, &output, &outbytesleft) >= 0) if(cd_utf16_inv != (iconv_t)-1 && (ssize_t)iconv(cd_utf16_inv, &input, &inbytesleft, &output, &outbytesleft) >= 0)
*output = '\0'; *output = '\0';
else else
#endif /* ENABLE_FILENAMES_ICONV */ #endif /* ENABLE_FILENAMES_ICONV */
strncpy(Selector_filename, filename_ansi, sizeof(Selector_filename)); strncpy(Selector_filename, filename_ansi, sizeof(Selector_filename));
Unicode_strlcpy(Selector_filename_unicode, filename_unicode, sizeof(Selector_filename_unicode)/sizeof(word));
// 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++)
@ -1937,23 +1945,18 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context
dummy=1; dummy=1;
if (!dummy) if (!dummy)
{ {
if (Get_fileformat(Selector->Format_filter)->Default_extension) if(!Directory_exists(Selector_filename))
{
if(!Directory_exists(Selector_filename))
{
strcat(Selector_filename, ".");
strcat(Selector_filename, Get_fileformat(Selector->Format_filter)->Default_extension);
}
}
else
{ {
const char * ext = Get_fileformat(Selector->Format_filter)->Default_extension;
// put default extension // put default extension
// (but maybe we should browse through all available ones until we find // (but maybe we should browse through all available ones until we find
// something suitable ?) // something suitable ?)
if(!Directory_exists(Selector_filename)) if (ext == NULL)
{ ext = "pkm";
strcat(Selector_filename, ".pkm"); strcat(Selector_filename, ".");
} strcat(Selector_filename, ext);
Unicode_char_strlcat(Selector_filename_unicode, ".", sizeof(Selector_filename_unicode)/sizeof(word));
Unicode_char_strlcat(Selector_filename_unicode, ext, sizeof(Selector_filename_unicode)/sizeof(word));
} }
} }
if(load) if(load)

View File

@ -768,9 +768,10 @@ GFX2_GLOBAL int Line_number_in_INI_file;
#else #else
#define FROMCODE "UTF-8" #define FROMCODE "UTF-8"
#endif #endif
GFX2_GLOBAL iconv_t cd; GFX2_GLOBAL iconv_t cd; // FROMCODE => TOCODE
GFX2_GLOBAL iconv_t cd_inv; GFX2_GLOBAL iconv_t cd_inv; // TOCODE => FROMCODE
GFX2_GLOBAL iconv_t cd_utf16; GFX2_GLOBAL iconv_t cd_utf16; // FROMCODE => UTF16
GFX2_GLOBAL iconv_t cd_utf16_inv; // UTF16 => FROMCODE
#endif /* ENABLE_FILENAMES_ICONV */ #endif /* ENABLE_FILENAMES_ICONV */
// -- Specific to SDL // -- Specific to SDL

View File

@ -480,8 +480,10 @@ int Init_program(int argc,char * argv[])
cd_inv = iconv_open(FROMCODE, TOCODE); // From ANSI to UTF8 cd_inv = iconv_open(FROMCODE, TOCODE); // From ANSI to UTF8
#if SDL_BYTEORDER == SDL_BIG_ENDIAN #if SDL_BYTEORDER == SDL_BIG_ENDIAN
cd_utf16 = iconv_open("UTF-16BE", FROMCODE); // From UTF8 to UTF16 cd_utf16 = iconv_open("UTF-16BE", FROMCODE); // From UTF8 to UTF16
cd_utf16_inv = iconv_open(FROMCODE, "UTF-16BE"); // From UTF16 to UTF8
#else #else
cd_utf16 = iconv_open("UTF-16LE", FROMCODE); // From UTF8 to UTF16 cd_utf16 = iconv_open("UTF-16LE", FROMCODE); // From UTF8 to UTF16
cd_utf16_inv = iconv_open(FROMCODE, "UTF-16LE"); // From UTF16 to UTF8
#endif #endif
#endif /* ENABLE_FILENAMES_ICONV */ #endif /* ENABLE_FILENAMES_ICONV */

View File

@ -2,6 +2,7 @@
*/ */
/* Grafx2 - The Ultimate 256-color bitmap paint program /* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2018 Thomas Bernard
Copyright 2014 Sergii Pylypenko Copyright 2014 Sergii Pylypenko
Copyright 2008 Yves Rizoud Copyright 2008 Yves Rizoud
Copyright 2007 Adrien Destugues Copyright 2007 Adrien Destugues
@ -41,6 +42,7 @@
#include "windows.h" #include "windows.h"
#include "input.h" #include "input.h"
#include "engine.h" #include "engine.h"
#include "unicode.h"
#ifdef __WIN32__ #ifdef __WIN32__
#include <windows.h> #include <windows.h>
@ -67,17 +69,23 @@
#define CURSOR_COLOR MC_Black #define CURSOR_COLOR MC_Black
#define CURSOR_BACKGROUND_COLOR MC_Dark #define CURSOR_BACKGROUND_COLOR MC_Dark
// Suppresion d'un caractère à une certaine POSITION dans une CHAINE. // remove a character from a string
void Remove_character(char * str, byte position) static void Remove_character(char * str, int position)
{
for (;str[position]!='\0';position++)
str[position]=str[position+1];
}
// remove a character from a string
static void Remove_character_unicode(word * str, int position)
{ {
for (;str[position]!='\0';position++) for (;str[position]!='\0';position++)
str[position]=str[position+1]; str[position]=str[position+1];
} }
void Insert_character(char * str, char letter, byte position) static void Insert_character(char * str, char letter, int position)
// Insertion d'une LETTRE à une certaine POSITION // Insert a character in str at position
// dans une CHAINE d'une certaine TAILLE.
{ {
char temp_char; char temp_char;
@ -94,6 +102,18 @@ void Insert_character(char * str, char letter, byte position)
str[position]='\0'; str[position]='\0';
} }
static void Insert_character_unicode(word * str, word c, int position)
{
for (;;)
{
word temp = str[position];
str[position++] = c;
if (c == 0)
return; // we just have written the NULL terminator
c = temp;
}
}
int Prepend_string(char* dest, char* src, int max) int Prepend_string(char* dest, char* src, int max)
// Insert a string at the start of another. Up to MAX characters only // Insert a string at the start of another. Up to MAX characters only
// Returns actual number of chars inserted // Returns actual number of chars inserted
@ -187,7 +207,7 @@ void Cleanup_string(char* str, int input_type)
str[j] = '\0'; str[j] = '\0';
} }
void Display_whole_string(word x_pos,word y_pos,char * str,byte position) static void Display_whole_string(word x_pos,word y_pos,const char * str,byte position)
{ {
char cursor[2]; char cursor[2];
Print_general(x_pos,y_pos,str,TEXT_COLOR,BACKGROUND_COLOR); Print_general(x_pos,y_pos,str,TEXT_COLOR,BACKGROUND_COLOR);
@ -197,6 +217,16 @@ void Display_whole_string(word x_pos,word y_pos,char * str,byte position)
Print_general(x_pos+(position<<3)*Menu_factor_X,y_pos,cursor,CURSOR_COLOR,CURSOR_BACKGROUND_COLOR); Print_general(x_pos+(position<<3)*Menu_factor_X,y_pos,cursor,CURSOR_COLOR,CURSOR_BACKGROUND_COLOR);
} }
static void Display_whole_string_unicode(word x_pos,word y_pos, const word * str_unicode,byte position)
{
char cursor[2];
Print_general_unicode(x_pos,y_pos,str_unicode,TEXT_COLOR,BACKGROUND_COLOR);
cursor[0]=str_unicode[position] ? str_unicode[position] : ' ';
cursor[1]='\0';
Print_general(x_pos+(position<<3)*Menu_factor_X,y_pos,cursor,CURSOR_COLOR,CURSOR_BACKGROUND_COLOR);
}
void Init_virtual_keyboard(word y_pos, word keyboard_width, word keyboard_height) void Init_virtual_keyboard(word y_pos, word keyboard_width, word keyboard_height)
{ {
int h_pos; int h_pos;
@ -343,7 +373,7 @@ byte Readline(word x_pos,word y_pos,char * str,byte visible_size,byte input_type
byte max_size; byte max_size;
// Grosse astuce pour les noms de fichiers: La taille affichée est différente // Grosse astuce pour les noms de fichiers: La taille affichée est différente
// de la taille maximum gérée. // de la taille maximum gérée.
if (input_type == 2) if (input_type == INPUT_TYPE_FILENAME)
max_size = 255; max_size = 255;
else else
max_size = visible_size; max_size = visible_size;
@ -354,6 +384,11 @@ byte Readline(word x_pos,word y_pos,char * str,byte visible_size,byte input_type
* Enhanced super scanf deluxe pro plus giga mieux :-) * * Enhanced super scanf deluxe pro plus giga mieux :-) *
****************************************************************************/ ****************************************************************************/
byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_size, byte input_type, byte decimal_places) byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_size, byte input_type, byte decimal_places)
{
return Readline_ex_unicode(x_pos, y_pos, str, NULL, visible_size, max_size, input_type, decimal_places);
}
byte Readline_ex_unicode(word x_pos,word y_pos,char * str,word * str_unicode,byte visible_size,byte max_size, byte input_type, byte decimal_places)
// Paramètres: // Paramètres:
// x_pos, y_pos : Coordonnées de la saisie dans la fenêtre // x_pos, y_pos : Coordonnées de la saisie dans la fenêtre
// str : Chaîne recevant la saisie (et contenant éventuellement une valeur initiale) // str : Chaîne recevant la saisie (et contenant éventuellement une valeur initiale)
@ -365,6 +400,8 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
{ {
char initial_string[256]; char initial_string[256];
char display_string[256]; char display_string[256];
word initial_string_unicode[256];
word display_string_unicode[256];
byte position; byte position;
byte size; byte size;
word input_key=0; word input_key=0;
@ -375,7 +412,7 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
// Virtual keyboard // Virtual keyboard
byte use_virtual_keyboard=0; byte use_virtual_keyboard=0;
static byte caps_lock=0; static byte caps_lock=0;
word keymapping[] = static const word keymapping[] =
{ {
SDLK_CLEAR,SDLK_BACKSPACE,SDLK_RETURN,KEY_ESC, SDLK_CLEAR,SDLK_BACKSPACE,SDLK_RETURN,KEY_ESC,
'0','1','2','3','4','5','6','7','8','9','.',',', '0','1','2','3','4','5','6','7','8','9','.',',',
@ -528,20 +565,38 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
// Mise à jour des variables se rapportant à la chaîne en fonction de la chaîne initiale // Mise à jour des variables se rapportant à la chaîne en fonction de la chaîne initiale
strcpy(initial_string,str); strcpy(initial_string,str);
if (str_unicode != NULL)
{
size = Unicode_strlen(str_unicode);
memcpy(initial_string_unicode, str_unicode, 2*(size+1));
position=(size<max_size)? size:size-1;
if (position-offset>=visible_size)
offset=position-visible_size+1;
// copy only part of the string if it is too long
Unicode_strlcpy(display_string_unicode, str_unicode+offset, visible_size);
if (offset>0)
display_string_unicode[0] = (byte)LEFT_TRIANGLE_CHARACTER;
if (visible_size + offset + 1 < size )
display_string_unicode[visible_size-1] = (byte)RIGHT_TRIANGLE_CHARACTER;
size=strlen(str); Display_whole_string_unicode(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),display_string_unicode,position - offset);
position=(size<max_size)? size:size-1; }
if (position-offset>=visible_size) else
offset=position-visible_size+1; {
// Formatage d'une partie de la chaine (si trop longue pour tenir) size=strlen(str);
strncpy(display_string, str + offset, visible_size); position=(size<max_size)? size:size-1;
display_string[visible_size]='\0'; if (position-offset>=visible_size)
if (offset>0) offset=position-visible_size+1;
display_string[0]=LEFT_TRIANGLE_CHARACTER; // copy only part of the string if it is too long
if (visible_size + offset + 1 < size ) strncpy(display_string, str + offset, visible_size);
display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER; display_string[visible_size]='\0';
if (offset>0)
display_string[0]=LEFT_TRIANGLE_CHARACTER;
if (visible_size + offset + 1 < size )
display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER;
Display_whole_string(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),display_string,position - offset); Display_whole_string(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),display_string,position - offset);
}
Update_window_area(x_pos,y_pos,visible_size<<3,8); Update_window_area(x_pos,y_pos,visible_size<<3,8);
Flush_update(); Flush_update();
if (Mouse_K) if (Mouse_K)
@ -607,15 +662,23 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
continue; // No clipboard data continue; // No clipboard data
Cleanup_string(data, input_type); Cleanup_string(data, input_type);
// Insert it at the cursor position // Insert it at the cursor position
nb_added = Prepend_string(str + position, data, max_size - position); nb_added = Prepend_string(str + position, data, max_size - position);//TODO : unicode
while (nb_added) while (nb_added)
{ {
size++; size++;
if (size<max_size) if (size<max_size)
{ {
position++; position++;
if (display_string[position-offset]==RIGHT_TRIANGLE_CHARACTER || position-offset>=visible_size) if (str_unicode != NULL)
offset++; {
if (display_string_unicode[position-offset]==(byte)RIGHT_TRIANGLE_CHARACTER || position-offset>=visible_size)
offset++;
}
else
{
if (display_string[position-offset]==RIGHT_TRIANGLE_CHARACTER || position-offset>=visible_size)
offset++;
}
} }
nb_added--; nb_added--;
} }
@ -633,7 +696,10 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
case SDLK_DELETE : // Suppr. case SDLK_DELETE : // Suppr.
if (position<size) if (position<size)
{ {
Remove_character(str,position); if (str_unicode != NULL)
Remove_character_unicode(str_unicode,position);
else
Remove_character(str,position);
size--; size--;
// Effacement de la chaîne // Effacement de la chaîne
@ -659,8 +725,16 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
position++; position++;
//if (position > visible_size + offset - 2) //if (position > visible_size + offset - 2)
//if (offset + visible_size < max_size && (position == size || (position > visible_size + offset - 2))) //if (offset + visible_size < max_size && (position == size || (position > visible_size + offset - 2)))
if (display_string[position-offset]==RIGHT_TRIANGLE_CHARACTER || position-offset>=visible_size) if (str_unicode != NULL)
offset++; {
if (display_string_unicode[position-offset]==(byte)RIGHT_TRIANGLE_CHARACTER || position-offset>=visible_size)
offset++;
}
else
{
if (display_string[position-offset]==RIGHT_TRIANGLE_CHARACTER || position-offset>=visible_size)
offset++;
}
goto affichage; goto affichage;
} }
break; break;
@ -686,12 +760,15 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
break; break;
case SDLK_BACKSPACE : // Backspace : combinaison de gauche + suppr case SDLK_BACKSPACE : // Backspace : combinaison de gauche + suppr
if (position) if (position > 0)
{ {
position--; position--;
if (offset > 0 && (position == 0 || position < (offset + 1))) if (offset > 0 && (position == 0 || position < (offset + 1)))
offset--; offset--;
Remove_character(str,position); if (str_unicode != NULL)
Remove_character_unicode(str_unicode,position);
else
Remove_character(str,position);
size--; size--;
// Effacement de la chaîne // Effacement de la chaîne
Window_rectangle(x_pos,y_pos,visible_size<<3,8,BACKGROUND_COLOR); Window_rectangle(x_pos,y_pos,visible_size<<3,8,BACKGROUND_COLOR);
@ -700,6 +777,8 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
break; break;
case SDLK_CLEAR : // Clear case SDLK_CLEAR : // Clear
str[0]='\0'; str[0]='\0';
if (str_unicode != NULL)
str_unicode[0] = 0;
position=offset=0; position=offset=0;
// Effacement de la chaîne // Effacement de la chaîne
Window_rectangle(x_pos,y_pos,visible_size<<3,8,BACKGROUND_COLOR); Window_rectangle(x_pos,y_pos,visible_size<<3,8,BACKGROUND_COLOR);
@ -711,6 +790,11 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
// On restaure la chaine initiale // On restaure la chaine initiale
strcpy(str,initial_string); strcpy(str,initial_string);
size=strlen(str); size=strlen(str);
if (str_unicode != NULL)
{
Unicode_strlcpy(str_unicode, initial_string_unicode, 256);
size = Unicode_strlen(str_unicode);
}
break; break;
default : default :
if (size<max_size) if (size<max_size)
@ -720,15 +804,28 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
if (is_authorized == 1 || (is_authorized == 2 && position == 0 && str[position] != '-')) if (is_authorized == 1 || (is_authorized == 2 && position == 0 && str[position] != '-'))
{ {
// ... alors on l'insère ... // ... alors on l'insère ...
Insert_character(str,input_key,position/*,size*/); if (str_unicode != NULL)
Insert_character_unicode(str_unicode,input_key,position/*,size*/);
else
Insert_character(str,input_key,position/*,size*/);
// ce qui augmente la taille de la chaine // ce qui augmente la taille de la chaine
size++; size++;
// et qui risque de déplacer le curseur vers la droite // et qui risque de déplacer le curseur vers la droite
if (size<max_size) if (size<max_size)
{ {
position++; position++;
if (display_string[position-offset]==RIGHT_TRIANGLE_CHARACTER || position-offset>=visible_size) if (position-offset>=visible_size)
offset++; offset++;
else if (str_unicode != NULL)
{
if (display_string_unicode[position-offset]==RIGHT_TRIANGLE_CHARACTER)
offset++;
}
else
{
if (display_string[position-offset]==RIGHT_TRIANGLE_CHARACTER)
offset++;
}
} }
// Enfin, on raffiche la chaine // Enfin, on raffiche la chaine
goto affichage; goto affichage;
@ -737,16 +834,31 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
break; break;
affichage: affichage:
size=strlen(str); if (str_unicode != NULL)
// Formatage d'une partie de la chaine (si trop longue pour tenir) {
strncpy(display_string, str + offset, visible_size); size=Unicode_strlen(str_unicode);
display_string[visible_size]='\0'; // only show part of the string if too long
if (offset>0) Unicode_strlcpy(display_string_unicode, str_unicode + offset, visible_size);
display_string[0]=LEFT_TRIANGLE_CHARACTER; if (offset>0)
if (visible_size + offset + 0 < size ) display_string_unicode[0] = (byte)LEFT_TRIANGLE_CHARACTER;
display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER; if (visible_size + offset + 0 < size )
display_string_unicode[visible_size-1] = (byte)RIGHT_TRIANGLE_CHARACTER;
Display_whole_string(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),display_string,position - offset);
Display_whole_string_unicode(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),display_string_unicode,position - offset);
}
else
{
size=strlen(str);
// only show part of the string if too long
strncpy(display_string, str + offset, visible_size);
display_string[visible_size]='\0';
if (offset>0)
display_string[0]=LEFT_TRIANGLE_CHARACTER;
if (visible_size + offset + 0 < size )
display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER;
Display_whole_string(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),display_string,position - offset);
}
Update_rect(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y), Update_rect(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3)); visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3));
} // End du "switch(input_key)" } // End du "switch(input_key)"

View File

@ -2,6 +2,7 @@
*/ */
/* Grafx2 - The Ultimate 256-color bitmap paint program /* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2018 Thomas Bernard
Copyright 2007 Adrien Destugues Copyright 2007 Adrien Destugues
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
@ -55,6 +56,8 @@ byte Readline(word x_pos,word y_pos,char * str,byte visible_size,byte input_type
/// @return 0 if user cancelled (esc), 1 if accepted (return) /// @return 0 if user cancelled (esc), 1 if accepted (return)
byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_size, byte input_type, byte decimal_places); byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_size, byte input_type, byte decimal_places);
byte Readline_ex_unicode(word x_pos,word y_pos,char * str, word * unicode_str, byte visible_size,byte max_size, byte input_type, byte decimal_places);
/// ///
/// Converts a double to string. /// Converts a double to string.
/// @param str Target string, should be pre-allocated and at least 40 characters, to be safe. /// @param str Target string, should be pre-allocated and at least 40 characters, to be safe.

View File

@ -96,3 +96,12 @@ void Unicode_char_strlcpy(word * dst, const char * src, size_t len)
} }
*dst = 0; *dst = 0;
} }
/// Append a regular Latin1 string to an unicode string
void Unicode_char_strlcat(word * dst, const char * src, size_t len)
{
size_t dst_len = Unicode_strlen(dst);
if (dst_len >= len)
return;
Unicode_char_strlcpy(dst + dst_len, src, len - dst_len);
}

View File

@ -39,4 +39,7 @@ int Unicode_char_strcmp(const word * s1, const char * s2);
/// Copy a regular Latin1 string to an unicode string /// Copy a regular Latin1 string to an unicode string
void Unicode_char_strlcpy(word * dst, const char * src, size_t len); void Unicode_char_strlcpy(word * dst, const char * src, size_t len);
/// Append a regular Latin1 string to an unicode string
void Unicode_char_strlcat(word * dst, const char * src, size_t len);
#endif #endif

View File

@ -66,6 +66,7 @@ word Palette_cells_X(void);
word Palette_cells_Y(void); word Palette_cells_Y(void);
void Print_general(short x,short y,const char * str,byte text_color,byte background_color); void Print_general(short x,short y,const char * str,byte text_color,byte background_color);
void Print_general_unicode(short x,short y,const word * 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(short x,short y,const char * 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_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_in_window_limited(short x,short y,const char * str,byte size,byte text_color,byte background_color);