SDL: Convert XLookupString Latin-1 text to UTF-8

From 3a6cb7e7c50ba4b386d015bb4193d3d95a2444fc Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 1 Aug 2022 10:28:29 -0700
Subject: [PATCH] Convert XLookupString Latin-1 text to UTF-8

Fixes bug https://github.com/libsdl-org/SDL/issues/4699
---
 src/video/x11/SDL_x11events.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c
index b347b079b72..fca0d3855d0 100644
--- a/src/video/x11/SDL_x11events.c
+++ b/src/video/x11/SDL_x11events.c
@@ -729,6 +729,23 @@ isReparentNotify(Display *display, XEvent *ev, XPointer arg)
         ev->xreparent.serial == unmap->serial;
 }
 
+static int
+XLookupStringAsUTF8(XKeyEvent *event_struct, char *buffer_return, int bytes_buffer, KeySym *keysym_return, XComposeStatus *status_in_out)
+{
+    int result = X11_XLookupString(event_struct, buffer_return, bytes_buffer, keysym_return, status_in_out);
+    if (result > 0) {
+        char *utf8_text = SDL_iconv_string("UTF-8", "ISO-8859-1", buffer_return, result);
+        if (utf8_text) {
+            SDL_strlcpy(buffer_return, utf8_text, bytes_buffer);
+            SDL_free(utf8_text);
+            return SDL_strlen(buffer_return);
+        } else {
+            return 0;
+        }
+    }
+    return result;
+}
+
 static void
 X11_DispatchEvent(_THIS, XEvent *xevent)
 {
@@ -1047,10 +1064,10 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
                 X11_Xutf8LookupString(data->ic, &xevent->xkey, text, sizeof(text),
                                   &keysym, &status);
             } else {
-                X11_XLookupString(&xevent->xkey, text, sizeof(text), &keysym, NULL);
+                XLookupStringAsUTF8(&xevent->xkey, text, sizeof(text), &keysym, NULL);
             }
 #else
-            X11_XLookupString(&xevent->xkey, text, sizeof(text), &keysym, NULL);
+            XLookupStringAsUTF8(&xevent->xkey, text, sizeof(text), &keysym, NULL);
 #endif
 
 #ifdef SDL_USE_IME
@@ -1064,7 +1081,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
                     if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) {
                         SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
                     }
-                    if(*text) {
+                    if (*text) {
                         SDL_SendKeyboardText(text);
                     }
                 } else {