mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-12 04:35:56 +00:00
IME fixes (#3207)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
- Moved enums, flags, and structs to ime_common.h to simplify usage with Ime and ImeDialog - Updated Ime to use an enum as the return type, consistent with ImeDialog - Removed duplicate definition of OrbisImeKeycode - Added OrbisImeLanguage as a flags enum - Added missing options to OrbisImeOption - Removed OrbisImeDialogOption; OrbisImeOption should be used instead - Added OrbisImeTextAreaMode - Updated OrbisImeTextAreaMode - Fixed OrbisImeEventParam by adding the missing member OrbisImePanelType panel_type - Updated the sceImeOpen declaration to use extended parameters (not yet implemented) -Fixed Diablo III (CUSA00434) assertion failure on ImeDialog initialization Co-authored-by: w1naenator <valdis.bogdans@hotmail.com>
This commit is contained in:
parent
80f7ec2681
commit
ddede4a52d
7 changed files with 325 additions and 258 deletions
|
@ -43,8 +43,8 @@ public:
|
||||||
openEvent.param.rect.x = m_param.ime.posx;
|
openEvent.param.rect.x = m_param.ime.posx;
|
||||||
openEvent.param.rect.y = m_param.ime.posy;
|
openEvent.param.rect.y = m_param.ime.posy;
|
||||||
} else {
|
} else {
|
||||||
openEvent.param.resource_id_array.userId = 1;
|
openEvent.param.resource_id_array.user_id = 1;
|
||||||
openEvent.param.resource_id_array.resourceId[0] = 1;
|
openEvent.param.resource_id_array.resource_id[0] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we supposed to call the event handler on init with
|
// Are we supposed to call the event handler on init with
|
||||||
|
@ -59,10 +59,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Update(OrbisImeEventHandler handler) {
|
Error Update(OrbisImeEventHandler handler) {
|
||||||
if (!m_ime_mode) {
|
if (!m_ime_mode) {
|
||||||
/* We don't handle any events for ImeKeyboard */
|
/* We don't handle any events for ImeKeyboard */
|
||||||
return ORBIS_OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_lock lock{g_ime_state.queue_mutex};
|
std::unique_lock lock{g_ime_state.queue_mutex};
|
||||||
|
@ -73,7 +73,7 @@ public:
|
||||||
Execute(handler, &event, false);
|
Execute(handler, &event, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ORBIS_OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Execute(OrbisImeEventHandler handler, OrbisImeEvent* event, bool use_param_handler) {
|
void Execute(OrbisImeEventHandler handler, OrbisImeEvent* event, bool use_param_handler) {
|
||||||
|
@ -94,14 +94,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 SetText(const char16_t* text, u32 length) {
|
Error SetText(const char16_t* text, u32 length) {
|
||||||
g_ime_state.SetText(text, length);
|
g_ime_state.SetText(text, length);
|
||||||
return ORBIS_OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 SetCaret(const OrbisImeCaret* caret) {
|
Error SetCaret(const OrbisImeCaret* caret) {
|
||||||
g_ime_state.SetCaret(caret->index);
|
g_ime_state.SetCaret(caret->index);
|
||||||
return ORBIS_OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsIme() {
|
bool IsIme() {
|
||||||
|
@ -222,11 +222,11 @@ int PS4_SYSV_ABI sceImeGetPanelPositionAndForm() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32* height) {
|
Error PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32* height) {
|
||||||
LOG_INFO(Lib_Ime, "called");
|
LOG_INFO(Lib_Ime, "called");
|
||||||
|
|
||||||
if (!width || !height) {
|
if (!width || !height) {
|
||||||
return ORBIS_IME_ERROR_INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (param->type) {
|
switch (param->type) {
|
||||||
|
@ -244,18 +244,18 @@ s32 PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32*
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ORBIS_OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceImeKeyboardClose(s32 userId) {
|
Error PS4_SYSV_ABI sceImeKeyboardClose(s32 userId) {
|
||||||
LOG_INFO(Lib_Ime, "(STUBBED) called");
|
LOG_INFO(Lib_Ime, "(STUBBED) called");
|
||||||
|
|
||||||
if (!g_keyboard_handler) {
|
if (!g_keyboard_handler) {
|
||||||
return ORBIS_IME_ERROR_NOT_OPENED;
|
return Error::NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_keyboard_handler.release();
|
g_keyboard_handler.release();
|
||||||
return ORBIS_OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeKeyboardGetInfo() {
|
int PS4_SYSV_ABI sceImeKeyboardGetInfo() {
|
||||||
|
@ -268,25 +268,25 @@ int PS4_SYSV_ABI sceImeKeyboardGetResourceId() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceImeKeyboardOpen(s32 userId, const OrbisImeKeyboardParam* param) {
|
Error PS4_SYSV_ABI sceImeKeyboardOpen(s32 userId, const OrbisImeKeyboardParam* param) {
|
||||||
LOG_INFO(Lib_Ime, "called");
|
LOG_INFO(Lib_Ime, "called");
|
||||||
|
|
||||||
if (!param) {
|
if (!param) {
|
||||||
return ORBIS_IME_ERROR_INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
if (!param->arg) {
|
if (!param->arg) {
|
||||||
return ORBIS_IME_ERROR_INVALID_ARG;
|
return Error::INVALID_ARG;
|
||||||
}
|
}
|
||||||
if (!param->handler) {
|
if (!param->handler) {
|
||||||
return ORBIS_IME_ERROR_INVALID_HANDLER;
|
return Error::INVALID_HANDLER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_keyboard_handler) {
|
if (g_keyboard_handler) {
|
||||||
return ORBIS_IME_ERROR_BUSY;
|
return Error::BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_keyboard_handler = std::make_unique<ImeHandler>(param);
|
g_keyboard_handler = std::make_unique<ImeHandler>(param);
|
||||||
return ORBIS_OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeKeyboardOpenInternal() {
|
int PS4_SYSV_ABI sceImeKeyboardOpenInternal() {
|
||||||
|
@ -304,18 +304,18 @@ int PS4_SYSV_ABI sceImeKeyboardUpdate() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceImeOpen(const OrbisImeParam* param, const void* extended) {
|
Error PS4_SYSV_ABI sceImeOpen(const OrbisImeParam* param, const OrbisImeParamExtended* extended) {
|
||||||
LOG_INFO(Lib_Ime, "called");
|
LOG_INFO(Lib_Ime, "called");
|
||||||
|
|
||||||
if (!param) {
|
if (!param) {
|
||||||
return ORBIS_IME_ERROR_INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
if (g_ime_handler) {
|
if (g_ime_handler) {
|
||||||
return ORBIS_IME_ERROR_BUSY;
|
return Error::BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ime_handler = std::make_unique<ImeHandler>(param);
|
g_ime_handler = std::make_unique<ImeHandler>(param);
|
||||||
return ORBIS_OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeOpenInternal() {
|
int PS4_SYSV_ABI sceImeOpenInternal() {
|
||||||
|
@ -339,27 +339,27 @@ int PS4_SYSV_ABI sceImeSetCandidateIndex() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeSetCaret(const OrbisImeCaret* caret) {
|
Error PS4_SYSV_ABI sceImeSetCaret(const OrbisImeCaret* caret) {
|
||||||
LOG_TRACE(Lib_Ime, "called");
|
LOG_TRACE(Lib_Ime, "called");
|
||||||
|
|
||||||
if (!g_ime_handler) {
|
if (!g_ime_handler) {
|
||||||
return ORBIS_IME_ERROR_NOT_OPENED;
|
return Error::NOT_OPENED;
|
||||||
}
|
}
|
||||||
if (!caret) {
|
if (!caret) {
|
||||||
return ORBIS_IME_ERROR_INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_ime_handler->SetCaret(caret);
|
return g_ime_handler->SetCaret(caret);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceImeSetText(const char16_t* text, u32 length) {
|
Error PS4_SYSV_ABI sceImeSetText(const char16_t* text, u32 length) {
|
||||||
LOG_TRACE(Lib_Ime, "called");
|
LOG_TRACE(Lib_Ime, "called");
|
||||||
|
|
||||||
if (!g_ime_handler) {
|
if (!g_ime_handler) {
|
||||||
return ORBIS_IME_ERROR_NOT_OPENED;
|
return Error::NOT_OPENED;
|
||||||
}
|
}
|
||||||
if (!text) {
|
if (!text) {
|
||||||
return ORBIS_IME_ERROR_INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_ime_handler->SetText(text, length);
|
return g_ime_handler->SetText(text, length);
|
||||||
|
@ -370,7 +370,7 @@ int PS4_SYSV_ABI sceImeSetTextGeometry() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceImeUpdate(OrbisImeEventHandler handler) {
|
Error PS4_SYSV_ABI sceImeUpdate(OrbisImeEventHandler handler) {
|
||||||
if (g_ime_handler) {
|
if (g_ime_handler) {
|
||||||
g_ime_handler->Update(handler);
|
g_ime_handler->Update(handler);
|
||||||
}
|
}
|
||||||
|
@ -380,10 +380,10 @@ s32 PS4_SYSV_ABI sceImeUpdate(OrbisImeEventHandler handler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_ime_handler || !g_keyboard_handler) {
|
if (!g_ime_handler || !g_keyboard_handler) {
|
||||||
return ORBIS_IME_ERROR_NOT_OPENED;
|
return Error::NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ORBIS_OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeVshClearPreedit() {
|
int PS4_SYSV_ABI sceImeVshClearPreedit() {
|
||||||
|
|
|
@ -13,72 +13,6 @@ class SymbolsResolver;
|
||||||
|
|
||||||
namespace Libraries::Ime {
|
namespace Libraries::Ime {
|
||||||
|
|
||||||
constexpr u32 ORBIS_IME_MAX_TEXT_LENGTH = 2048;
|
|
||||||
|
|
||||||
enum class OrbisImeKeyboardOption : u32 {
|
|
||||||
Default = 0,
|
|
||||||
Repeat = 1,
|
|
||||||
RepeatEachKey = 2,
|
|
||||||
AddOsk = 4,
|
|
||||||
EffectiveWithIme = 8,
|
|
||||||
DisableResume = 16,
|
|
||||||
DisableCapslockWithoutShift = 32,
|
|
||||||
};
|
|
||||||
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeKeyboardOption)
|
|
||||||
|
|
||||||
enum class OrbisImeOption : u32 {
|
|
||||||
DEFAULT = 0,
|
|
||||||
MULTILINE = 1,
|
|
||||||
NO_AUTO_CAPITALIZATION = 2,
|
|
||||||
PASSWORD = 4,
|
|
||||||
LANGUAGES_FORCED = 8,
|
|
||||||
EXT_KEYBOARD = 16,
|
|
||||||
NO_LEARNING = 32,
|
|
||||||
FIXED_POSITION = 64,
|
|
||||||
DISABLE_RESUME = 256,
|
|
||||||
DISABLE_AUTO_SPACE = 512,
|
|
||||||
DISABLE_POSITION_ADJUSTMENT = 2048,
|
|
||||||
EXPANDED_PREEDIT_BUFFER = 4096,
|
|
||||||
USE_JAPANESE_EISUU_KEY_AS_CAPSLOCK = 8192,
|
|
||||||
USE_2K_COORDINATES = 16384,
|
|
||||||
};
|
|
||||||
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeOption)
|
|
||||||
|
|
||||||
struct OrbisImeKeyboardParam {
|
|
||||||
OrbisImeKeyboardOption option;
|
|
||||||
s8 reserved1[4];
|
|
||||||
void* arg;
|
|
||||||
OrbisImeEventHandler handler;
|
|
||||||
s8 reserved2[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OrbisImeParam {
|
|
||||||
s32 user_id;
|
|
||||||
OrbisImeType type;
|
|
||||||
u64 supported_languages;
|
|
||||||
OrbisImeEnterLabel enter_label;
|
|
||||||
OrbisImeInputMethod input_method;
|
|
||||||
OrbisImeTextFilter filter;
|
|
||||||
OrbisImeOption option;
|
|
||||||
u32 maxTextLength;
|
|
||||||
char16_t* inputTextBuffer;
|
|
||||||
float posx;
|
|
||||||
float posy;
|
|
||||||
OrbisImeHorizontalAlignment horizontal_alignment;
|
|
||||||
OrbisImeVerticalAlignment vertical_alignment;
|
|
||||||
void* work;
|
|
||||||
void* arg;
|
|
||||||
OrbisImeEventHandler handler;
|
|
||||||
s8 reserved[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OrbisImeCaret {
|
|
||||||
f32 x;
|
|
||||||
f32 y;
|
|
||||||
u32 height;
|
|
||||||
u32 index;
|
|
||||||
};
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI FinalizeImeModule();
|
int PS4_SYSV_ABI FinalizeImeModule();
|
||||||
int PS4_SYSV_ABI InitializeImeModule();
|
int PS4_SYSV_ABI InitializeImeModule();
|
||||||
int PS4_SYSV_ABI sceImeCheckFilterText();
|
int PS4_SYSV_ABI sceImeCheckFilterText();
|
||||||
|
@ -98,22 +32,22 @@ int PS4_SYSV_ABI sceImeDisableController();
|
||||||
int PS4_SYSV_ABI sceImeFilterText();
|
int PS4_SYSV_ABI sceImeFilterText();
|
||||||
int PS4_SYSV_ABI sceImeForTestFunction();
|
int PS4_SYSV_ABI sceImeForTestFunction();
|
||||||
int PS4_SYSV_ABI sceImeGetPanelPositionAndForm();
|
int PS4_SYSV_ABI sceImeGetPanelPositionAndForm();
|
||||||
s32 PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32* height);
|
Error PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32* height);
|
||||||
s32 PS4_SYSV_ABI sceImeKeyboardClose(s32 userId);
|
Error PS4_SYSV_ABI sceImeKeyboardClose(s32 userId);
|
||||||
int PS4_SYSV_ABI sceImeKeyboardGetInfo();
|
int PS4_SYSV_ABI sceImeKeyboardGetInfo();
|
||||||
int PS4_SYSV_ABI sceImeKeyboardGetResourceId();
|
int PS4_SYSV_ABI sceImeKeyboardGetResourceId();
|
||||||
s32 PS4_SYSV_ABI sceImeKeyboardOpen(s32 userId, const OrbisImeKeyboardParam* param);
|
Error PS4_SYSV_ABI sceImeKeyboardOpen(s32 userId, const OrbisImeKeyboardParam* param);
|
||||||
int PS4_SYSV_ABI sceImeKeyboardOpenInternal();
|
int PS4_SYSV_ABI sceImeKeyboardOpenInternal();
|
||||||
int PS4_SYSV_ABI sceImeKeyboardSetMode();
|
int PS4_SYSV_ABI sceImeKeyboardSetMode();
|
||||||
int PS4_SYSV_ABI sceImeKeyboardUpdate();
|
int PS4_SYSV_ABI sceImeKeyboardUpdate();
|
||||||
s32 PS4_SYSV_ABI sceImeOpen(const OrbisImeParam* param, const void* extended);
|
Error PS4_SYSV_ABI sceImeOpen(const OrbisImeParam* param, const OrbisImeParamExtended* extended);
|
||||||
int PS4_SYSV_ABI sceImeOpenInternal();
|
int PS4_SYSV_ABI sceImeOpenInternal();
|
||||||
void PS4_SYSV_ABI sceImeParamInit(OrbisImeParam* param);
|
void PS4_SYSV_ABI sceImeParamInit(OrbisImeParam* param);
|
||||||
int PS4_SYSV_ABI sceImeSetCandidateIndex();
|
int PS4_SYSV_ABI sceImeSetCandidateIndex();
|
||||||
s32 PS4_SYSV_ABI sceImeSetCaret(const OrbisImeCaret* caret);
|
Error PS4_SYSV_ABI sceImeSetCaret(const OrbisImeCaret* caret);
|
||||||
s32 PS4_SYSV_ABI sceImeSetText(const char16_t* text, u32 length);
|
Error PS4_SYSV_ABI sceImeSetText(const char16_t* text, u32 length);
|
||||||
int PS4_SYSV_ABI sceImeSetTextGeometry();
|
int PS4_SYSV_ABI sceImeSetTextGeometry();
|
||||||
s32 PS4_SYSV_ABI sceImeUpdate(OrbisImeEventHandler handler);
|
Error PS4_SYSV_ABI sceImeUpdate(OrbisImeEventHandler handler);
|
||||||
int PS4_SYSV_ABI sceImeVshClearPreedit();
|
int PS4_SYSV_ABI sceImeVshClearPreedit();
|
||||||
int PS4_SYSV_ABI sceImeVshClose();
|
int PS4_SYSV_ABI sceImeVshClose();
|
||||||
int PS4_SYSV_ABI sceImeVshConfirmPreedit();
|
int PS4_SYSV_ABI sceImeVshConfirmPreedit();
|
||||||
|
|
|
@ -3,9 +3,108 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/enum.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "core/libraries/rtc/rtc.h"
|
#include "core/libraries/rtc/rtc.h"
|
||||||
|
|
||||||
|
constexpr u32 ORBIS_IME_MAX_TEXT_LENGTH = 2048;
|
||||||
|
constexpr u32 ORBIS_IME_DIALOG_MAX_TEXT_LENGTH = 2048;
|
||||||
|
|
||||||
|
enum class Error : u32 {
|
||||||
|
OK = 0x0,
|
||||||
|
BUSY = 0x80bc0001,
|
||||||
|
NOT_OPENED = 0x80bc0002,
|
||||||
|
NO_MEMORY = 0x80bc0003,
|
||||||
|
CONNECTION_FAILED = 0x80bc0004,
|
||||||
|
TOO_MANY_REQUESTS = 0x80bc0005,
|
||||||
|
INVALID_TEXT = 0x80bc0006,
|
||||||
|
EVENT_OVERFLOW = 0x80bc0007,
|
||||||
|
NOT_ACTIVE = 0x80bc0008,
|
||||||
|
IME_SUSPENDING = 0x80bc0009,
|
||||||
|
DEVICE_IN_USE = 0x80bc000a,
|
||||||
|
INVALID_USER_ID = 0x80bc0010,
|
||||||
|
INVALID_TYPE = 0x80bc0011,
|
||||||
|
INVALID_SUPPORTED_LANGUAGES = 0x80bc0012,
|
||||||
|
INVALID_ENTER_LABEL = 0x80bc0013,
|
||||||
|
INVALID_INPUT_METHOD = 0x80bc0014,
|
||||||
|
INVALID_OPTION = 0x80bc0015,
|
||||||
|
INVALID_MAX_TEXT_LENGTH = 0x80bc0016,
|
||||||
|
INVALID_INPUT_TEXT_BUFFER = 0x80bc0017,
|
||||||
|
INVALID_POSX = 0x80bc0018,
|
||||||
|
INVALID_POSY = 0x80bc0019,
|
||||||
|
INVALID_HORIZONTALIGNMENT = 0x80bc001a,
|
||||||
|
INVALID_VERTICALALIGNMENT = 0x80bc001b,
|
||||||
|
INVALID_EXTENDED = 0x80bc001c,
|
||||||
|
INVALID_KEYBOARD_TYPE = 0x80bc001d,
|
||||||
|
INVALID_WORK = 0x80bc0020,
|
||||||
|
INVALID_ARG = 0x80bc0021,
|
||||||
|
INVALID_HANDLER = 0x80bc0022,
|
||||||
|
NO_RESOURCE_ID = 0x80bc0023,
|
||||||
|
INVALID_MODE = 0x80bc0024,
|
||||||
|
INVALID_PARAM = 0x80bc0030,
|
||||||
|
INVALID_ADDRESS = 0x80bc0031,
|
||||||
|
INVALID_RESERVED = 0x80bc0032,
|
||||||
|
INVALID_TIMING = 0x80bc0033,
|
||||||
|
INTERNAL = 0x80bc00ff,
|
||||||
|
DIALOG_INVALID_TITLE = 0x80bc0101,
|
||||||
|
DIALOG_NOT_RUNNING = 0x80bc0105,
|
||||||
|
DIALOG_NOT_FINISHED = 0x80bc0106,
|
||||||
|
DIALOG_NOT_IN_USE = 0x80bc0107
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class OrbisImeOption : u32 {
|
||||||
|
DEFAULT = 0,
|
||||||
|
MULTILINE = 1,
|
||||||
|
NO_AUTO_CAPITALIZATION = 2,
|
||||||
|
PASSWORD = 4,
|
||||||
|
LANGUAGES_FORCED = 8,
|
||||||
|
EXT_KEYBOARD = 16,
|
||||||
|
NO_LEARNING = 32,
|
||||||
|
FIXED_POSITION = 64,
|
||||||
|
DISABLE_COPY_PASTE = 128,
|
||||||
|
DISABLE_RESUME = 256,
|
||||||
|
DISABLE_AUTO_SPACE = 512,
|
||||||
|
DISABLE_POSITION_ADJUSTMENT = 2048,
|
||||||
|
EXPANDED_PREEDIT_BUFFER = 4096,
|
||||||
|
USE_JAPANESE_EISUU_KEY_AS_CAPSLOCK = 8192,
|
||||||
|
USE_2K_COORDINATES = 16384,
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeOption);
|
||||||
|
|
||||||
|
enum class OrbisImeLanguage : u64 {
|
||||||
|
DANISH = 0x0000000000000001,
|
||||||
|
GERMAN = 0x0000000000000002,
|
||||||
|
ENGLISH_US = 0x0000000000000004,
|
||||||
|
SPANISH = 0x0000000000000008,
|
||||||
|
FRENCH = 0x0000000000000010,
|
||||||
|
ITALIAN = 0x0000000000000020,
|
||||||
|
DUTCH = 0x0000000000000040,
|
||||||
|
NORWEGIAN = 0x0000000000000080,
|
||||||
|
POLISH = 0x0000000000000100,
|
||||||
|
PORTUGUESE_PT = 0x0000000000000200,
|
||||||
|
RUSSIAN = 0x0000000000000400,
|
||||||
|
FINNISH = 0x0000000000000800,
|
||||||
|
SWEDISH = 0x0000000000001000,
|
||||||
|
JAPANESE = 0x0000000000002000,
|
||||||
|
KOREAN = 0x0000000000004000,
|
||||||
|
SIMPLIFIED_CHINESE = 0x0000000000008000,
|
||||||
|
TRADITIONAL_CHINESE = 0x0000000000010000,
|
||||||
|
PORTUGUESE_BR = 0x0000000000020000,
|
||||||
|
ENGLISH_GB = 0x0000000000040000,
|
||||||
|
TURKISH = 0x0000000000080000,
|
||||||
|
SPANISH_LA = 0x0000000000100000,
|
||||||
|
ARABIC = 0x0000000001000000,
|
||||||
|
FRENCH_CA = 0x0000000002000000,
|
||||||
|
THAI = 0x0000000004000000,
|
||||||
|
CZECH = 0x0000000008000000,
|
||||||
|
GREEK = 0x0000000010000000,
|
||||||
|
INDONESIAN = 0x0000000020000000,
|
||||||
|
VIETNAMESE = 0x0000000040000000,
|
||||||
|
ROMANIAN = 0x0000000080000000,
|
||||||
|
HUNGARIAN = 0x0000000100000000,
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeLanguage);
|
||||||
|
|
||||||
enum class OrbisImeType : u32 {
|
enum class OrbisImeType : u32 {
|
||||||
Default = 0,
|
Default = 0,
|
||||||
BasicLatin = 1,
|
BasicLatin = 1,
|
||||||
|
@ -41,6 +140,7 @@ enum class OrbisImeEventId : u32 {
|
||||||
Open = 0,
|
Open = 0,
|
||||||
UpdateText = 1,
|
UpdateText = 1,
|
||||||
UpdateCaret = 2,
|
UpdateCaret = 2,
|
||||||
|
ChangeSize = 3,
|
||||||
PressClose = 4,
|
PressClose = 4,
|
||||||
PressEnter = 5,
|
PressEnter = 5,
|
||||||
Abort = 6,
|
Abort = 6,
|
||||||
|
@ -51,6 +151,10 @@ enum class OrbisImeEventId : u32 {
|
||||||
CandidateDone = 11,
|
CandidateDone = 11,
|
||||||
CandidateCancel = 12,
|
CandidateCancel = 12,
|
||||||
ChangeDevice = 14,
|
ChangeDevice = 14,
|
||||||
|
JumpToNextObject = 15,
|
||||||
|
JumpToBeforeObject = 16,
|
||||||
|
ChangeWindowType = 17,
|
||||||
|
|
||||||
ChangeInputMethodState = 18,
|
ChangeInputMethodState = 18,
|
||||||
|
|
||||||
KeyboardOpen = 256,
|
KeyboardOpen = 256,
|
||||||
|
@ -110,6 +214,13 @@ enum class OrbisImeDeviceType : u32 {
|
||||||
RemoteOsk = 3,
|
RemoteOsk = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class OrbisImePanelPriority : u32 {
|
||||||
|
Default = 0,
|
||||||
|
Alphabet = 1,
|
||||||
|
Symbol = 2,
|
||||||
|
Accent = 3,
|
||||||
|
};
|
||||||
|
|
||||||
struct OrbisImeRect {
|
struct OrbisImeRect {
|
||||||
f32 x;
|
f32 x;
|
||||||
f32 y;
|
f32 y;
|
||||||
|
@ -117,8 +228,22 @@ struct OrbisImeRect {
|
||||||
u32 height;
|
u32 height;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OrbisImeColor {
|
||||||
|
u8 r;
|
||||||
|
u8 g;
|
||||||
|
u8 b;
|
||||||
|
u8 a;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class OrbisImeTextAreaMode : u32 {
|
||||||
|
Disable = 0,
|
||||||
|
Edit = 1,
|
||||||
|
Preedit = 2,
|
||||||
|
Select = 3,
|
||||||
|
};
|
||||||
|
|
||||||
struct OrbisImeTextAreaProperty {
|
struct OrbisImeTextAreaProperty {
|
||||||
u32 mode; // OrbisImeTextAreaMode
|
OrbisImeTextAreaMode mode;
|
||||||
u32 index;
|
u32 index;
|
||||||
s32 length;
|
s32 length;
|
||||||
};
|
};
|
||||||
|
@ -135,14 +260,14 @@ struct OrbisImeKeycode {
|
||||||
char16_t character;
|
char16_t character;
|
||||||
u32 status;
|
u32 status;
|
||||||
OrbisImeKeyboardType type;
|
OrbisImeKeyboardType type;
|
||||||
s32 user_id;
|
s32 user_id; // Todo: switch to OrbisUserServiceUserId
|
||||||
u32 resource_id;
|
u32 resource_id;
|
||||||
Libraries::Rtc::OrbisRtcTick timestamp;
|
Libraries::Rtc::OrbisRtcTick timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisImeKeyboardResourceIdArray {
|
struct OrbisImeKeyboardResourceIdArray {
|
||||||
s32 userId;
|
s32 user_id; // Todo: switch to OrbisUserServiceUserId
|
||||||
u32 resourceId[5];
|
u32 resource_id[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class OrbisImeCaretMovementDirection : u32 {
|
enum class OrbisImeCaretMovementDirection : u32 {
|
||||||
|
@ -159,6 +284,16 @@ enum class OrbisImeCaretMovementDirection : u32 {
|
||||||
Bottom = 10,
|
Bottom = 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class OrbisImePanelType : u32 {
|
||||||
|
Hide = 0,
|
||||||
|
Osk = 1,
|
||||||
|
Dialog = 2,
|
||||||
|
Candidate = 3,
|
||||||
|
Edit = 4,
|
||||||
|
EditAndCandidate = 5,
|
||||||
|
Accessibility = 6,
|
||||||
|
};
|
||||||
|
|
||||||
union OrbisImeEventParam {
|
union OrbisImeEventParam {
|
||||||
OrbisImeRect rect;
|
OrbisImeRect rect;
|
||||||
OrbisImeEditText text;
|
OrbisImeEditText text;
|
||||||
|
@ -168,6 +303,7 @@ union OrbisImeEventParam {
|
||||||
char16_t* candidate_word;
|
char16_t* candidate_word;
|
||||||
s32 candidate_index;
|
s32 candidate_index;
|
||||||
OrbisImeDeviceType device_type;
|
OrbisImeDeviceType device_type;
|
||||||
|
OrbisImePanelType panel_type;
|
||||||
u32 input_method_state;
|
u32 input_method_state;
|
||||||
s8 reserved[64];
|
s8 reserved[64];
|
||||||
};
|
};
|
||||||
|
@ -177,7 +313,95 @@ struct OrbisImeEvent {
|
||||||
OrbisImeEventParam param;
|
OrbisImeEventParam param;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using OrbisImeExtKeyboardFilter = PS4_SYSV_ABI int (*)(const OrbisImeKeycode* srcKeycode,
|
||||||
|
u16* outKeycode, u32* outStatus,
|
||||||
|
void* reserved);
|
||||||
|
|
||||||
using OrbisImeTextFilter = PS4_SYSV_ABI int (*)(char16_t* outText, u32* outTextLength,
|
using OrbisImeTextFilter = PS4_SYSV_ABI int (*)(char16_t* outText, u32* outTextLength,
|
||||||
const char16_t* srcText, u32 srcTextLength);
|
const char16_t* srcText, u32 srcTextLength);
|
||||||
|
|
||||||
using OrbisImeEventHandler = PS4_SYSV_ABI void (*)(void* arg, const OrbisImeEvent* e);
|
using OrbisImeEventHandler = PS4_SYSV_ABI void (*)(void* arg, const OrbisImeEvent* e);
|
||||||
|
|
||||||
|
enum class OrbisImeKeyboardOption : u32 {
|
||||||
|
Default = 0,
|
||||||
|
Repeat = 1,
|
||||||
|
RepeatEachKey = 2,
|
||||||
|
AddOsk = 4,
|
||||||
|
EffectiveWithIme = 8,
|
||||||
|
DisableResume = 16,
|
||||||
|
DisableCapslockWithoutShift = 32,
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeKeyboardOption)
|
||||||
|
|
||||||
|
struct OrbisImeKeyboardParam {
|
||||||
|
OrbisImeKeyboardOption option;
|
||||||
|
s8 reserved1[4];
|
||||||
|
void* arg;
|
||||||
|
OrbisImeEventHandler handler;
|
||||||
|
s8 reserved2[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrbisImeParam {
|
||||||
|
s32 user_id; // Todo: switch to OrbisUserServiceUserId
|
||||||
|
OrbisImeType type;
|
||||||
|
u64 supported_languages; // OrbisImeLanguage flags
|
||||||
|
OrbisImeEnterLabel enter_label;
|
||||||
|
OrbisImeInputMethod input_method;
|
||||||
|
OrbisImeTextFilter filter;
|
||||||
|
OrbisImeOption option;
|
||||||
|
u32 maxTextLength;
|
||||||
|
char16_t* inputTextBuffer;
|
||||||
|
f32 posx;
|
||||||
|
f32 posy;
|
||||||
|
OrbisImeHorizontalAlignment horizontal_alignment;
|
||||||
|
OrbisImeVerticalAlignment vertical_alignment;
|
||||||
|
void* work;
|
||||||
|
void* arg;
|
||||||
|
OrbisImeEventHandler handler;
|
||||||
|
s8 reserved[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrbisImeCaret {
|
||||||
|
f32 x;
|
||||||
|
f32 y;
|
||||||
|
u32 height;
|
||||||
|
u32 index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrbisImeDialogParam {
|
||||||
|
s32 user_id;
|
||||||
|
OrbisImeType type;
|
||||||
|
u64 supported_languages; // OrbisImeLanguage flags
|
||||||
|
OrbisImeEnterLabel enter_label;
|
||||||
|
OrbisImeInputMethod input_method;
|
||||||
|
OrbisImeTextFilter filter;
|
||||||
|
OrbisImeOption option;
|
||||||
|
u32 max_text_length;
|
||||||
|
char16_t* input_text_buffer;
|
||||||
|
f32 posx;
|
||||||
|
f32 posy;
|
||||||
|
OrbisImeHorizontalAlignment horizontal_alignment;
|
||||||
|
OrbisImeVerticalAlignment vertical_alignment;
|
||||||
|
const char16_t* placeholder;
|
||||||
|
const char16_t* title;
|
||||||
|
s8 reserved[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrbisImeParamExtended {
|
||||||
|
u32 option; // OrbisImeExtOption flags
|
||||||
|
OrbisImeColor color_base;
|
||||||
|
OrbisImeColor color_line;
|
||||||
|
OrbisImeColor color_text_field;
|
||||||
|
OrbisImeColor color_preedit;
|
||||||
|
OrbisImeColor color_button_default;
|
||||||
|
OrbisImeColor color_button_function;
|
||||||
|
OrbisImeColor color_button_symbol;
|
||||||
|
OrbisImeColor color_text;
|
||||||
|
OrbisImeColor color_special;
|
||||||
|
OrbisImePanelPriority priority;
|
||||||
|
char* additional_dictionary_path;
|
||||||
|
OrbisImeExtKeyboardFilter ext_keyboard_filter;
|
||||||
|
u32 disable_device;
|
||||||
|
u32 ext_keyboard_mode;
|
||||||
|
s8 reserved[60];
|
||||||
|
};
|
||||||
|
|
|
@ -20,19 +20,19 @@ static OrbisImeDialogResult g_ime_dlg_result{};
|
||||||
static ImeDialogState g_ime_dlg_state{};
|
static ImeDialogState g_ime_dlg_state{};
|
||||||
static ImeDialogUi g_ime_dlg_ui;
|
static ImeDialogUi g_ime_dlg_ui;
|
||||||
|
|
||||||
static bool IsValidOption(OrbisImeDialogOption option, OrbisImeType type) {
|
static bool IsValidOption(OrbisImeOption option, OrbisImeType type) {
|
||||||
if (False(~option &
|
if (False(~option & (OrbisImeOption::MULTILINE |
|
||||||
(OrbisImeDialogOption::Multiline | OrbisImeDialogOption::NoAutoCompletion))) {
|
OrbisImeOption::NO_AUTO_CAPITALIZATION /* NoAutoCompletion */))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (True(option & OrbisImeDialogOption::Multiline) && type != OrbisImeType::Default &&
|
if (True(option & OrbisImeOption::MULTILINE) && type != OrbisImeType::Default &&
|
||||||
type != OrbisImeType::BasicLatin) {
|
type != OrbisImeType::BasicLatin) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (True(option & OrbisImeDialogOption::NoAutoCompletion) && type != OrbisImeType::Number &&
|
if (True(option & OrbisImeOption::NO_AUTO_CAPITALIZATION /* NoAutoCompletion */) &&
|
||||||
type != OrbisImeType::BasicLatin) {
|
type != OrbisImeType::Number && type != OrbisImeType::BasicLatin) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ Error PS4_SYSV_ABI sceImeDialogGetPanelSize(const OrbisImeDialogParam* param, u3
|
||||||
case OrbisImeType::Url:
|
case OrbisImeType::Url:
|
||||||
case OrbisImeType::Mail:
|
case OrbisImeType::Mail:
|
||||||
*width = 500; // original: 793
|
*width = 500; // original: 793
|
||||||
if (True(param->option & OrbisImeDialogOption::Multiline)) {
|
if (True(param->option & OrbisImeOption::MULTILINE)) {
|
||||||
*height = 300; // original: 576
|
*height = 300; // original: 576
|
||||||
} else {
|
} else {
|
||||||
*height = 150; // original: 476
|
*height = 150; // original: 476
|
||||||
|
@ -149,18 +149,20 @@ OrbisImeDialogStatus PS4_SYSV_ABI sceImeDialogGetStatus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExtended* extended) {
|
Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExtended* extended) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, ">> sceImeDialogInit: entering, param={}, extended={}",
|
||||||
|
static_cast<void*>(param), static_cast<void*>(extended));
|
||||||
if (g_ime_dlg_status != OrbisImeDialogStatus::None) {
|
if (g_ime_dlg_status != OrbisImeDialogStatus::None) {
|
||||||
LOG_INFO(Lib_ImeDialog, "IME dialog is already running");
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: busy (status=%u)", (u32)g_ime_dlg_status);
|
||||||
return Error::BUSY;
|
return Error::BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param == nullptr) {
|
if (param == nullptr) {
|
||||||
LOG_INFO(Lib_ImeDialog, "called with param (NULL)");
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: param is null");
|
||||||
return Error::INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!magic_enum::enum_contains(param->type)) {
|
if (!magic_enum::enum_contains(param->type)) {
|
||||||
LOG_INFO(Lib_ImeDialog, "Invalid param->type");
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid param->type=%u", (u32)param->type);
|
||||||
return Error::INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,16 +170,14 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt
|
||||||
// TODO: do correct param->supportedLanguages validation
|
// TODO: do correct param->supportedLanguages validation
|
||||||
|
|
||||||
if (param->posx < 0.0f ||
|
if (param->posx < 0.0f ||
|
||||||
param->posx >=
|
param->posx >= MAX_X_POSITIONS[False(param->option & OrbisImeOption::USE_2K_COORDINATES)]) {
|
||||||
MAX_X_POSITIONS[False(param->option & OrbisImeDialogOption::LargeResolution)]) {
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid posx=%f", param->posx);
|
||||||
LOG_INFO(Lib_ImeDialog, "Invalid param->posx");
|
|
||||||
return Error::INVALID_POSX;
|
return Error::INVALID_POSX;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param->posy < 0.0f ||
|
if (param->posy < 0.0f ||
|
||||||
param->posy >=
|
param->posy >= MAX_Y_POSITIONS[False(param->option & OrbisImeOption::USE_2K_COORDINATES)]) {
|
||||||
MAX_Y_POSITIONS[False(param->option & OrbisImeDialogOption::LargeResolution)]) {
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid posy=%f", param->posy);
|
||||||
LOG_INFO(Lib_ImeDialog, "Invalid param->posy");
|
|
||||||
return Error::INVALID_POSY;
|
return Error::INVALID_POSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,12 +192,13 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValidOption(param->option, param->type)) {
|
if (!IsValidOption(param->option, param->type)) {
|
||||||
LOG_INFO(Lib_ImeDialog, "Invalid param->option");
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid option=0x%X for type=%u",
|
||||||
|
static_cast<u32>(param->option), (u32)param->type);
|
||||||
return Error::INVALID_PARAM;
|
return Error::INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param->input_text_buffer == nullptr) {
|
if (param->input_text_buffer == nullptr) {
|
||||||
LOG_INFO(Lib_ImeDialog, "Invalid param->inputTextBuffer");
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: input_text_buffer is null");
|
||||||
return Error::INVALID_INPUT_TEXT_BUFFER;
|
return Error::INVALID_INPUT_TEXT_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,16 +221,24 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param->max_text_length > ORBIS_IME_DIALOG_MAX_TEXT_LENGTH) {
|
if (param->max_text_length == 0 || param->max_text_length > ORBIS_IME_MAX_TEXT_LENGTH) {
|
||||||
LOG_INFO(Lib_ImeDialog, "Invalid param->maxTextLength");
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid max_text_length=%u",
|
||||||
|
param->max_text_length);
|
||||||
return Error::INVALID_MAX_TEXT_LENGTH;
|
return Error::INVALID_MAX_TEXT_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Title string validation
|
||||||
|
if (param->title != nullptr && !std::char_traits<char16_t>::length(param->title)) {
|
||||||
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: title is empty");
|
||||||
|
return Error::INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
g_ime_dlg_result = {};
|
g_ime_dlg_result = {};
|
||||||
g_ime_dlg_state = ImeDialogState(param, extended);
|
g_ime_dlg_state = ImeDialogState(param, extended);
|
||||||
g_ime_dlg_status = OrbisImeDialogStatus::Running;
|
g_ime_dlg_status = OrbisImeDialogStatus::Running;
|
||||||
g_ime_dlg_ui = ImeDialogUi(&g_ime_dlg_state, &g_ime_dlg_status, &g_ime_dlg_result);
|
g_ime_dlg_ui = ImeDialogUi(&g_ime_dlg_state, &g_ime_dlg_status, &g_ime_dlg_result);
|
||||||
|
|
||||||
|
LOG_INFO(Lib_ImeDialog, "<< sceImeDialogInit: successful, status now=Running");
|
||||||
return Error::OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,50 +13,6 @@ class SymbolsResolver;
|
||||||
|
|
||||||
namespace Libraries::ImeDialog {
|
namespace Libraries::ImeDialog {
|
||||||
|
|
||||||
constexpr u32 ORBIS_IME_DIALOG_MAX_TEXT_LENGTH = 2048;
|
|
||||||
|
|
||||||
enum class Error : u32 {
|
|
||||||
OK = 0x0,
|
|
||||||
BUSY = 0x80bc0001,
|
|
||||||
NOT_OPENED = 0x80bc0002,
|
|
||||||
NO_MEMORY = 0x80bc0003,
|
|
||||||
CONNECTION_FAILED = 0x80bc0004,
|
|
||||||
TOO_MANY_REQUESTS = 0x80bc0005,
|
|
||||||
INVALID_TEXT = 0x80bc0006,
|
|
||||||
EVENT_OVERFLOW = 0x80bc0007,
|
|
||||||
NOT_ACTIVE = 0x80bc0008,
|
|
||||||
IME_SUSPENDING = 0x80bc0009,
|
|
||||||
DEVICE_IN_USE = 0x80bc000a,
|
|
||||||
INVALID_USER_ID = 0x80bc0010,
|
|
||||||
INVALID_TYPE = 0x80bc0011,
|
|
||||||
INVALID_SUPPORTED_LANGUAGES = 0x80bc0012,
|
|
||||||
INVALID_ENTER_LABEL = 0x80bc0013,
|
|
||||||
INVALID_INPUT_METHOD = 0x80bc0014,
|
|
||||||
INVALID_OPTION = 0x80bc0015,
|
|
||||||
INVALID_MAX_TEXT_LENGTH = 0x80bc0016,
|
|
||||||
INVALID_INPUT_TEXT_BUFFER = 0x80bc0017,
|
|
||||||
INVALID_POSX = 0x80bc0018,
|
|
||||||
INVALID_POSY = 0x80bc0019,
|
|
||||||
INVALID_HORIZONTALIGNMENT = 0x80bc001a,
|
|
||||||
INVALID_VERTICALALIGNMENT = 0x80bc001b,
|
|
||||||
INVALID_EXTENDED = 0x80bc001c,
|
|
||||||
INVALID_KEYBOARD_TYPE = 0x80bc001d,
|
|
||||||
INVALID_WORK = 0x80bc0020,
|
|
||||||
INVALID_ARG = 0x80bc0021,
|
|
||||||
INVALID_HANDLER = 0x80bc0022,
|
|
||||||
NO_RESOURCE_ID = 0x80bc0023,
|
|
||||||
INVALID_MODE = 0x80bc0024,
|
|
||||||
INVALID_PARAM = 0x80bc0030,
|
|
||||||
INVALID_ADDRESS = 0x80bc0031,
|
|
||||||
INVALID_RESERVED = 0x80bc0032,
|
|
||||||
INVALID_TIMING = 0x80bc0033,
|
|
||||||
INTERNAL = 0x80bc00ff,
|
|
||||||
DIALOG_INVALID_TITLE = 0x80bc0101,
|
|
||||||
DIALOG_NOT_RUNNING = 0x80bc0105,
|
|
||||||
DIALOG_NOT_FINISHED = 0x80bc0106,
|
|
||||||
DIALOG_NOT_IN_USE = 0x80bc0107,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class OrbisImeDialogStatus : u32 {
|
enum class OrbisImeDialogStatus : u32 {
|
||||||
None = 0,
|
None = 0,
|
||||||
Running = 1,
|
Running = 1,
|
||||||
|
@ -69,87 +25,11 @@ enum class OrbisImeDialogEndStatus : u32 {
|
||||||
Aborted = 2,
|
Aborted = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class OrbisImeDialogOption : u32 {
|
|
||||||
Default = 0,
|
|
||||||
Multiline = 1,
|
|
||||||
NoAutoCorrection = 2,
|
|
||||||
NoAutoCompletion = 4,
|
|
||||||
// TODO: Document missing options
|
|
||||||
LargeResolution = 1024,
|
|
||||||
};
|
|
||||||
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeDialogOption)
|
|
||||||
|
|
||||||
enum class OrbisImePanelPriority : u32 {
|
|
||||||
Default = 0,
|
|
||||||
Alphabet = 1,
|
|
||||||
Symbol = 2,
|
|
||||||
Accent = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OrbisImeColor {
|
|
||||||
u8 r;
|
|
||||||
u8 g;
|
|
||||||
u8 b;
|
|
||||||
u8 a;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OrbisImeDialogResult {
|
struct OrbisImeDialogResult {
|
||||||
OrbisImeDialogEndStatus endstatus;
|
OrbisImeDialogEndStatus endstatus;
|
||||||
s32 reserved[12];
|
s32 reserved[12];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisImeKeycode {
|
|
||||||
u16 keycode;
|
|
||||||
char16_t character;
|
|
||||||
u32 status;
|
|
||||||
OrbisImeKeyboardType type;
|
|
||||||
s32 user_id;
|
|
||||||
u32 resource_id;
|
|
||||||
u64 timestamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
using OrbisImeExtKeyboardFilter = PS4_SYSV_ABI int (*)(const OrbisImeKeycode* srcKeycode,
|
|
||||||
u16* outKeycode, u32* outStatus,
|
|
||||||
void* reserved);
|
|
||||||
|
|
||||||
struct OrbisImeDialogParam {
|
|
||||||
s32 user_id;
|
|
||||||
OrbisImeType type;
|
|
||||||
u64 supported_languages;
|
|
||||||
OrbisImeEnterLabel enter_label;
|
|
||||||
OrbisImeInputMethod input_method;
|
|
||||||
OrbisImeTextFilter filter;
|
|
||||||
OrbisImeDialogOption option;
|
|
||||||
u32 max_text_length;
|
|
||||||
char16_t* input_text_buffer;
|
|
||||||
float posx;
|
|
||||||
float posy;
|
|
||||||
OrbisImeHorizontalAlignment horizontal_alignment;
|
|
||||||
OrbisImeVerticalAlignment vertical_alignment;
|
|
||||||
const char16_t* placeholder;
|
|
||||||
const char16_t* title;
|
|
||||||
s8 reserved[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OrbisImeParamExtended {
|
|
||||||
u32 option; // OrbisImeDialogOptionExtended
|
|
||||||
OrbisImeColor color_base;
|
|
||||||
OrbisImeColor color_line;
|
|
||||||
OrbisImeColor color_text_field;
|
|
||||||
OrbisImeColor color_preedit;
|
|
||||||
OrbisImeColor color_button_default;
|
|
||||||
OrbisImeColor color_button_function;
|
|
||||||
OrbisImeColor color_button_symbol;
|
|
||||||
OrbisImeColor color_text;
|
|
||||||
OrbisImeColor color_special;
|
|
||||||
OrbisImePanelPriority priority;
|
|
||||||
char* additional_dictionary_path;
|
|
||||||
OrbisImeExtKeyboardFilter ext_keyboard_filter;
|
|
||||||
uint32_t disable_device;
|
|
||||||
uint32_t ext_keyboard_mode;
|
|
||||||
int8_t reserved[60];
|
|
||||||
};
|
|
||||||
|
|
||||||
Error PS4_SYSV_ABI sceImeDialogAbort();
|
Error PS4_SYSV_ABI sceImeDialogAbort();
|
||||||
Error PS4_SYSV_ABI sceImeDialogForceClose();
|
Error PS4_SYSV_ABI sceImeDialogForceClose();
|
||||||
Error PS4_SYSV_ABI sceImeDialogForTestFunction();
|
Error PS4_SYSV_ABI sceImeDialogForTestFunction();
|
||||||
|
|
|
@ -21,12 +21,16 @@ namespace Libraries::ImeDialog {
|
||||||
|
|
||||||
ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param,
|
ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param,
|
||||||
const OrbisImeParamExtended* extended) {
|
const OrbisImeParamExtended* extended) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, ">> ImeDialogState::Ctor: param={}, text_buffer={}",
|
||||||
|
static_cast<const void*>(param),
|
||||||
|
static_cast<void*>(param ? param->input_text_buffer : nullptr));
|
||||||
if (!param) {
|
if (!param) {
|
||||||
|
LOG_ERROR(Lib_ImeDialog, " param==nullptr, returning without init");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
user_id = param->user_id;
|
user_id = param->user_id;
|
||||||
is_multi_line = True(param->option & OrbisImeDialogOption::Multiline);
|
is_multi_line = True(param->option & OrbisImeOption::MULTILINE);
|
||||||
is_numeric = param->type == OrbisImeType::Number;
|
is_numeric = param->type == OrbisImeType::Number;
|
||||||
type = param->type;
|
type = param->type;
|
||||||
enter_label = param->enter_label;
|
enter_label = param->enter_label;
|
||||||
|
@ -220,6 +224,7 @@ void ImeDialogUi::Free() {
|
||||||
|
|
||||||
void ImeDialogUi::Draw() {
|
void ImeDialogUi::Draw() {
|
||||||
std::unique_lock lock{draw_mutex};
|
std::unique_lock lock{draw_mutex};
|
||||||
|
LOG_INFO(Lib_ImeDialog, ">> ImeDialogUi::Draw: first_render=%d", first_render);
|
||||||
|
|
||||||
if (!state) {
|
if (!state) {
|
||||||
return;
|
return;
|
||||||
|
@ -259,9 +264,13 @@ void ImeDialogUi::Draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->is_multi_line) {
|
if (state->is_multi_line) {
|
||||||
|
LOG_INFO(Lib_ImeDialog, " Drawing multi-line widget…");
|
||||||
DrawMultiLineInputText();
|
DrawMultiLineInputText();
|
||||||
|
LOG_INFO(Lib_ImeDialog, " Done DrawMultiLineInputText");
|
||||||
} else {
|
} else {
|
||||||
|
LOG_INFO(Lib_ImeDialog, " Drawing input text widget…");
|
||||||
DrawInputText();
|
DrawInputText();
|
||||||
|
LOG_INFO(Lib_ImeDialog, " Done DrawInputText");
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCursorPosY(GetCursorPosY() + 10.0f);
|
SetCursorPosY(GetCursorPosY() + 10.0f);
|
||||||
|
@ -306,6 +315,7 @@ void ImeDialogUi::Draw() {
|
||||||
End();
|
End();
|
||||||
|
|
||||||
first_render = false;
|
first_render = false;
|
||||||
|
LOG_INFO(Lib_ImeDialog, "<< ImeDialogUi::Draw complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImeDialogUi::DrawInputText() {
|
void ImeDialogUi::DrawInputText() {
|
||||||
|
@ -316,7 +326,7 @@ void ImeDialogUi::DrawInputText() {
|
||||||
}
|
}
|
||||||
const char* placeholder = state->placeholder.empty() ? nullptr : state->placeholder.data();
|
const char* placeholder = state->placeholder.empty() ? nullptr : state->placeholder.data();
|
||||||
if (InputTextEx("##ImeDialogInput", placeholder, state->current_text.begin(),
|
if (InputTextEx("##ImeDialogInput", placeholder, state->current_text.begin(),
|
||||||
state->max_text_length, input_size, ImGuiInputTextFlags_CallbackCharFilter,
|
state->max_text_length + 1, input_size, ImGuiInputTextFlags_CallbackCharFilter,
|
||||||
InputTextCallback, this)) {
|
InputTextCallback, this)) {
|
||||||
state->input_changed = true;
|
state->input_changed = true;
|
||||||
}
|
}
|
||||||
|
@ -332,7 +342,7 @@ void ImeDialogUi::DrawMultiLineInputText() {
|
||||||
}
|
}
|
||||||
const char* placeholder = state->placeholder.empty() ? nullptr : state->placeholder.data();
|
const char* placeholder = state->placeholder.empty() ? nullptr : state->placeholder.data();
|
||||||
if (InputTextEx("##ImeDialogInput", placeholder, state->current_text.begin(),
|
if (InputTextEx("##ImeDialogInput", placeholder, state->current_text.begin(),
|
||||||
state->max_text_length, input_size, flags, InputTextCallback, this)) {
|
state->max_text_length + 1, input_size, flags, InputTextCallback, this)) {
|
||||||
state->input_changed = true;
|
state->input_changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -341,13 +351,19 @@ int ImeDialogUi::InputTextCallback(ImGuiInputTextCallbackData* data) {
|
||||||
ImeDialogUi* ui = static_cast<ImeDialogUi*>(data->UserData);
|
ImeDialogUi* ui = static_cast<ImeDialogUi*>(data->UserData);
|
||||||
ASSERT(ui);
|
ASSERT(ui);
|
||||||
|
|
||||||
|
LOG_DEBUG(Lib_ImeDialog, ">> InputTextCallback: EventFlag={}, EventChar={}", data->EventFlag,
|
||||||
|
data->EventChar);
|
||||||
|
|
||||||
// Should we filter punctuation?
|
// Should we filter punctuation?
|
||||||
if (ui->state->is_numeric && (data->EventChar < '0' || data->EventChar > '9') &&
|
if (ui->state->is_numeric && (data->EventChar < '0' || data->EventChar > '9') &&
|
||||||
data->EventChar != '\b' && data->EventChar != ',' && data->EventChar != '.') {
|
data->EventChar != '\b' && data->EventChar != ',' && data->EventChar != '.') {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "InputTextCallback: rejecting non-digit char '{}'",
|
||||||
|
static_cast<char>(data->EventChar));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ui->state->keyboard_filter) {
|
if (!ui->state->keyboard_filter) {
|
||||||
|
LOG_DEBUG(Lib_ImeDialog, "InputTextCallback: no keyboard_filter, accepting char");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,16 +383,20 @@ int ImeDialogUi::InputTextCallback(ImGuiInputTextCallbackData* data) {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!ui->state->ConvertUTF8ToOrbis(event_char, 4, &src_keycode.character, 1)) {
|
if (!ui->state->ConvertUTF8ToOrbis(event_char, 4, &src_keycode.character, 1)) {
|
||||||
LOG_ERROR(Lib_ImeDialog, "Failed to convert orbis char to utf8");
|
LOG_ERROR(Lib_ImeDialog, "InputTextCallback: ConvertUTF8ToOrbis failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_ImeDialog, "InputTextCallback: converted to Orbis char={:#X}",
|
||||||
|
static_cast<uint16_t>(src_keycode.character));
|
||||||
src_keycode.keycode = src_keycode.character; // TODO set this to the correct value
|
src_keycode.keycode = src_keycode.character; // TODO set this to the correct value
|
||||||
|
|
||||||
u16 out_keycode;
|
u16 out_keycode;
|
||||||
u32 out_status;
|
u32 out_status;
|
||||||
|
|
||||||
ui->state->CallKeyboardFilter(&src_keycode, &out_keycode, &out_status);
|
bool keep = ui->state->CallKeyboardFilter(&src_keycode, &out_keycode, &out_status);
|
||||||
|
LOG_DEBUG(Lib_ImeDialog,
|
||||||
|
"InputTextCallback: CallKeyboardFilter returned %s (keycode=0x%X, status=0x%X)",
|
||||||
|
keep ? "true" : "false", out_keycode, out_status);
|
||||||
// TODO. set the keycode
|
// TODO. set the keycode
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -199,7 +199,7 @@ int ImeUi::InputTextCallback(ImGuiInputTextCallbackData* data) {
|
||||||
eventParam.caret_index = data->CursorPos;
|
eventParam.caret_index = data->CursorPos;
|
||||||
eventParam.area_num = 1;
|
eventParam.area_num = 1;
|
||||||
|
|
||||||
eventParam.text_area[0].mode = 1; // Edit mode
|
eventParam.text_area[0].mode = OrbisImeTextAreaMode::Edit;
|
||||||
eventParam.text_area[0].index = data->CursorPos;
|
eventParam.text_area[0].index = data->CursorPos;
|
||||||
eventParam.text_area[0].length = data->BufTextLen;
|
eventParam.text_area[0].length = data->BufTextLen;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue