From c4b9f621649d4e2ddb05e7f396e43e2d9e0402cc Mon Sep 17 00:00:00 2001
From: Ethan Lee <[EMAIL REDACTED]>
Date: Sun, 13 Nov 2022 12:45:13 -0500
Subject: [PATCH] x11: Add support for the Steam Deck on-screen keyboard
---
src/video/x11/SDL_x11keyboard.c | 44 +++++++++++++++++++++++++++++++++
src/video/x11/SDL_x11keyboard.h | 4 +++
src/video/x11/SDL_x11video.c | 9 +++++++
src/video/x11/SDL_x11video.h | 4 +++
4 files changed, 61 insertions(+)
diff --git a/src/video/x11/SDL_x11keyboard.c b/src/video/x11/SDL_x11keyboard.c
index 664c816613f7..f5be37ec5d61 100644
--- a/src/video/x11/SDL_x11keyboard.c
+++ b/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: */
diff --git a/src/video/x11/SDL_x11keyboard.h b/src/video/x11/SDL_x11keyboard.h
index 4ce41069b7b7..645e7ba415a6 100644
--- a/src/video/x11/SDL_x11keyboard.h
+++ b/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_ */
diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c
index 2e5e190bd0cb..49f5c5b9bc49 100644
--- a/src/video/x11/SDL_x11video.c
+++ b/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;
diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h
index e2edf248ad53..511ed365c9c3 100644
--- a/src/video/x11/SDL_x11video.h
+++ b/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);