SDL: wayland: Enforce text capitalization manually, for remapped keymods

From 6d9ca926265fdadfc1676b9cfef8b098b0ac5d29 Mon Sep 17 00:00:00 2001
From: Ethan Lee <[EMAIL REDACTED]>
Date: Fri, 25 Mar 2022 01:36:39 -0400
Subject: [PATCH] wayland: Enforce text capitalization manually, for remapped
 keymods

---
 src/video/wayland/SDL_waylandevents.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index 1aac970c0ba..fbab0601fab 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -910,6 +910,8 @@ keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint
     SDL_WindowData *window = input->keyboard_focus;
     const xkb_keysym_t *syms;
     xkb_keysym_t sym;
+    SDL_Keymod mod;
+    SDL_bool caps;
 
     if (!window || window->keyboard_device != input || !input->xkb.state) {
         return SDL_FALSE;
@@ -921,6 +923,24 @@ keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint
     }
     sym = syms[0];
 
+    /* Wayland is actually pretty cool and sends key codes based on presumed
+     * caps lock state, problem is that it isn't totally accurate if the key
+     * has been remapped, so we have to force caps for our purposes.
+     * -flibit
+     */
+    mod = SDL_GetModState();
+    caps = (
+        /* Caps lock without shift... */
+        ((mod & KMOD_CAPS) && !(mod & KMOD_SHIFT)) ||
+        /* No caps lock with shift... */
+        (!(mod & KMOD_CAPS) && (mod & KMOD_SHIFT))
+    );
+    if (caps) {
+        sym = toupper(sym);
+    } else {
+        sym = tolower(sym);
+    }
+
 #ifdef SDL_USE_IME
     if (SDL_IME_ProcessKeyEvent(sym, key + 8)) {
         *handled_by_ime = SDL_TRUE;