Browse Source

x11: Add support for the Steam Deck on-screen keyboard

Ethan Lee 2 years ago
parent
commit
c4b9f62164

+ 44 - 0
src/video/x11/SDL_x11keyboard.c

@@ -22,6 +22,8 @@
 
 #if SDL_VIDEO_DRIVER_X11
 
+#include "SDL_hints.h"
+#include "SDL_misc.h"
 #include "SDL_x11video.h"
 
 #include "../../events/SDL_keyboard_c.h"
@@ -841,6 +843,48 @@ X11_SetTextInputRect(_THIS, const SDL_Rect *rect)
 #endif
 }
 
+SDL_bool
+X11_HasScreenKeyboardSupport(_THIS)
+{
+    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+    return videodata->is_steam_deck;
+}
+
+void
+X11_ShowScreenKeyboard(_THIS, SDL_Window *window)
+{
+    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+
+    if (videodata->is_steam_deck) {
+        /* For more documentation of the URL parameters, see:
+         * https://partner.steamgames.com/doc/api/ISteamUtils#ShowFloatingGamepadTextInput
+         */
+        char deeplink[128];
+        SDL_snprintf(deeplink, sizeof(deeplink),
+                     "steam://open/keyboard?XPosition=0&YPosition=0&Width=0&Height=0&Mode=%d",
+                     SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, SDL_FALSE) ? 0 : 1);
+        SDL_OpenURL(deeplink);
+        videodata->steam_keyboard_open = SDL_TRUE;
+    }
+}
+
+void X11_HideScreenKeyboard(_THIS, SDL_Window *window)
+{
+    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+
+    if (videodata->is_steam_deck) {
+        SDL_OpenURL("steam://close/keyboard");
+        videodata->steam_keyboard_open = SDL_FALSE;
+    }
+}
+
+SDL_bool X11_IsScreenKeyboardShown(_THIS, SDL_Window *window)
+{
+    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+
+    return videodata->steam_keyboard_open;
+}
+
 #endif /* SDL_VIDEO_DRIVER_X11 */
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 4 - 0
src/video/x11/SDL_x11keyboard.h

@@ -29,6 +29,10 @@ extern void X11_QuitKeyboard(_THIS);
 extern void X11_StartTextInput(_THIS);
 extern void X11_StopTextInput(_THIS);
 extern void X11_SetTextInputRect(_THIS, const SDL_Rect *rect);
+extern SDL_bool X11_HasScreenKeyboardSupport(_THIS);
+extern void X11_ShowScreenKeyboard(_THIS, SDL_Window *window);
+extern void X11_HideScreenKeyboard(_THIS, SDL_Window *window);
+extern SDL_bool X11_IsScreenKeyboardShown(_THIS, SDL_Window *window);
 extern KeySym X11_KeyCodeToSym(_THIS, KeyCode, unsigned char group);
 
 #endif /* SDL_x11keyboard_h_ */

+ 9 - 0
src/video/x11/SDL_x11video.c

@@ -212,6 +212,11 @@ X11_CreateDevice(void)
     safety_net_triggered = SDL_FALSE;
     orig_x11_errhandler = X11_XSetErrorHandler(X11_SafetyNetErrHandler);
 
+    /* Steam Deck will have an on-screen keyboard, so check their environment
+     * variable so we can make use of SDL_StartTextInput.
+     */
+    data->is_steam_deck = SDL_GetHintBoolean("SteamDeck", SDL_FALSE);
+
     /* Set the function pointers */
     device->VideoInit = X11_VideoInit;
     device->VideoQuit = X11_VideoQuit;
@@ -307,6 +312,10 @@ X11_CreateDevice(void)
     device->StartTextInput = X11_StartTextInput;
     device->StopTextInput = X11_StopTextInput;
     device->SetTextInputRect = X11_SetTextInputRect;
+    device->HasScreenKeyboardSupport = X11_HasScreenKeyboardSupport;
+    device->ShowScreenKeyboard = X11_ShowScreenKeyboard;
+    device->HideScreenKeyboard = X11_HideScreenKeyboard;
+    device->IsScreenKeyboardShown = X11_IsScreenKeyboardShown;
 
     device->free = X11_DeleteDevice;
 

+ 4 - 0
src/video/x11/SDL_x11video.h

@@ -152,6 +152,10 @@ typedef struct SDL_VideoData
     PFN_XGetXCBConnection vulkan_XGetXCBConnection;
 #endif
 
+    /* Used to interact with the on-screen keyboard */
+    SDL_bool is_steam_deck;
+    SDL_bool steam_keyboard_open;
+
 } SDL_VideoData;
 
 extern SDL_bool X11_UseDirectColorVisuals(void);