Skip to content

Commit 55ee6c8

Browse files
committed
ogc: add support APIs for virtual keyboards
This commit adds a new public header (SDL_ogcsupport.h) which provides a couple of APIs so that an application would be able to hook into the On-Screen Keyboard (OSK) calls and provide its own implementation of an OSK. The usefulness of this is that the API is designed in such a way that the OSK implementation can reside in a separate project which would only provide a static library to be linked against the application. In this way, SDL applications only need change a couple of lines in order to get the OSK functionality.
1 parent 853b3d6 commit 55ee6c8

File tree

8 files changed

+382
-4
lines changed

8 files changed

+382
-4
lines changed

include/SDL_ogcsupport.h

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
Simple DirectMedia Layer
3+
Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
4+
5+
This software is provided 'as-is', without any express or implied
6+
warranty. In no event will the authors be held liable for any damages
7+
arising from the use of this software.
8+
9+
Permission is granted to anyone to use this software for any purpose,
10+
including commercial applications, and to alter it and redistribute it
11+
freely, subject to the following restrictions:
12+
13+
1. The origin of this software must not be misrepresented; you must not
14+
claim that you wrote the original software. If you use this software
15+
in a product, an acknowledgment in the product documentation would be
16+
appreciated but is not required.
17+
2. Altered source versions must be plainly marked as such, and must not be
18+
misrepresented as being the original software.
19+
3. This notice may not be removed or altered from any source distribution.
20+
*/
21+
22+
#ifndef SDL_ogcsupport_h_
23+
#define SDL_ogcsupport_h_
24+
25+
/**
26+
* \file SDL_ogcsupport.h
27+
*
28+
* Header for the Wii/GameCube support routines.
29+
*/
30+
31+
#include "SDL_stdinc.h"
32+
#include "SDL_events.h"
33+
34+
#include "begin_code.h"
35+
/* Set up for C function definitions, even when using C++ */
36+
#ifdef __cplusplus
37+
extern "C" {
38+
#endif
39+
40+
typedef struct SDL_OGC_DriverData SDL_OGC_DriverData;
41+
42+
typedef struct SDL_OGC_VkContext
43+
{
44+
size_t struct_size;
45+
46+
SDL_OGC_DriverData *driverdata;
47+
48+
SDL_bool is_open;
49+
SDL_Window *window;
50+
SDL_Rect input_rect;
51+
int screen_pan_y;
52+
} SDL_OGC_VkContext;
53+
54+
typedef struct SDL_OGC_VkPlugin
55+
{
56+
size_t struct_size;
57+
58+
void (*Init)(SDL_OGC_VkContext *context);
59+
void (*RenderKeyboard)(SDL_OGC_VkContext *context);
60+
SDL_bool (*ProcessEvent)(SDL_OGC_VkContext *context, SDL_Event *event);
61+
void (*StartTextInput)(SDL_OGC_VkContext *context);
62+
void (*StopTextInput)(SDL_OGC_VkContext *context);
63+
void (*SetTextInputRect)(SDL_OGC_VkContext *context, const SDL_Rect *rect);
64+
void (*ShowScreenKeyboard)(SDL_OGC_VkContext *context);
65+
void (*HideScreenKeyboard)(SDL_OGC_VkContext *context);
66+
} SDL_OGC_VkPlugin;
67+
68+
extern DECLSPEC const SDL_OGC_VkPlugin *
69+
SDL_OGC_RegisterVkPlugin(const SDL_OGC_VkPlugin *plugin);
70+
71+
/**
72+
* Processes the given \a event: if a virtual keyboard is active, input events
73+
* will be passed over to the keyboard module and should not be processed by
74+
* the application.
75+
*
76+
* \param event The SDL_Event to be processed
77+
* \returns SDL_TRUE if the event was processed and must be ignored by the
78+
* application.
79+
*/
80+
extern DECLSPEC SDL_bool SDL_OGC_ProcessEvent(SDL_Event *event);
81+
82+
/**
83+
* A SDL_PollEvent() wrapper which invokes SDL_OGC_ProcessEvent() for every
84+
* received event.
85+
*/
86+
SDL_FORCE_INLINE int SDL_OGC_PollEvent(SDL_Event *event)
87+
{
88+
while (SDL_PollEvent(event)) {
89+
if (!SDL_OGC_ProcessEvent(event)) {
90+
return 1;
91+
}
92+
}
93+
return 0;
94+
}
95+
96+
/* Should we add some preprocessor conditions to this? */
97+
#ifndef SDL_PollEvent
98+
#define SDL_PollEvent SDL_OGC_PollEvent
99+
#endif
100+
101+
/* Functions for OSK plugin implementations */
102+
extern DECLSPEC int SDL_OGC_SendKeyboardText(const char *text);
103+
extern DECLSPEC int SDL_OGC_SendVirtualKeyboardKey(Uint8 state,
104+
SDL_Scancode scancode);
105+
106+
/* Ends C function definitions when using C++ */
107+
#ifdef __cplusplus
108+
}
109+
#endif
110+
#include "close_code.h"
111+
112+
#endif /* SDL_ogcsupport_h_ */
113+
114+
/* vi: set ts=4 sw=4 expandtab: */

