mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 10:04:39 +00:00
Ime lib fixes (#3244)
* IME fixes - 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 * Ime lib fixes - Updated functions to consistently use the Error enum type for return values. - Added detailed logging to aid future IME/OSK development and debugging. - Now use OrbisUserServiceUserId (s32) and OrbisImeKeycodeState in relevant functions and structs. - Introduced a generic template method to generate full bitmasks for all Orbis flag-style enums, simplifying validation and mask creation. - Implemented additional parameter validations in sceImeOpen. - Added missing enums: OrbisDisableDevice, OrbisImeInputMethodState, OrbisImeInitExtKeyboardMode, OrbisImeKeycodeState, and other USB keyboard-related enums. - Fixed incorrect usage of format specifiers in calls to logging macros (LOG_*). * Data Type Fixes - Replaced the use of the type alias OrbisUserServiceUserId = s32 with Libraries::UserService::OrbisUserServiceUserId directly. * Fixed IDE warnings - generate_full_mask now returns const instead of constexpr. - Added argument list to std::unique_lock<std::mutex> construction for clarity. * Clang fixes * Removed unneccessary comment --------- Co-authored-by: w1naenator <valdis.bogdans@hotmail.com>
This commit is contained in:
parent
b56039b15a
commit
af67473de3
@ -65,7 +65,7 @@ public:
|
|||||||
return Error::OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_lock lock{g_ime_state.queue_mutex};
|
std::unique_lock<std::mutex> lock{g_ime_state.queue_mutex};
|
||||||
|
|
||||||
while (!g_ime_state.event_queue.empty()) {
|
while (!g_ime_state.event_queue.empty()) {
|
||||||
OrbisImeEvent event = g_ime_state.event_queue.front();
|
OrbisImeEvent event = g_ime_state.event_queue.front();
|
||||||
@ -144,17 +144,17 @@ int PS4_SYSV_ABI sceImeCheckUpdateTextInfo() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceImeClose() {
|
Error PS4_SYSV_ABI sceImeClose() {
|
||||||
LOG_INFO(Lib_Ime, "(STUBBED) called");
|
LOG_INFO(Lib_Ime, "called");
|
||||||
|
|
||||||
if (!g_ime_handler) {
|
if (!g_ime_handler) {
|
||||||
return ORBIS_IME_ERROR_NOT_OPENED;
|
return Error::NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ime_handler.release();
|
g_ime_handler.release();
|
||||||
g_ime_ui = ImeUi();
|
g_ime_ui = ImeUi();
|
||||||
g_ime_state = ImeState();
|
g_ime_state = ImeState();
|
||||||
return ORBIS_OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeConfigGet() {
|
int PS4_SYSV_ABI sceImeConfigGet() {
|
||||||
@ -223,32 +223,68 @@ int PS4_SYSV_ABI sceImeGetPanelPositionAndForm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error 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, "sceImeGetPanelSize called");
|
||||||
|
|
||||||
if (!width || !height) {
|
if (!param) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeGetPanelSize: param is NULL");
|
||||||
return Error::INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
if (!width) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeGetPanelSize: width pointer is NULL");
|
||||||
|
return Error::INVALID_ADDRESS;
|
||||||
|
}
|
||||||
|
if (!height) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeGetPanelSize: height pointer is NULL");
|
||||||
|
return Error::INVALID_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static_cast<u32>(param->option) & ~0x7BFF) { // Basic check for invalid options
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeGetPanelSize: Invalid option 0x{:X}",
|
||||||
|
static_cast<u32>(param->option));
|
||||||
|
return Error::INVALID_OPTION;
|
||||||
|
}
|
||||||
|
|
||||||
switch (param->type) {
|
switch (param->type) {
|
||||||
case OrbisImeType::Default:
|
case OrbisImeType::Default:
|
||||||
|
*width = 500; // dummy value
|
||||||
|
*height = 100; // dummy value
|
||||||
|
LOG_INFO(Lib_Ime, "sceImeGetPanelSize: IME type Default ({})",
|
||||||
|
static_cast<u32>(param->type));
|
||||||
|
break;
|
||||||
case OrbisImeType::BasicLatin:
|
case OrbisImeType::BasicLatin:
|
||||||
|
*width = 500; // dummy value
|
||||||
|
*height = 100; // dummy value
|
||||||
|
LOG_INFO(Lib_Ime, "sceImeGetPanelSize: IME type BasicLatin ({})",
|
||||||
|
static_cast<u32>(param->type));
|
||||||
|
break;
|
||||||
case OrbisImeType::Url:
|
case OrbisImeType::Url:
|
||||||
|
*width = 500; // dummy value
|
||||||
|
*height = 100; // dummy value
|
||||||
|
LOG_INFO(Lib_Ime, "sceImeGetPanelSize: IME type Url ({})", static_cast<u32>(param->type));
|
||||||
|
break;
|
||||||
case OrbisImeType::Mail:
|
case OrbisImeType::Mail:
|
||||||
// We set our custom sizes, commented sizes are the original ones
|
// We set our custom sizes, commented sizes are the original ones
|
||||||
*width = 500; // 793
|
*width = 500; // 793
|
||||||
*height = 100; // 408
|
*height = 100; // 408
|
||||||
|
LOG_INFO(Lib_Ime, "sceImeGetPanelSize: IME type Mail ({})", static_cast<u32>(param->type));
|
||||||
break;
|
break;
|
||||||
case OrbisImeType::Number:
|
case OrbisImeType::Number:
|
||||||
*width = 370;
|
*width = 370;
|
||||||
*height = 402;
|
*height = 402;
|
||||||
|
LOG_INFO(Lib_Ime, "sceImeGetPanelSize: IME type Number ({})",
|
||||||
|
static_cast<u32>(param->type));
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeGetPanelSize: Invalid IME type ({})",
|
||||||
|
static_cast<u32>(param->type));
|
||||||
|
return Error::INVALID_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Error::OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error PS4_SYSV_ABI sceImeKeyboardClose(s32 userId) {
|
Error PS4_SYSV_ABI sceImeKeyboardClose(Libraries::UserService::OrbisUserServiceUserId userId) {
|
||||||
LOG_INFO(Lib_Ime, "(STUBBED) called");
|
LOG_INFO(Lib_Ime, "called");
|
||||||
|
|
||||||
if (!g_keyboard_handler) {
|
if (!g_keyboard_handler) {
|
||||||
return Error::NOT_OPENED;
|
return Error::NOT_OPENED;
|
||||||
@ -268,9 +304,12 @@ int PS4_SYSV_ABI sceImeKeyboardGetResourceId() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error PS4_SYSV_ABI sceImeKeyboardOpen(s32 userId, const OrbisImeKeyboardParam* param) {
|
Error PS4_SYSV_ABI sceImeKeyboardOpen(Libraries::UserService::OrbisUserServiceUserId userId,
|
||||||
|
const OrbisImeKeyboardParam* param) {
|
||||||
LOG_INFO(Lib_Ime, "called");
|
LOG_INFO(Lib_Ime, "called");
|
||||||
|
|
||||||
|
LOG_INFO(Lib_Ime, "kValidImeDialogExtOptionMask=0x{:X}", kValidImeDialogExtOptionMask);
|
||||||
|
|
||||||
if (!param) {
|
if (!param) {
|
||||||
return Error::INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
@ -308,13 +347,169 @@ Error PS4_SYSV_ABI sceImeOpen(const OrbisImeParam* param, const OrbisImeParamExt
|
|||||||
LOG_INFO(Lib_Ime, "called");
|
LOG_INFO(Lib_Ime, "called");
|
||||||
|
|
||||||
if (!param) {
|
if (!param) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: param is null");
|
||||||
return Error::INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
|
} else {
|
||||||
|
// LOG_DEBUG values for debugging purposes
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: user_id={}", param->user_id);
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: type={}", static_cast<u32>(param->type));
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: supported_languages={:064b}",
|
||||||
|
static_cast<u64>(param->supported_languages));
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: enter_label={}", static_cast<u32>(param->enter_label));
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: input_method={}", static_cast<u32>(param->input_method));
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: filter={:p}", reinterpret_cast<void*>(param->filter));
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: option={:032b}", static_cast<u32>(param->option));
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: maxTextLength={}", param->maxTextLength);
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: inputTextBuffer={:p}",
|
||||||
|
static_cast<const void*>(param->inputTextBuffer));
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: posx={}", param->posx);
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: posy={}", param->posy);
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: horizontal_alignment={}",
|
||||||
|
static_cast<u32>(param->horizontal_alignment));
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: vertical_alignment={}",
|
||||||
|
static_cast<u32>(param->vertical_alignment));
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: work={:p}", param->work);
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: arg={:p}", param->arg);
|
||||||
|
LOG_DEBUG(Lib_Ime, "param: handler={:p}", reinterpret_cast<void*>(param->handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!extended) {
|
||||||
|
LOG_INFO(Lib_Ime, "sceImeOpen: extended is null");
|
||||||
|
} else {
|
||||||
|
// LOG_DEBUG values for debugging purposes
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: option={:032b}", static_cast<u32>(extended->option));
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: color_base={{{},{},{},{}}}", extended->color_base.r,
|
||||||
|
extended->color_base.g, extended->color_base.b, extended->color_base.a);
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: color_line={{{},{},{},{}}}", extended->color_line.r,
|
||||||
|
extended->color_line.g, extended->color_line.b, extended->color_line.a);
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: color_text_field={{{},{},{},{}}}",
|
||||||
|
extended->color_text_field.r, extended->color_text_field.g,
|
||||||
|
extended->color_text_field.b, extended->color_text_field.a);
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: color_preedit={{{},{},{},{}}}", extended->color_preedit.r,
|
||||||
|
extended->color_preedit.g, extended->color_preedit.b, extended->color_preedit.a);
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: color_button_default={{{},{},{},{}}}",
|
||||||
|
extended->color_button_default.r, extended->color_button_default.g,
|
||||||
|
extended->color_button_default.b, extended->color_button_default.a);
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: color_button_function={{{},{},{},{}}}",
|
||||||
|
extended->color_button_function.r, extended->color_button_function.g,
|
||||||
|
extended->color_button_function.b, extended->color_button_function.a);
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: color_button_symbol={{{},{},{},{}}}",
|
||||||
|
extended->color_button_symbol.r, extended->color_button_symbol.g,
|
||||||
|
extended->color_button_symbol.b, extended->color_button_symbol.a);
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: color_text={{{},{},{},{}}}", extended->color_text.r,
|
||||||
|
extended->color_text.g, extended->color_text.b, extended->color_text.a);
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: color_special={{{},{},{},{}}}", extended->color_special.r,
|
||||||
|
extended->color_special.g, extended->color_special.b, extended->color_special.a);
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: priority={}", static_cast<u32>(extended->priority));
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: additional_dictionary_path={:p}",
|
||||||
|
static_cast<const void*>(extended->additional_dictionary_path));
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: ext_keyboard_filter={:p}",
|
||||||
|
reinterpret_cast<void*>(extended->ext_keyboard_filter));
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: disable_device={:032b}",
|
||||||
|
static_cast<u32>(extended->disable_device));
|
||||||
|
LOG_DEBUG(Lib_Ime, "extended: ext_keyboard_mode={}", extended->ext_keyboard_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->user_id < 1 || param->user_id > 4) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: Invalid user_id ({})", static_cast<u32>(param->user_id));
|
||||||
|
return Error::INVALID_USER_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!magic_enum::enum_contains(param->type)) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: Invalid type ({})", static_cast<u32>(param->type));
|
||||||
|
return Error::INVALID_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static_cast<u64>(param->supported_languages) & ~kValidOrbisImeLanguageMask) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: supported_languages has invalid bits (0x{:016X})",
|
||||||
|
static_cast<u64>(param->supported_languages));
|
||||||
|
return Error::INVALID_SUPPORTED_LANGUAGES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!magic_enum::enum_contains(param->enter_label)) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: Invalid enter_label ({})",
|
||||||
|
static_cast<u32>(param->enter_label));
|
||||||
|
return Error::INVALID_ENTER_LABEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!magic_enum::enum_contains(param->input_method)) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: Invalid input_method ({})",
|
||||||
|
static_cast<u32>(param->input_method));
|
||||||
|
return Error::INVALID_INPUT_METHOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static_cast<u32>(param->option) & ~kValidImeOptionMask) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: option has invalid bits set (0x{:X}), mask=(0x{:X})",
|
||||||
|
static_cast<u32>(param->option), kValidImeOptionMask);
|
||||||
|
return Error::INVALID_OPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->maxTextLength == 0 || param->maxTextLength > ORBIS_IME_DIALOG_MAX_TEXT_LENGTH) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: maxTextLength invalid ({})", param->maxTextLength);
|
||||||
|
return Error::INVALID_MAX_TEXT_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!param->inputTextBuffer) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: inputTextBuffer is NULL");
|
||||||
|
return Error::INVALID_INPUT_TEXT_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool useHighRes = True(param->option & OrbisImeOption::USE_OVER_2K_COORDINATES);
|
||||||
|
const float maxWidth = useHighRes ? 3840.0f : 1920.0f;
|
||||||
|
const float maxHeight = useHighRes ? 2160.0f : 1080.0f;
|
||||||
|
|
||||||
|
if (param->posx < 0.0f || param->posx >= maxWidth) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: posx out of range (%.2f), max allowed %.0f", param->posx,
|
||||||
|
maxWidth);
|
||||||
|
return Error::INVALID_POSX;
|
||||||
|
}
|
||||||
|
if (param->posy < 0.0f || param->posy >= maxHeight) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: posy out of range (%.2f), max allowed %.0f", param->posy,
|
||||||
|
maxHeight);
|
||||||
|
return Error::INVALID_POSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!magic_enum::enum_contains(param->horizontal_alignment)) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: Invalid horizontal_alignment ({})",
|
||||||
|
static_cast<u32>(param->horizontal_alignment));
|
||||||
|
return Error::INVALID_HORIZONTALIGNMENT;
|
||||||
|
}
|
||||||
|
if (!magic_enum::enum_contains(param->vertical_alignment)) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: Invalid vertical_alignment ({})",
|
||||||
|
static_cast<u32>(param->vertical_alignment));
|
||||||
|
return Error::INVALID_VERTICALALIGNMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extended) {
|
||||||
|
u32 ext_option_value = static_cast<u32>(extended->option);
|
||||||
|
if (ext_option_value & ~kValidImeExtOptionMask) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: extended->option has invalid bits set (0x{:X})",
|
||||||
|
ext_option_value);
|
||||||
|
return Error::INVALID_EXTENDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!param->work) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: work buffer is NULL");
|
||||||
|
return Error::INVALID_WORK;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < sizeof(param->reserved); ++i) {
|
||||||
|
if (param->reserved[i] != 0) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: reserved field must be zeroed");
|
||||||
|
return Error::INVALID_RESERVED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todo: validate arg and handler
|
||||||
|
|
||||||
if (g_ime_handler) {
|
if (g_ime_handler) {
|
||||||
|
LOG_ERROR(Lib_Ime, "sceImeOpen: Error BUSY");
|
||||||
return Error::BUSY;
|
return Error::BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ime_handler = std::make_unique<ImeHandler>(param);
|
g_ime_handler = std::make_unique<ImeHandler>(param);
|
||||||
|
LOG_INFO(Lib_Ime, "sceImeOpen: OK");
|
||||||
return Error::OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,7 +519,7 @@ int PS4_SYSV_ABI sceImeOpenInternal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PS4_SYSV_ABI sceImeParamInit(OrbisImeParam* param) {
|
void PS4_SYSV_ABI sceImeParamInit(OrbisImeParam* param) {
|
||||||
LOG_INFO(Lib_Ime, "called");
|
LOG_INFO(Lib_Ime, "sceImeParamInit called");
|
||||||
|
|
||||||
if (!param) {
|
if (!param) {
|
||||||
return;
|
return;
|
||||||
|
@ -18,7 +18,7 @@ int PS4_SYSV_ABI InitializeImeModule();
|
|||||||
int PS4_SYSV_ABI sceImeCheckFilterText();
|
int PS4_SYSV_ABI sceImeCheckFilterText();
|
||||||
int PS4_SYSV_ABI sceImeCheckRemoteEventParam();
|
int PS4_SYSV_ABI sceImeCheckRemoteEventParam();
|
||||||
int PS4_SYSV_ABI sceImeCheckUpdateTextInfo();
|
int PS4_SYSV_ABI sceImeCheckUpdateTextInfo();
|
||||||
int PS4_SYSV_ABI sceImeClose();
|
Error PS4_SYSV_ABI sceImeClose();
|
||||||
int PS4_SYSV_ABI sceImeConfigGet();
|
int PS4_SYSV_ABI sceImeConfigGet();
|
||||||
int PS4_SYSV_ABI sceImeConfigSet();
|
int PS4_SYSV_ABI sceImeConfigSet();
|
||||||
int PS4_SYSV_ABI sceImeConfirmCandidate();
|
int PS4_SYSV_ABI sceImeConfirmCandidate();
|
||||||
@ -33,10 +33,11 @@ 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();
|
||||||
Error PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32* height);
|
Error PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32* height);
|
||||||
Error PS4_SYSV_ABI sceImeKeyboardClose(s32 userId);
|
Error PS4_SYSV_ABI sceImeKeyboardClose(Libraries::UserService::OrbisUserServiceUserId userId);
|
||||||
int PS4_SYSV_ABI sceImeKeyboardGetInfo();
|
int PS4_SYSV_ABI sceImeKeyboardGetInfo();
|
||||||
int PS4_SYSV_ABI sceImeKeyboardGetResourceId();
|
int PS4_SYSV_ABI sceImeKeyboardGetResourceId();
|
||||||
Error PS4_SYSV_ABI sceImeKeyboardOpen(s32 userId, const OrbisImeKeyboardParam* param);
|
Error PS4_SYSV_ABI sceImeKeyboardOpen(Libraries::UserService::OrbisUserServiceUserId 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();
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <core/libraries/system/userservice.h>
|
||||||
|
#include <magic_enum/magic_enum.hpp>
|
||||||
#include "common/enum.h"
|
#include "common/enum.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "core/libraries/rtc/rtc.h"
|
#include "core/libraries/rtc/rtc.h"
|
||||||
@ -10,8 +12,28 @@
|
|||||||
constexpr u32 ORBIS_IME_MAX_TEXT_LENGTH = 2048;
|
constexpr u32 ORBIS_IME_MAX_TEXT_LENGTH = 2048;
|
||||||
constexpr u32 ORBIS_IME_DIALOG_MAX_TEXT_LENGTH = 2048;
|
constexpr u32 ORBIS_IME_DIALOG_MAX_TEXT_LENGTH = 2048;
|
||||||
|
|
||||||
|
template <typename E>
|
||||||
|
const std::underlying_type_t<E> generate_full_mask() {
|
||||||
|
static_assert(std::is_enum_v<E>, "E must be an enum type.");
|
||||||
|
static_assert(magic_enum::customize::enum_range<E>::is_flags,
|
||||||
|
"E must be marked as is_flags = true.");
|
||||||
|
|
||||||
|
using U = std::underlying_type_t<E>;
|
||||||
|
const auto values = magic_enum::enum_values<E>();
|
||||||
|
U mask = 0;
|
||||||
|
|
||||||
|
// Use index-based loop for better constexpr compatibility
|
||||||
|
for (std::size_t i = 0; i < values.size(); ++i) {
|
||||||
|
mask |= static_cast<U>(values[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
enum class Error : u32 {
|
enum class Error : u32 {
|
||||||
OK = 0x0,
|
OK = 0x0,
|
||||||
|
|
||||||
|
// ImeDialog library
|
||||||
BUSY = 0x80bc0001,
|
BUSY = 0x80bc0001,
|
||||||
NOT_OPENED = 0x80bc0002,
|
NOT_OPENED = 0x80bc0002,
|
||||||
NO_MEMORY = 0x80bc0003,
|
NO_MEMORY = 0x80bc0003,
|
||||||
@ -46,6 +68,8 @@ enum class Error : u32 {
|
|||||||
INVALID_RESERVED = 0x80bc0032,
|
INVALID_RESERVED = 0x80bc0032,
|
||||||
INVALID_TIMING = 0x80bc0033,
|
INVALID_TIMING = 0x80bc0033,
|
||||||
INTERNAL = 0x80bc00ff,
|
INTERNAL = 0x80bc00ff,
|
||||||
|
|
||||||
|
// Ime library
|
||||||
DIALOG_INVALID_TITLE = 0x80bc0101,
|
DIALOG_INVALID_TITLE = 0x80bc0101,
|
||||||
DIALOG_NOT_RUNNING = 0x80bc0105,
|
DIALOG_NOT_RUNNING = 0x80bc0105,
|
||||||
DIALOG_NOT_FINISHED = 0x80bc0106,
|
DIALOG_NOT_FINISHED = 0x80bc0106,
|
||||||
@ -67,9 +91,44 @@ enum class OrbisImeOption : u32 {
|
|||||||
DISABLE_POSITION_ADJUSTMENT = 2048,
|
DISABLE_POSITION_ADJUSTMENT = 2048,
|
||||||
EXPANDED_PREEDIT_BUFFER = 4096,
|
EXPANDED_PREEDIT_BUFFER = 4096,
|
||||||
USE_JAPANESE_EISUU_KEY_AS_CAPSLOCK = 8192,
|
USE_JAPANESE_EISUU_KEY_AS_CAPSLOCK = 8192,
|
||||||
USE_2K_COORDINATES = 16384,
|
USE_OVER_2K_COORDINATES = 16384,
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeOption);
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeOption);
|
||||||
|
template <>
|
||||||
|
struct magic_enum::customize::enum_range<OrbisImeOption> {
|
||||||
|
static constexpr bool is_flags = true;
|
||||||
|
};
|
||||||
|
const u32 kValidImeOptionMask = generate_full_mask<OrbisImeOption>();
|
||||||
|
|
||||||
|
enum class OrbisImeExtOption : u32 {
|
||||||
|
DEFAULT = 0x00000000,
|
||||||
|
SET_PRIORITY = 0x00000002,
|
||||||
|
PRIORITY_FULL_WIDTH = 0x00000008,
|
||||||
|
PRIORITY_FIXED_PANEL = 0x00000010,
|
||||||
|
DISABLE_POINTER = 0x00000040,
|
||||||
|
ENABLE_ADDITIONAL_DICTIONARY = 0x00000080,
|
||||||
|
DISABLE_STARTUP_SE = 0x00000100,
|
||||||
|
DISABLE_LIST_FOR_EXT_KEYBOARD = 0x00000200,
|
||||||
|
HIDE_KEYPANEL_IF_EXT_KEYBOARD = 0x00000400,
|
||||||
|
INIT_EXT_KEYBOARD_MODE = 0x00000800,
|
||||||
|
|
||||||
|
ENABLE_ACCESSIBILITY = 0x00001000, // ImeDialog unly
|
||||||
|
ADDITIONAL_DICTIONARY_PRIORITY_MODE = 0x00004000, // ImeDialog only
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeExtOption);
|
||||||
|
|
||||||
|
constexpr u32 kValidImeExtOptionMask = static_cast<u32>(
|
||||||
|
OrbisImeExtOption::SET_PRIORITY | OrbisImeExtOption::PRIORITY_FULL_WIDTH |
|
||||||
|
OrbisImeExtOption::PRIORITY_FIXED_PANEL | OrbisImeExtOption::DISABLE_POINTER |
|
||||||
|
OrbisImeExtOption::ENABLE_ADDITIONAL_DICTIONARY | OrbisImeExtOption::DISABLE_STARTUP_SE |
|
||||||
|
OrbisImeExtOption::DISABLE_LIST_FOR_EXT_KEYBOARD |
|
||||||
|
OrbisImeExtOption::HIDE_KEYPANEL_IF_EXT_KEYBOARD | OrbisImeExtOption::INIT_EXT_KEYBOARD_MODE);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct magic_enum::customize::enum_range<OrbisImeExtOption> {
|
||||||
|
static constexpr bool is_flags = true;
|
||||||
|
};
|
||||||
|
const u32 kValidImeDialogExtOptionMask = generate_full_mask<OrbisImeExtOption>();
|
||||||
|
|
||||||
enum class OrbisImeLanguage : u64 {
|
enum class OrbisImeLanguage : u64 {
|
||||||
DANISH = 0x0000000000000001,
|
DANISH = 0x0000000000000001,
|
||||||
@ -105,6 +164,112 @@ enum class OrbisImeLanguage : u64 {
|
|||||||
};
|
};
|
||||||
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeLanguage);
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeLanguage);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct magic_enum::customize::enum_range<OrbisImeLanguage> {
|
||||||
|
static constexpr bool is_flags = true;
|
||||||
|
};
|
||||||
|
const u64 kValidOrbisImeLanguageMask = generate_full_mask<OrbisImeLanguage>();
|
||||||
|
|
||||||
|
enum class OrbisImeDisableDevice : u32 {
|
||||||
|
DEFAULT = 0x00000000,
|
||||||
|
CONTROLLER = 0x00000001,
|
||||||
|
EXT_KEYBOARD = 0x00000002,
|
||||||
|
REMOTE_OSK = 0x00000004,
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeDisableDevice);
|
||||||
|
template <>
|
||||||
|
struct magic_enum::customize::enum_range<OrbisImeDisableDevice> {
|
||||||
|
static constexpr bool is_flags = true;
|
||||||
|
};
|
||||||
|
const u32 kValidOrbisImeDisableDeviceMask = generate_full_mask<OrbisImeDisableDevice>();
|
||||||
|
|
||||||
|
enum class OrbisImeInputMethodState : u32 {
|
||||||
|
PREEDIT = 0x01000000,
|
||||||
|
SELECTED = 0x02000000,
|
||||||
|
NATIVE = 0x04000000,
|
||||||
|
NATIVE2 = 0x08000000,
|
||||||
|
FULL_WIDTH = 0x10000000,
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeInputMethodState);
|
||||||
|
template <>
|
||||||
|
struct magic_enum::customize::enum_range<OrbisImeInputMethodState> {
|
||||||
|
static constexpr bool is_flags = true;
|
||||||
|
};
|
||||||
|
const u32 kValidOrbisImeInputMethodStateMask = generate_full_mask<OrbisImeInputMethodState>();
|
||||||
|
|
||||||
|
enum class OrbisImeInitExtKeyboardMode : u32 {
|
||||||
|
ISABLE_ARABIC_INDIC_NUMERALS = 0x00000001,
|
||||||
|
ENABLE_FORMAT_CHARACTERS = 0x00000002,
|
||||||
|
INPUT_METHOD_STATE_NATIVE = 0x04000000,
|
||||||
|
INPUT_METHOD_STATE_NATIVE2 = 0x08000000,
|
||||||
|
INPUT_METHOD_STATE_FULL_WIDTH = 0x10000000,
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeInitExtKeyboardMode);
|
||||||
|
template <>
|
||||||
|
struct magic_enum::customize::enum_range<OrbisImeInitExtKeyboardMode> {
|
||||||
|
static constexpr bool is_flags = true;
|
||||||
|
};
|
||||||
|
const u32 kValidOrbisImeInitExtKeyboardModeMask = generate_full_mask<OrbisImeInitExtKeyboardMode>();
|
||||||
|
|
||||||
|
enum class OrbisImeKeycodeState : u32 {
|
||||||
|
KEYCODE_VALID = 0x00000001,
|
||||||
|
CHARACTER_VALID = 0x00000002,
|
||||||
|
WITH_IME = 0x00000004,
|
||||||
|
FROM_OSK = 0x00000008,
|
||||||
|
FROM_OSK_SHORTCUT = 0x00000010,
|
||||||
|
FROM_IME_OPERATION = 0x00000020,
|
||||||
|
REPLACE_CHARACTER = 0x00000040,
|
||||||
|
CONTINUOUS_EVENT = 0x00000080,
|
||||||
|
MODIFIER_L_CTRL = 0x00000100,
|
||||||
|
MODIFIER_L_SHIFT = 0x00000200,
|
||||||
|
MODIFIER_L_ALT = 0x00000400,
|
||||||
|
MODIFIER_L_GUI = 0x00000800,
|
||||||
|
MODIFIER_R_CTRL = 0x00001000,
|
||||||
|
MODIFIER_R_SHIFT = 0x00002000,
|
||||||
|
MODIFIER_R_ALT = 0x00004000,
|
||||||
|
MODIFIER_R_GUI = 0x00008000,
|
||||||
|
LED_NUM_LOCK = 0x00010000,
|
||||||
|
LED_CAPS_LOCK = 0x00020000,
|
||||||
|
LED_SCROLL_LOCK = 0x00040000,
|
||||||
|
RESERVED1 = 0x00080000,
|
||||||
|
RESERVED2 = 0x00100000,
|
||||||
|
FROM_IME_INPUT = 0x00200000,
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeKeycodeState);
|
||||||
|
template <>
|
||||||
|
struct magic_enum::customize::enum_range<OrbisImeKeycodeState> {
|
||||||
|
static constexpr bool is_flags = true;
|
||||||
|
};
|
||||||
|
const u32 kValidOrbisImeKeycodeStateMask = generate_full_mask<OrbisImeKeycodeState>();
|
||||||
|
|
||||||
|
enum class OrbisImeKeyboardOption : u32 {
|
||||||
|
Default = 0,
|
||||||
|
Repeat = 1,
|
||||||
|
RepeatEachKey = 2,
|
||||||
|
AddOsk = 4,
|
||||||
|
EffectiveWithIme = 8,
|
||||||
|
DisableResume = 16,
|
||||||
|
DisableCapslockWithoutShift = 32,
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeKeyboardOption)
|
||||||
|
template <>
|
||||||
|
struct magic_enum::customize::enum_range<OrbisImeKeyboardOption> {
|
||||||
|
static constexpr bool is_flags = true;
|
||||||
|
};
|
||||||
|
const u32 kValidOrbisImeKeyboardOptionMask = generate_full_mask<OrbisImeKeyboardOption>();
|
||||||
|
|
||||||
|
enum class OrbisImeKeyboardMode : u32 {
|
||||||
|
Auto = 0,
|
||||||
|
Manual = 1,
|
||||||
|
Alphabet = 0,
|
||||||
|
Native = 2,
|
||||||
|
Part = 4,
|
||||||
|
Katakana = 8,
|
||||||
|
Hkana = 16,
|
||||||
|
ArabicIndicNumerals = 32,
|
||||||
|
DisableFormatCharacters = 64,
|
||||||
|
};
|
||||||
|
|
||||||
enum class OrbisImeType : u32 {
|
enum class OrbisImeType : u32 {
|
||||||
Default = 0,
|
Default = 0,
|
||||||
BasicLatin = 1,
|
BasicLatin = 1,
|
||||||
@ -260,13 +425,13 @@ struct OrbisImeKeycode {
|
|||||||
char16_t character;
|
char16_t character;
|
||||||
u32 status;
|
u32 status;
|
||||||
OrbisImeKeyboardType type;
|
OrbisImeKeyboardType type;
|
||||||
s32 user_id; // Todo: switch to OrbisUserServiceUserId
|
Libraries::UserService::OrbisUserServiceUserId user_id;
|
||||||
u32 resource_id;
|
u32 resource_id;
|
||||||
Libraries::Rtc::OrbisRtcTick timestamp;
|
Libraries::Rtc::OrbisRtcTick timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisImeKeyboardResourceIdArray {
|
struct OrbisImeKeyboardResourceIdArray {
|
||||||
s32 user_id; // Todo: switch to OrbisUserServiceUserId
|
Libraries::UserService::OrbisUserServiceUserId user_id;
|
||||||
u32 resource_id[5];
|
u32 resource_id[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -322,17 +487,6 @@ using OrbisImeTextFilter = PS4_SYSV_ABI int (*)(char16_t* outText, u32* outTextL
|
|||||||
|
|
||||||
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 {
|
struct OrbisImeKeyboardParam {
|
||||||
OrbisImeKeyboardOption option;
|
OrbisImeKeyboardOption option;
|
||||||
s8 reserved1[4];
|
s8 reserved1[4];
|
||||||
@ -342,9 +496,9 @@ struct OrbisImeKeyboardParam {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisImeParam {
|
struct OrbisImeParam {
|
||||||
s32 user_id; // Todo: switch to OrbisUserServiceUserId
|
Libraries::UserService::OrbisUserServiceUserId user_id;
|
||||||
OrbisImeType type;
|
OrbisImeType type;
|
||||||
u64 supported_languages; // OrbisImeLanguage flags
|
OrbisImeLanguage supported_languages;
|
||||||
OrbisImeEnterLabel enter_label;
|
OrbisImeEnterLabel enter_label;
|
||||||
OrbisImeInputMethod input_method;
|
OrbisImeInputMethod input_method;
|
||||||
OrbisImeTextFilter filter;
|
OrbisImeTextFilter filter;
|
||||||
@ -369,9 +523,9 @@ struct OrbisImeCaret {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisImeDialogParam {
|
struct OrbisImeDialogParam {
|
||||||
s32 user_id;
|
Libraries::UserService::OrbisUserServiceUserId user_id;
|
||||||
OrbisImeType type;
|
OrbisImeType type;
|
||||||
u64 supported_languages; // OrbisImeLanguage flags
|
OrbisImeLanguage supported_languages;
|
||||||
OrbisImeEnterLabel enter_label;
|
OrbisImeEnterLabel enter_label;
|
||||||
OrbisImeInputMethod input_method;
|
OrbisImeInputMethod input_method;
|
||||||
OrbisImeTextFilter filter;
|
OrbisImeTextFilter filter;
|
||||||
@ -388,7 +542,7 @@ struct OrbisImeDialogParam {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisImeParamExtended {
|
struct OrbisImeParamExtended {
|
||||||
u32 option; // OrbisImeExtOption flags
|
OrbisImeExtOption option;
|
||||||
OrbisImeColor color_base;
|
OrbisImeColor color_base;
|
||||||
OrbisImeColor color_line;
|
OrbisImeColor color_line;
|
||||||
OrbisImeColor color_text_field;
|
OrbisImeColor color_text_field;
|
||||||
@ -401,7 +555,7 @@ struct OrbisImeParamExtended {
|
|||||||
OrbisImePanelPriority priority;
|
OrbisImePanelPriority priority;
|
||||||
char* additional_dictionary_path;
|
char* additional_dictionary_path;
|
||||||
OrbisImeExtKeyboardFilter ext_keyboard_filter;
|
OrbisImeExtKeyboardFilter ext_keyboard_filter;
|
||||||
u32 disable_device;
|
OrbisImeDisableDevice disable_device;
|
||||||
u32 ext_keyboard_mode;
|
u32 ext_keyboard_mode;
|
||||||
s8 reserved[60];
|
s8 reserved[60];
|
||||||
};
|
};
|
||||||
|
@ -149,20 +149,47 @@ 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={}",
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: entering, param={}, extended={}",
|
||||||
static_cast<void*>(param), static_cast<void*>(extended));
|
static_cast<void*>(param), static_cast<void*>(extended));
|
||||||
if (g_ime_dlg_status != OrbisImeDialogStatus::None) {
|
|
||||||
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: busy (status=%u)", (u32)g_ime_dlg_status);
|
|
||||||
return Error::BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param == nullptr) {
|
if (param == nullptr) {
|
||||||
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: param is null");
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: param is null");
|
||||||
return Error::INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
|
} else {
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.user_id = {}",
|
||||||
|
static_cast<u32>(param->user_id));
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.type = {}", static_cast<u32>(param->type));
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.supported_languages = 0x{:X}",
|
||||||
|
static_cast<u64>(param->supported_languages));
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.enter_label = {}",
|
||||||
|
static_cast<u32>(param->enter_label));
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.input_method = {}",
|
||||||
|
static_cast<u32>(param->input_method));
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.filter = {}", (void*)param->filter);
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.option = 0x{:X}",
|
||||||
|
static_cast<u32>(param->option));
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.max_text_length = {}",
|
||||||
|
param->max_text_length);
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.input_text_buffer = {}",
|
||||||
|
(void*)param->input_text_buffer);
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.posx = {}", param->posx);
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.posy = {}", param->posy);
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.horizontal_alignment = {}",
|
||||||
|
static_cast<u32>(param->horizontal_alignment));
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.vertical_alignment = {}",
|
||||||
|
static_cast<u32>(param->vertical_alignment));
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.placeholder = {}",
|
||||||
|
param->placeholder ? "<non-null>" : "NULL");
|
||||||
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: param.title = {}",
|
||||||
|
param->title ? "<non-null>" : "NULL");
|
||||||
|
}
|
||||||
|
if (g_ime_dlg_status != OrbisImeDialogStatus::None) {
|
||||||
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: busy (status={})", (u32)g_ime_dlg_status);
|
||||||
|
return Error::BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!magic_enum::enum_contains(param->type)) {
|
if (!magic_enum::enum_contains(param->type)) {
|
||||||
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid param->type=%u", (u32)param->type);
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid param->type={}", (u32)param->type);
|
||||||
return Error::INVALID_ADDRESS;
|
return Error::INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,14 +197,16 @@ 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 >= MAX_X_POSITIONS[False(param->option & OrbisImeOption::USE_2K_COORDINATES)]) {
|
param->posx >=
|
||||||
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid posx=%f", param->posx);
|
MAX_X_POSITIONS[False(param->option & OrbisImeOption::USE_OVER_2K_COORDINATES)]) {
|
||||||
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid posx={}", param->posx);
|
||||||
return Error::INVALID_POSX;
|
return Error::INVALID_POSX;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param->posy < 0.0f ||
|
if (param->posy < 0.0f ||
|
||||||
param->posy >= MAX_Y_POSITIONS[False(param->option & OrbisImeOption::USE_2K_COORDINATES)]) {
|
param->posy >=
|
||||||
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid posy=%f", param->posy);
|
MAX_Y_POSITIONS[False(param->option & OrbisImeOption::USE_OVER_2K_COORDINATES)]) {
|
||||||
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid posy={}", param->posy);
|
||||||
return Error::INVALID_POSY;
|
return Error::INVALID_POSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +221,7 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValidOption(param->option, param->type)) {
|
if (!IsValidOption(param->option, param->type)) {
|
||||||
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid option=0x%X for type=%u",
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid option=0x{:X}for type={}",
|
||||||
static_cast<u32>(param->option), (u32)param->type);
|
static_cast<u32>(param->option), (u32)param->type);
|
||||||
return Error::INVALID_PARAM;
|
return Error::INVALID_PARAM;
|
||||||
}
|
}
|
||||||
@ -204,25 +233,27 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt
|
|||||||
|
|
||||||
if (extended) {
|
if (extended) {
|
||||||
if (!magic_enum::enum_contains(extended->priority)) {
|
if (!magic_enum::enum_contains(extended->priority)) {
|
||||||
LOG_INFO(Lib_ImeDialog, "Invalid extended->priority");
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: Invalid extended->priority");
|
||||||
return Error::INVALID_EXTENDED;
|
return Error::INVALID_EXTENDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: do correct extended->option validation
|
// TODO: do correct extended->option validation
|
||||||
|
|
||||||
if ((extended->ext_keyboard_mode & 0xe3fffffc) != 0) {
|
if ((extended->ext_keyboard_mode & 0xe3fffffc) != 0) {
|
||||||
LOG_INFO(Lib_ImeDialog, "Invalid extended->extKeyboardMode");
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: Invalid extended->extKeyboardMode");
|
||||||
return Error::INVALID_EXTENDED;
|
return Error::INVALID_EXTENDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extended->disable_device > 7) {
|
if (static_cast<u32>(extended->disable_device) & ~kValidOrbisImeDisableDeviceMask) {
|
||||||
LOG_INFO(Lib_ImeDialog, "Invalid extended->disableDevice");
|
LOG_ERROR(Lib_ImeDialog,
|
||||||
|
"sceImeDialogInit: disable_device has invalid bits set (0x{:X})",
|
||||||
|
static_cast<u32>(extended->disable_device));
|
||||||
return Error::INVALID_EXTENDED;
|
return Error::INVALID_EXTENDED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param->max_text_length == 0 || param->max_text_length > ORBIS_IME_MAX_TEXT_LENGTH) {
|
if (param->max_text_length == 0 || param->max_text_length > ORBIS_IME_MAX_TEXT_LENGTH) {
|
||||||
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid max_text_length=%u",
|
LOG_ERROR(Lib_ImeDialog, "sceImeDialogInit: invalid max_text_length={}",
|
||||||
param->max_text_length);
|
param->max_text_length);
|
||||||
return Error::INVALID_MAX_TEXT_LENGTH;
|
return Error::INVALID_MAX_TEXT_LENGTH;
|
||||||
}
|
}
|
||||||
@ -238,7 +269,7 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt
|
|||||||
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");
|
LOG_INFO(Lib_ImeDialog, "sceImeDialogInit: successful, status now=Running");
|
||||||
return Error::OK;
|
return Error::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user