From 32d4bdb80f7a0d2b6d3d2c2be7aee09d5f636e01 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Fri, 7 Jun 2024 22:16:25 +0300 Subject: [PATCH] engine: fix UTF-8 sequence input Fixes: 2e0fc3e4c168 ("engine: client: do not repeatedly check cl_charset value, use generic Con_UtfProcessChar") --- engine/client/client.h | 3 +++ engine/client/console.c | 12 +++++++----- engine/client/keys.c | 12 ++++++------ engine/platform/sdl/events.c | 14 +++++++++----- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/engine/client/client.h b/engine/client/client.h index 549a6dca..4200cefd 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -632,6 +632,9 @@ typedef struct int extensions; netadr_t serveradr; + + // do we accept utf8 as input + qboolean accept_utf8; } client_static_t; #ifdef __cplusplus diff --git a/engine/client/console.c b/engine/client/console.c index 7170c8ab..b5cb8415 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -35,7 +35,6 @@ static CVAR_DEFINE_AUTO( scr_drawversion, "1", FCVAR_ARCHIVE, "draw version in m static CVAR_DEFINE_AUTO( con_oldfont, "0", 0, "use legacy font from gfx.wad, might be missing or broken" ); static int g_codepage = 0; -static qboolean g_utf8 = false; static qboolean g_messagemode_privileged = true; @@ -635,10 +634,13 @@ int Con_UtfProcessCharForce( int in ) int GAME_EXPORT Con_UtfProcessChar( int in ) { - if( !g_utf8 ) + if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence return in; + + // otherwise, decode it and convert to selected codepage return Con_UtfProcessCharForce( in ); } + /* ================= Con_UtfMoveLeft @@ -652,7 +654,7 @@ int Con_UtfMoveLeft( char *str, int pos ) int k = 0; int i; - if( !g_utf8 ) + if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence return pos - 1; if( pos == 1 ) @@ -679,7 +681,7 @@ int Con_UtfMoveRight( char *str, int pos, int length ) utfstate_t state = { 0 }; int i; - if( !g_utf8 ) + if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence return pos + 1; for( i = pos; i <= length; i++ ) @@ -2097,7 +2099,7 @@ void Con_RunConsole( void ) g_codepage = 1252; } - g_utf8 = !Q_stricmp( cl_charset.string, "utf-8" ); + cls.accept_utf8 = !Q_stricmp( cl_charset.string, "utf-8" ); Con_InvalidateFonts(); Con_LoadConchars(); ClearBits( con_charset.flags, FCVAR_CHANGED ); diff --git a/engine/client/keys.c b/engine/client/keys.c index f0ea13d1..529e1e51 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -1055,15 +1055,16 @@ static qboolean OSK_KeyEvent( int key, int down ) break; } - ch = Con_UtfProcessChar((byte)osk.curbutton.val ); + ch = (byte)osk.curbutton.val; + + // do not pass UTF-8 sequence into the engine, convert it here + if( !cls.accept_utf8 ) + ch = Con_UtfProcessCharForce( ch ); if( !ch ) break; - Con_CharEvent( ch ); - if( cls.key_dest == key_menu ) - UI_CharEvent ( ch ); - + CL_CharEvent( ch ); break; } } @@ -1118,7 +1119,6 @@ static void OSK_EnableTextInput( qboolean enable, qboolean force ) { osk.curlayout = 0; osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x]; - } } diff --git a/engine/platform/sdl/events.c b/engine/platform/sdl/events.c index 63f4551c..34b6990f 100644 --- a/engine/platform/sdl/events.c +++ b/engine/platform/sdl/events.c @@ -357,13 +357,17 @@ SDLash_InputEvent #if SDL_VERSION_ATLEAST( 2, 0, 0 ) static void SDLash_InputEvent( SDL_TextInputEvent input ) { - char *text; + const char *text; + VGui_ReportTextInput( input.text ); + for( text = input.text; *text; text++ ) { - int ch; + int ch = (byte)*text; - ch = Con_UtfProcessChar((byte)*text ); + // do not pass UTF-8 sequence into the engine, convert it here + if( !cls.accept_utf8 ) + ch = Con_UtfProcessCharForce( ch ); if( !ch ) continue; @@ -453,7 +457,7 @@ SDLash_EventFilter ============= */ -static void SDLash_EventFilter( SDL_Event *event ) +static void SDLash_EventHandler( SDL_Event *event ) { switch ( event->type ) { @@ -684,7 +688,7 @@ void Platform_RunEvents( void ) SDL_Event event; while( !host.crashed && !host.shutdown_issued && SDL_PollEvent( &event ) ) - SDLash_EventFilter( &event ); + SDLash_EventHandler( &event ); #if XASH_PSVITA PSVita_InputUpdate();