src/render/ogc/SDL_render_ogc.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,10 @@ static int OGC_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
340340
{
341341
const SDL_Rect *viewport = &cmd->data.viewport.rect;
342342

343-
OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h);
343+
/* If rendering to the screen, pan the viewport to account for the OSK */
344+
bool honour_screen_pan = renderer->target == NULL;
345+
OGC_set_viewport(viewport->x, viewport->y, viewport->w, viewport->h,
346+
honour_screen_pan);
344347
return 0;
345348
}
346349

src/video/ogc/SDL_ogcgxcommon.c

+20-2
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,28 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = {
4040
1.0,
4141
};
4242

43-
void OGC_set_viewport(int x, int y, int w, int h)
43+
static int s_screen_pan_y = 0;
44+
45+
void OGC_set_screen_pan_y(int y)
46+
{
47+
if (y != s_screen_pan_y) {
48+
s_screen_pan_y = y;
49+
}
50+
}
51+
52+
int OGC_get_screen_pan_y()
53+
{
54+
return s_screen_pan_y;
55+
}
56+
57+
void OGC_set_viewport(int x, int y, int w, int h, bool honour_panning)
4458
{
4559
Mtx44 proj;
4660

61+
if (honour_panning) {
62+
y += s_screen_pan_y;
63+
}
64+
4765
GX_SetViewport(x, y, w, h, 0, 1);
4866
GX_SetScissor(x, y, w, h);
4967

@@ -86,7 +104,7 @@ void OGC_draw_init(int w, int h)
86104
GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
87105
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
88106

89-
OGC_set_viewport(0, 0, w, h);
107+
OGC_set_viewport(0, 0, w, h, false);
90108

91109
GX_InvVtxCache(); // update vertex cache
92110
}

src/video/ogc/SDL_ogcgxcommon.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,16 @@
2424
#define SDL_ogcgxcommon_h_
2525

2626
#include "SDL_render.h"
27+
#include "SDL_ogcvideo.h"
2728

2829
#include <gctypes.h>
2930

3031
#define GX_COLOR_AS_U32(c) *((u32*)&c)
3132

3233
void OGC_draw_init(int w, int h);
33-
void OGC_set_viewport(int x, int y, int w, int h);
34+
void OGC_set_screen_pan_y(int y);
35+
int OGC_get_screen_pan_y();
36+
void OGC_set_viewport(int x, int y, int w, int h, bool honour_panning);
3437
void OGC_load_texture(void *texels, int w, int h, u8 gx_format,
3538
SDL_ScaleMode scale_mode);
3639

src/video/ogc/SDL_ogcosk.c

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
Simple DirectMedia Layer
3+
Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
4+
5+
This software is provided 'as-is', without any express or implied
6+
warranty. In no event will the authors be held liable for any damages
7+
arising from the use of this software.
8+
9+
Permission is granted to anyone to use this software for any purpose,
10+
including commercial applications, and to alter it and redistribute it
11+
freely, subject to the following restrictions:
12+
13+
1. The origin of this software must not be misrepresented; you must not
14+
claim that you wrote the original software. If you use this software
15+
in a product, an acknowledgment in the product documentation would be
16+
appreciated but is not required.
17+
2. Altered source versions must be plainly marked as such, and must not be
18+
misrepresented as being the original software.
19+
3. This notice may not be removed or altered from any source distribution.
20+
*/
21+
#include "../../SDL_internal.h"
22+
23+
#ifdef SDL_VIDEO_DRIVER_OGC
24+
25+
#include "SDL.h"
26+
#include "../../events/SDL_keyboard_c.h"
27+
28+
#include "SDL_ogcosk.h"
29+
#include "SDL_ogcgxcommon.h"
30+
#include "SDL_ogcvideo.h"
31+
32+
/* The active Virtual Keyboard plugin (if any) */
33+
const SDL_OGC_VkPlugin *ogc_vk_plugin = NULL;
34+
35+
static SDL_OGC_VkContext *ogc_vk_context = NULL;
36+
37+
static void init_context()
38+
{
39+
if (ogc_vk_context) return;
40+
41+
ogc_vk_context = SDL_calloc(1, sizeof(SDL_OGC_VkContext));
42+
if (!ogc_vk_context) {
43+
SDL_OutOfMemory();
44+
return;
45+
}
46+
47+
ogc_vk_context->struct_size = sizeof(SDL_OGC_VkContext);
48+
if (ogc_vk_plugin) {
49+
ogc_vk_plugin->Init(ogc_vk_context);
50+
}
51+
}
52+
53+
void OGC_StartTextInput(_THIS)
54+
{
55+
if (!ogc_vk_plugin) return;
56+
ogc_vk_plugin->StartTextInput(ogc_vk_context);
57+
}
58+
59+
void OGC_StopTextInput(_THIS)
60+
{
61+
if (!ogc_vk_plugin) return;
62+
ogc_vk_plugin->StopTextInput(ogc_vk_context);
63+
}
64+
65+
void OGC_SetTextInputRect(_THIS, const SDL_Rect *rect)
66+
{
67+
if (!ogc_vk_plugin || !ogc_vk_context) {
68+
return;
69+
}
70+
71+
ogc_vk_plugin->SetTextInputRect(ogc_vk_context, rect);
72+
}
73+
74+
void OGC_ClearComposition(_THIS)
75+
{
76+
}
77+
78+
SDL_bool OGC_IsTextInputShown(_THIS)
79+
{
80+
return ogc_vk_context && ogc_vk_context->is_open;
81+
}
82+
83+
84+
SDL_bool OGC_HasScreenKeyboardSupport(_THIS)
85+
{
86+
return ogc_vk_plugin != NULL;
87+
}
88+
89+
void OGC_ShowScreenKeyboard(_THIS, SDL_Window *window)
90+
{
91+
if (!ogc_vk_plugin) return;
92+
93+
ogc_vk_context->window = window;
94+
ogc_vk_plugin->ShowScreenKeyboard(ogc_vk_context);
95+
}
96+
97+
void OGC_HideScreenKeyboard(_THIS, SDL_Window *window)
98+
{
99+
if (!ogc_vk_plugin) return;
100+
ogc_vk_plugin->HideScreenKeyboard(ogc_vk_context);
101+
}
102+
103+
SDL_bool OGC_IsScreenKeyboardShown(_THIS, SDL_Window *window)
104+
{
105+
return OGC_IsTextInputShown(_this);
106+
}
107+
108+
const SDL_OGC_VkPlugin *
109+
SDL_OGC_RegisterVkPlugin(const SDL_OGC_VkPlugin *plugin)
110+
{
111+
const SDL_OGC_VkPlugin *old_plugin = ogc_vk_plugin;
112+
ogc_vk_plugin = plugin;
113+
init_context();
114+
return old_plugin;
115+
}
116+
117+
SDL_bool SDL_OGC_ProcessEvent(SDL_Event *event)
118+
{
119+
if (!ogc_vk_plugin || !ogc_vk_context || !ogc_vk_context->is_open) {
120+
return SDL_FALSE;
121+
}
122+
123+
return ogc_vk_plugin->ProcessEvent(ogc_vk_context, event);
124+
}
125+
126+
SDL_bool OGC_keyboard_render(_THIS)
127+
{
128+
if (!ogc_vk_plugin || !ogc_vk_context || !ogc_vk_context->is_open) {
129+
return SDL_FALSE;
130+
}
131+
132+
ogc_vk_plugin->RenderKeyboard(ogc_vk_context);
133+
return SDL_TRUE;
134+
}
135+
136+
int OGC_keyboard_get_pan_y(_THIS)
137+
{
138+
if (!ogc_vk_plugin || !ogc_vk_context) {
139+
return 0;
140+
}
141+
142+
return ogc_vk_context->screen_pan_y;
143+
}
144+
145+
int SDL_OGC_SendKeyboardText(const char *text)
146+
{
147+
return SDL_SendKeyboardText(text);
148+
}
149+
150+
int SDL_OGC_SendVirtualKeyboardKey(Uint8 state, SDL_Scancode scancode)
151+
{
152+
return SDL_SendVirtualKeyboardKey(state, scancode);
153+
}
154+
155+
#endif /* SDL_VIDEO_DRIVER_OGC */
156+
157+
/* vi: set ts=4 sw=4 expandtab: */

src/video/ogc/SDL_ogcosk.h

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Simple DirectMedia Layer
3+
Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
4+
5+
This software is provided 'as-is', without any express or implied
6+
warranty. In no event will the authors be held liable for any damages
7+
arising from the use of this software.
8+
9+
Permission is granted to anyone to use this software for any purpose,
10+
including commercial applications, and to alter it and redistribute it
11+
freely, subject to the following restrictions:
12+
13+
1. The origin of this software must not be misrepresented; you must not
14+
claim that you wrote the original software. If you use this software
15+
in a product, an acknowledgment in the product documentation would be
16+
appreciated but is not required.
17+
2. Altered source versions must be plainly marked as such, and must not be
18+
misrepresented as being the original software.
19+
3. This notice may not be removed or altered from any source distribution.
20+
*/
21+
22+
#ifndef SDL_ogcosk_c_h_
23+
#define SDL_ogcosk_c_h_
24+
25+
#include "../../SDL_internal.h"
26+
#include "../SDL_sysvideo.h"
27+
28+
#include "SDL_ogcsupport.h"
29+
30+
extern const SDL_OGC_VkPlugin *OGC_VkPlugin;
31+
32+
void OGC_StartTextInput(_THIS);
33+
void OGC_StopTextInput(_THIS);
34+
void OGC_SetTextInputRect(_THIS, const SDL_Rect *rect);
35+
void OGC_ClearComposition(_THIS);
36+
SDL_bool OGC_IsTextInputShown(_THIS);
37+
38+
SDL_bool OGC_HasScreenKeyboardSupport(_THIS);
39+
void OGC_ShowScreenKeyboard(_THIS, SDL_Window *window);
40+
void OGC_HideScreenKeyboard(_THIS, SDL_Window *window);
41+
SDL_bool OGC_IsScreenKeyboardShown(_THIS, SDL_Window *window);
42+
43+
SDL_bool OGC_keyboard_render(_THIS);
44+
int OGC_keyboard_get_pan_y(_THIS);
45+
46+
#endif /* SDL_ogcosk_c_h_ */
47+
48+
/* vi: set ts=4 sw=4 expandtab: */

0 commit comments

Comments
 (0)