Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ogc: add support APIs for virtual keyboards #61

Open
wants to merge 1 commit into
base: ogc-sdl-2.28
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions include/SDL_ogcsupport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <[email protected]>

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/

#ifndef SDL_ogcsupport_h_
#define SDL_ogcsupport_h_

/**
* \file SDL_ogcsupport.h
*
* Header for the Wii/GameCube support routines.
*/

#include "SDL_stdinc.h"
#include "SDL_events.h"

#include "begin_code.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif

typedef struct SDL_OGC_DriverData SDL_OGC_DriverData;

typedef struct SDL_OGC_VkContext
{
size_t struct_size;

SDL_OGC_DriverData *driverdata;

SDL_bool is_open;
SDL_Window *window;
SDL_Rect input_rect;
int screen_pan_y;
} SDL_OGC_VkContext;

typedef struct SDL_OGC_VkPlugin
{
size_t struct_size;

void (*Init)(SDL_OGC_VkContext *context);
void (*RenderKeyboard)(SDL_OGC_VkContext *context);
SDL_bool (*ProcessEvent)(SDL_OGC_VkContext *context, SDL_Event *event);
void (*StartTextInput)(SDL_OGC_VkContext *context);
void (*StopTextInput)(SDL_OGC_VkContext *context);
void (*SetTextInputRect)(SDL_OGC_VkContext *context, const SDL_Rect *rect);
void (*ShowScreenKeyboard)(SDL_OGC_VkContext *context);
void (*HideScreenKeyboard)(SDL_OGC_VkContext *context);
} SDL_OGC_VkPlugin;

extern DECLSPEC const SDL_OGC_VkPlugin *
SDL_OGC_RegisterVkPlugin(const SDL_OGC_VkPlugin *plugin);

/**
* Processes the given \a event: if a virtual keyboard is active, input events
* will be passed over to the keyboard module and should not be processed by
* the application.
*
* \param event The SDL_Event to be processed
* \returns SDL_TRUE if the event was processed and must be ignored by the
* application.
*/
extern DECLSPEC SDL_bool SDL_OGC_ProcessEvent(SDL_Event *event);

/**
* A SDL_PollEvent() wrapper which invokes SDL_OGC_ProcessEvent() for every
* received event.
*/
SDL_FORCE_INLINE int SDL_OGC_PollEvent(SDL_Event *event)
{
while (SDL_PollEvent(event)) {
if (!SDL_OGC_ProcessEvent(event)) {
return 1;
}
}
return 0;
}

/* Should we add some preprocessor conditions to this? */
#ifndef SDL_PollEvent
#define SDL_PollEvent SDL_OGC_PollEvent
#endif

/* Functions for OSK plugin implementations */
extern DECLSPEC int SDL_OGC_SendKeyboardText(const char *text);
extern DECLSPEC int SDL_OGC_SendVirtualKeyboardKey(Uint8 state,
SDL_Scancode scancode);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include "close_code.h"

#endif /* SDL_ogcsupport_h_ */

/* vi: set ts=4 sw=4 expandtab: */
5 changes: 4 additions & 1 deletion src/render/ogc/SDL_render_ogc.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,10 @@ static int OGC_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
{
const SDL_Rect *viewport = &cmd->data.viewport.rect;

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

Expand Down
22 changes: 20 additions & 2 deletions src/video/ogc/SDL_ogcgxcommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,28 @@ static const f32 tex_pos[] __attribute__((aligned(32))) = {
1.0,
};

void OGC_set_viewport(int x, int y, int w, int h)
static int s_screen_pan_y = 0;

void OGC_set_screen_pan_y(int y)
{
if (y != s_screen_pan_y) {
s_screen_pan_y = y;
}
}

int OGC_get_screen_pan_y()
{
return s_screen_pan_y;
}

void OGC_set_viewport(int x, int y, int w, int h, bool honour_panning)
{
Mtx44 proj;

if (honour_panning) {
y += s_screen_pan_y;
}

GX_SetViewport(x, y, w, h, 0, 1);
GX_SetScissor(x, y, w, h);

Expand Down Expand Up @@ -86,7 +104,7 @@ void OGC_draw_init(int w, int h)
GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);

OGC_set_viewport(0, 0, w, h);
OGC_set_viewport(0, 0, w, h, false);

GX_InvVtxCache(); // update vertex cache
}
Expand Down
5 changes: 4 additions & 1 deletion src/video/ogc/SDL_ogcgxcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@
#define SDL_ogcgxcommon_h_

#include "SDL_render.h"
#include "SDL_ogcvideo.h"

#include <gctypes.h>

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

void OGC_draw_init(int w, int h);
void OGC_set_viewport(int x, int y, int w, int h);
void OGC_set_screen_pan_y(int y);
int OGC_get_screen_pan_y();
void OGC_set_viewport(int x, int y, int w, int h, bool honour_panning);
void OGC_load_texture(void *texels, int w, int h, u8 gx_format,
SDL_ScaleMode scale_mode);

Expand Down
157 changes: 157 additions & 0 deletions src/video/ogc/SDL_ogcosk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <[email protected]>

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#ifdef SDL_VIDEO_DRIVER_OGC

#include "SDL.h"
#include "../../events/SDL_keyboard_c.h"

#include "SDL_ogcosk.h"
#include "SDL_ogcgxcommon.h"
#include "SDL_ogcvideo.h"

/* The active Virtual Keyboard plugin (if any) */
const SDL_OGC_VkPlugin *ogc_vk_plugin = NULL;

static SDL_OGC_VkContext *ogc_vk_context = NULL;

static void init_context()
{
if (ogc_vk_context) return;

ogc_vk_context = SDL_calloc(1, sizeof(SDL_OGC_VkContext));
if (!ogc_vk_context) {
SDL_OutOfMemory();
return;
}

ogc_vk_context->struct_size = sizeof(SDL_OGC_VkContext);
if (ogc_vk_plugin) {
ogc_vk_plugin->Init(ogc_vk_context);
}
}

void OGC_StartTextInput(_THIS)
{
if (!ogc_vk_plugin) return;
ogc_vk_plugin->StartTextInput(ogc_vk_context);
}

void OGC_StopTextInput(_THIS)
{
if (!ogc_vk_plugin) return;
ogc_vk_plugin->StopTextInput(ogc_vk_context);
}

void OGC_SetTextInputRect(_THIS, const SDL_Rect *rect)
{
if (!ogc_vk_plugin || !ogc_vk_context) {
return;
}

ogc_vk_plugin->SetTextInputRect(ogc_vk_context, rect);
}

void OGC_ClearComposition(_THIS)
{
}

SDL_bool OGC_IsTextInputShown(_THIS)
{
return ogc_vk_context && ogc_vk_context->is_open;
}


SDL_bool OGC_HasScreenKeyboardSupport(_THIS)
{
return ogc_vk_plugin != NULL;
}

void OGC_ShowScreenKeyboard(_THIS, SDL_Window *window)
{
if (!ogc_vk_plugin) return;

ogc_vk_context->window = window;
ogc_vk_plugin->ShowScreenKeyboard(ogc_vk_context);
}

void OGC_HideScreenKeyboard(_THIS, SDL_Window *window)
{
if (!ogc_vk_plugin) return;
ogc_vk_plugin->HideScreenKeyboard(ogc_vk_context);
}

SDL_bool OGC_IsScreenKeyboardShown(_THIS, SDL_Window *window)
{
return OGC_IsTextInputShown(_this);
}

const SDL_OGC_VkPlugin *
SDL_OGC_RegisterVkPlugin(const SDL_OGC_VkPlugin *plugin)
{
const SDL_OGC_VkPlugin *old_plugin = ogc_vk_plugin;
ogc_vk_plugin = plugin;
init_context();
return old_plugin;
}

SDL_bool SDL_OGC_ProcessEvent(SDL_Event *event)
{
if (!ogc_vk_plugin || !ogc_vk_context || !ogc_vk_context->is_open) {
return SDL_FALSE;
}

return ogc_vk_plugin->ProcessEvent(ogc_vk_context, event);
}

SDL_bool OGC_keyboard_render(_THIS)
{
if (!ogc_vk_plugin || !ogc_vk_context || !ogc_vk_context->is_open) {
return SDL_FALSE;
}

ogc_vk_plugin->RenderKeyboard(ogc_vk_context);
return SDL_TRUE;
}

int OGC_keyboard_get_pan_y(_THIS)
{
if (!ogc_vk_plugin || !ogc_vk_context) {
return 0;
}

return ogc_vk_context->screen_pan_y;
}

int SDL_OGC_SendKeyboardText(const char *text)
{
return SDL_SendKeyboardText(text);
}

int SDL_OGC_SendVirtualKeyboardKey(Uint8 state, SDL_Scancode scancode)
{
return SDL_SendVirtualKeyboardKey(state, scancode);
}

#endif /* SDL_VIDEO_DRIVER_OGC */

/* vi: set ts=4 sw=4 expandtab: */
48 changes: 48 additions & 0 deletions src/video/ogc/SDL_ogcosk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <[email protected]>

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/

#ifndef SDL_ogcosk_c_h_
#define SDL_ogcosk_c_h_

#include "../../SDL_internal.h"
#include "../SDL_sysvideo.h"

#include "SDL_ogcsupport.h"

extern const SDL_OGC_VkPlugin *OGC_VkPlugin;

void OGC_StartTextInput(_THIS);
void OGC_StopTextInput(_THIS);
void OGC_SetTextInputRect(_THIS, const SDL_Rect *rect);
void OGC_ClearComposition(_THIS);
SDL_bool OGC_IsTextInputShown(_THIS);

SDL_bool OGC_HasScreenKeyboardSupport(_THIS);
void OGC_ShowScreenKeyboard(_THIS, SDL_Window *window);
void OGC_HideScreenKeyboard(_THIS, SDL_Window *window);
SDL_bool OGC_IsScreenKeyboardShown(_THIS, SDL_Window *window);

SDL_bool OGC_keyboard_render(_THIS);
int OGC_keyboard_get_pan_y(_THIS);

#endif /* SDL_ogcosk_c_h_ */

/* vi: set ts=4 sw=4 expandtab: */
Loading
Loading