diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c index c06585df5..4ffe51d36 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm.c +++ b/src/render/vitagxm/SDL_render_vita_gxm.c @@ -36,6 +36,8 @@ #include "SDL_render_vita_gxm_tools.h" #include "SDL_render_vita_gxm_memory.h" +#include + static SDL_Renderer *VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags); static void VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event); @@ -1050,6 +1052,25 @@ VITA_GXM_RenderPresent(SDL_Renderer *renderer) data->displayData.address = data->displayBufferData[data->backBufferIndex]; + + SceCommonDialogUpdateParam updateParam; + + SDL_memset(&updateParam, 0, sizeof(updateParam)); + + updateParam.renderTarget.colorFormat = VITA_GXM_COLOR_FORMAT; + updateParam.renderTarget.surfaceType = SCE_GXM_COLOR_SURFACE_LINEAR; + updateParam.renderTarget.width = VITA_GXM_SCREEN_WIDTH; + updateParam.renderTarget.height = VITA_GXM_SCREEN_HEIGHT; + updateParam.renderTarget.strideInPixels = VITA_GXM_SCREEN_STRIDE; + + updateParam.renderTarget.colorSurfaceData = data->displayBufferData[data->backBufferIndex]; + updateParam.renderTarget.depthSurfaceData = data->depthBufferData; + + updateParam.displaySyncObject = (SceGxmSyncObject *)data->displayBufferSync[data->backBufferIndex]; + + sceCommonDialogUpdate(&updateParam); + + sceGxmDisplayQueueAddEntry( data->displayBufferSync[data->frontBufferIndex], // OLD fb data->displayBufferSync[data->backBufferIndex], // NEW fb diff --git a/src/video/vita/SDL_vitavideo.c b/src/video/vita/SDL_vitavideo.c index 5a22093fc..e639305fc 100644 --- a/src/video/vita/SDL_vitavideo.c +++ b/src/video/vita/SDL_vitavideo.c @@ -39,6 +39,8 @@ #include "SDL_vitamouse_c.h" #include "SDL_vitagl_c.h" +#include + SDL_Window *Vita_Window; static int @@ -52,9 +54,11 @@ VITA_Destroy(SDL_VideoDevice * device) { /* SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata; */ - if (device->driverdata != NULL) { - device->driverdata = NULL; - } + SDL_free(device->driverdata); + SDL_free(device); +// if (device->driverdata != NULL) { +// device->driverdata = NULL; +// } } static SDL_VideoDevice * @@ -88,6 +92,7 @@ VITA_Create() } device->gl_data = gldata; phdata->egl_initialized = SDL_TRUE; + phdata->ime_active = SDL_FALSE; device->driverdata = phdata; @@ -311,28 +316,120 @@ VITA_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) return SDL_FALSE; } - -/* TO Write Me */ SDL_bool VITA_HasScreenKeyboardSupport(_THIS) { - return SDL_FALSE; + return SDL_TRUE; } + void VITA_ShowScreenKeyboard(_THIS, SDL_Window *window) { + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + + wchar_t *title = L""; + wchar_t *text = L""; + + SceImeDialogParam param; + sceImeDialogParamInit(¶m); + + param.supportedLanguages = SCE_IME_LANGUAGE_ENGLISH_US; + param.languagesForced = SCE_FALSE; + param.type = SCE_IME_TYPE_DEFAULT; + param.option = 0; + param.textBoxMode = SCE_IME_DIALOG_TEXTBOX_MODE_WITH_CLEAR; + param.maxTextLength = SCE_IME_DIALOG_MAX_TEXT_LENGTH; + + param.title = title; + param.initialText = text; + param.inputTextBuffer = videodata->ime_buffer; + + SceInt32 res = sceImeDialogInit(¶m); + if (res < 0) { + SDL_SetError("Failed to init IME dialog"); + return; + } + + videodata->ime_active = SDL_TRUE; } + void VITA_HideScreenKeyboard(_THIS, SDL_Window *window) { + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + + switch (dialogStatus) { + default: + case SCE_COMMON_DIALOG_STATUS_NONE: + case SCE_COMMON_DIALOG_STATUS_RUNNING: + break; + case SCE_COMMON_DIALOG_STATUS_FINISHED: + sceImeDialogTerm(); + break; + } + + videodata->ime_active = SDL_FALSE; } + SDL_bool VITA_IsScreenKeyboardShown(_THIS, SDL_Window *window) { - return SDL_FALSE; + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + return (dialogStatus == SCE_COMMON_DIALOG_STATUS_RUNNING); +} + + +static void utf16_to_utf8(const uint16_t *src, uint8_t *dst) { + int i; + for (i = 0; src[i]; i++) { + if ((src[i] & 0xFF80) == 0) { + *(dst++) = src[i] & 0xFF; + } else if((src[i] & 0xF800) == 0) { + *(dst++) = ((src[i] >> 6) & 0xFF) | 0xC0; + *(dst++) = (src[i] & 0x3F) | 0x80; + } else if((src[i] & 0xFC00) == 0xD800 && (src[i + 1] & 0xFC00) == 0xDC00) { + *(dst++) = (((src[i] + 64) >> 8) & 0x3) | 0xF0; + *(dst++) = (((src[i] >> 2) + 16) & 0x3F) | 0x80; + *(dst++) = ((src[i] >> 4) & 0x30) | 0x80 | ((src[i + 1] << 2) & 0xF); + *(dst++) = (src[i + 1] & 0x3F) | 0x80; + i += 1; + } else { + *(dst++) = ((src[i] >> 12) & 0xF) | 0xE0; + *(dst++) = ((src[i] >> 6) & 0x3F) | 0x80; + *(dst++) = (src[i] & 0x3F) | 0x80; + } + } + + *dst = '\0'; } void VITA_PumpEvents(_THIS) { + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + VITA_PollTouch(); VITA_PollKeyboard(); VITA_PollMouse(); + + if (videodata->ime_active == SDL_TRUE) { + // update IME status. Terminate, if finished + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + if (dialogStatus == SCE_COMMON_DIALOG_STATUS_FINISHED) { + + SceImeDialogResult result; + SDL_memset(&result, 0, sizeof(SceImeDialogResult)); + sceImeDialogGetResult(&result); + + // Convert UTF16 to UTF8 + uint8_t utf8_buffer[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; + utf16_to_utf8(videodata->ime_buffer, utf8_buffer); + // send sdl event + SDL_SendKeyboardText((const char*)utf8_buffer); + + sceImeDialogTerm(); + + videodata->ime_active = SDL_FALSE; + } + + } } #endif /* SDL_VIDEO_DRIVER_VITA */ diff --git a/src/video/vita/SDL_vitavideo.h b/src/video/vita/SDL_vitavideo.h index 1902ec6d1..8f02e9680 100644 --- a/src/video/vita/SDL_vitavideo.h +++ b/src/video/vita/SDL_vitavideo.h @@ -25,11 +25,15 @@ #include "../../SDL_internal.h" #include "../SDL_sysvideo.h" +#include + typedef struct SDL_VideoData { SDL_bool egl_initialized; /* OpenGL device initialization status */ uint32_t egl_refcount; /* OpenGL reference count */ + wchar_t ime_buffer[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; + SDL_bool ime_active; } SDL_VideoData;