summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2013-01-19 21:35:09 +0000
committerTim Angus <tim@ngus.net>2014-08-28 10:59:21 +0100
commitedd219ca213a309a318b15831eb773029ee602cc (patch)
treee8b4295024222a541a33a2af15e0658441f83dbb /src
parent39888c9d127f2792453a42bd1c3bbc4fadfc78da (diff)
Convert SDL text input to UTF-32
Diffstat (limited to 'src')
-rw-r--r--src/sdl/sdl_input.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/src/sdl/sdl_input.c b/src/sdl/sdl_input.c
index 95d5a350..c1c86484 100644
--- a/src/sdl/sdl_input.c
+++ b/src/sdl/sdl_input.c
@@ -778,17 +778,43 @@ static void IN_ProcessEvents( void )
case SDL_TEXTINPUT:
{
- int i;
- int numChars = strlen( e.text.text );
+ char *c = e.text.text;
- for( i = 0; i < numChars; i++ )
+ // Quick and dirty UTF-8 to UTF-32 conversion
+ while( *c )
{
- char c = e.text.text[ i ];
+ int utf32 = 0;
- if( !IN_IsConsoleKey( 0, c ) )
- Com_QueueEvent( 0, SE_CHAR, c, 0, 0, NULL );
- }
- }
+ if( ( *c & 0x80 ) == 0 )
+ utf32 = *c++;
+ else if( ( *c & 0xE0 ) == 0xC0 ) // 110x xxxx
+ {
+ utf32 |= ( *c++ & 0x1F ) << 6;
+ utf32 |= ( *c++ & 0x3F );
+ }
+ else if( ( *c & 0xF0 ) == 0xE0 ) // 1110 xxxx
+ {
+ utf32 |= ( *c++ & 0x0F ) << 12;
+ utf32 |= ( *c++ & 0x3F ) << 6;
+ utf32 |= ( *c++ & 0x3F );
+ }
+ else if( ( *c & 0xF8 ) == 0xF0 ) // 1111 0xxx
+ {
+ utf32 |= ( *c++ & 0x07 ) << 18;
+ utf32 |= ( *c++ & 0x3F ) << 6;
+ utf32 |= ( *c++ & 0x3F ) << 6;
+ utf32 |= ( *c++ & 0x3F );
+ }
+ else
+ {
+ Com_DPrintf( "Unrecognised UTF-8 lead byte: 0x%x\n", (unsigned int)*c );
+ c++;
+ }
+
+ if( utf32 != 0 )
+ Com_QueueEvent( 0, SE_CHAR, utf32, 0, 0, NULL );
+ }
+ }
break;
case SDL_MOUSEMOTION: