clang-format

This commit is contained in:
Lander Gallastegi 2024-10-06 14:38:21 +02:00
parent fa3d4b06aa
commit a6e4745421
4 changed files with 127 additions and 121 deletions

View File

@ -20,15 +20,18 @@ 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(OrbisImeDialogOption option, OrbisImeType type) {
if (False(~option & (OrbisImeDialogOption::MULTILINE | OrbisImeDialogOption::NO_AUTO_COMPLETION))) { if (False(~option &
(OrbisImeDialogOption::MULTILINE | OrbisImeDialogOption::NO_AUTO_COMPLETION))) {
return false; return false;
} }
if (True(option & OrbisImeDialogOption::MULTILINE) && type != OrbisImeType::DEFAULT && type != OrbisImeType::BASIC_LATIN) { if (True(option & OrbisImeDialogOption::MULTILINE) && type != OrbisImeType::DEFAULT &&
type != OrbisImeType::BASIC_LATIN) {
return false; return false;
} }
if (True(option & OrbisImeDialogOption::NO_AUTO_COMPLETION) && type != OrbisImeType::NUMBER && type != OrbisImeType::BASIC_LATIN ) { if (True(option & OrbisImeDialogOption::NO_AUTO_COMPLETION) && type != OrbisImeType::NUMBER &&
type != OrbisImeType::BASIC_LATIN) {
return false; return false;
} }
@ -36,7 +39,8 @@ static bool IsValidOption(OrbisImeDialogOption option, OrbisImeType type) {
} }
// static bool IsMemZero(const void* ptr, size_t size) { // static bool IsMemZero(const void* ptr, size_t size) {
// return std::all_of(static_cast<const u8*>(ptr), static_cast<const u8*>(ptr) + size, [](u8 c) { return c == 0; }); // return std::all_of(static_cast<const u8*>(ptr), static_cast<const u8*>(ptr) + size, [](u8 c)
// { return c == 0; });
// } // }
Error PS4_SYSV_ABI sceImeDialogAbort() { Error PS4_SYSV_ABI sceImeDialogAbort() {
@ -143,15 +147,19 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt
return Error::INVALID_ADDRESS; return Error::INVALID_ADDRESS;
} }
//TODO: do correct param->option validation // TODO: do correct param->option validation
//TODO: do correct param->supportedLanguages validation // TODO: do correct param->supportedLanguages validation
if (param->posx < 0.0f || param->posx >= MAX_X_POSITIONS[False(param->option & OrbisImeDialogOption::LARGE_RESOLUTION)]) { if (param->posx < 0.0f ||
param->posx >=
MAX_X_POSITIONS[False(param->option & OrbisImeDialogOption::LARGE_RESOLUTION)]) {
LOG_INFO(Lib_ImeDialog, "Invalid param->posx"); LOG_INFO(Lib_ImeDialog, "Invalid param->posx");
return Error::INVALID_POSX; return Error::INVALID_POSX;
} }
if (param->posy < 0.0f || param->posy >= MAX_Y_POSITIONS[False(param->option & OrbisImeDialogOption::LARGE_RESOLUTION)]) { if (param->posy < 0.0f ||
param->posy >=
MAX_Y_POSITIONS[False(param->option & OrbisImeDialogOption::LARGE_RESOLUTION)]) {
LOG_INFO(Lib_ImeDialog, "Invalid param->posy"); LOG_INFO(Lib_ImeDialog, "Invalid param->posy");
return Error::INVALID_POSY; return Error::INVALID_POSY;
} }
@ -171,7 +179,7 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt
return Error::INVALID_PARAM; return Error::INVALID_PARAM;
} }
if (param->userId != 1) { //We only support user 1 for now if (param->userId != 1) { // We only support user 1 for now
LOG_INFO(Lib_ImeDialog, "Invalid param->userId"); LOG_INFO(Lib_ImeDialog, "Invalid param->userId");
return Error::INVALID_USER_ID; return Error::INVALID_USER_ID;
} }
@ -192,7 +200,7 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt
return Error::INVALID_EXTENDED; return Error::INVALID_EXTENDED;
} }
//TODO: do correct extended->option validation // TODO: do correct extended->option validation
// if (IsMemZero(extended->reserved, 60)) { // if (IsMemZero(extended->reserved, 60)) {
// LOG_INFO(Lib_ImeDialog, "Invalid extended->reserved"); // LOG_INFO(Lib_ImeDialog, "Invalid extended->reserved");

61
src/core/libraries/dialogs/ime_dialog.h Executable file → Normal file
View File

@ -56,32 +56,13 @@ enum class Error : u32 {
DIALOG_NOT_IN_USE = 0x80bc0107 DIALOG_NOT_IN_USE = 0x80bc0107
}; };
enum class OrbisImeDialogStatus : u32 { enum class OrbisImeDialogStatus : u32 { NONE = 0, RUNNING = 1, FINISHED = 2 };
NONE = 0,
RUNNING = 1,
FINISHED = 2
};
enum class OrbisImeDialogEndStatus : u32 { enum class OrbisImeDialogEndStatus : u32 { OK = 0, USER_CANCELED = 1, ABORTED = 2 };
OK = 0,
USER_CANCELED = 1,
ABORTED = 2
};
enum class OrbisImeType : u32 { enum class OrbisImeType : u32 { DEFAULT = 0, BASIC_LATIN = 1, URL = 2, MAIL = 3, NUMBER = 4 };
DEFAULT = 0,
BASIC_LATIN = 1,
URL = 2,
MAIL = 3,
NUMBER = 4
};
enum class OrbisImeEnterLabel : u32 { enum class OrbisImeEnterLabel : u32 { DEFAULT = 0, SEND = 1, SEARCH = 2, GO = 3 };
DEFAULT = 0,
SEND = 1,
SEARCH = 2,
GO = 3
};
enum class OrbisImeDialogOption : u32 { enum class OrbisImeDialogOption : u32 {
DEFAULT = 0, DEFAULT = 0,
@ -94,28 +75,13 @@ enum class OrbisImeDialogOption : u32 {
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeDialogOption) DECLARE_ENUM_FLAG_OPERATORS(OrbisImeDialogOption)
enum class OrbisImeInputMethod : u32 { enum class OrbisImeInputMethod : u32 { DEFAULT = 0 };
DEFAULT = 0
};
enum class OrbisImeHorizontalAlignment : u32 { enum class OrbisImeHorizontalAlignment : u32 { LEFT = 0, CENTER = 1, RIGHT = 2 };
LEFT = 0,
CENTER = 1,
RIGHT = 2
};
enum class OrbisImeVerticalAlignment : u32 { enum class OrbisImeVerticalAlignment : u32 { TOP = 0, CENTER = 1, BOTTOM = 2 };
TOP = 0,
CENTER = 1,
BOTTOM = 2
};
enum class OrbisImePanelPriority : u32 { enum class OrbisImePanelPriority : u32 { DEFAULT = 0, ALPHABET = 1, SYMBOL = 2, ACCENT = 3 };
DEFAULT = 0,
ALPHABET = 1,
SYMBOL = 2,
ACCENT = 3
};
enum class OrbisImeKeyboardType : u32 { enum class OrbisImeKeyboardType : u32 {
NONE = 0, NONE = 0,
@ -180,11 +146,12 @@ struct OrbisImeKeycode {
u64 timestamp; u64 timestamp;
}; };
typedef PS4_SYSV_ABI int (*OrbisImeTextFilter)(char16_t* outText, u32* outTextLength, const char16_t* srcText, typedef PS4_SYSV_ABI int (*OrbisImeTextFilter)(char16_t* outText, u32* outTextLength,
u32 srcTextLength); const char16_t* srcText, u32 srcTextLength);
typedef PS4_SYSV_ABI int (*OrbisImeExtKeyboardFilter)(const OrbisImeKeycode* srcKeycode, u16* outKeycode, typedef PS4_SYSV_ABI int (*OrbisImeExtKeyboardFilter)(const OrbisImeKeycode* srcKeycode,
u32* outStatus, void* reserved); u16* outKeycode, u32* outStatus,
void* reserved);
struct OrbisImeDialogParam { struct OrbisImeDialogParam {
s32 userId; s32 userId;
@ -206,7 +173,7 @@ struct OrbisImeDialogParam {
}; };
struct OrbisImeParamExtended { struct OrbisImeParamExtended {
u32 option; //OrbisImeDialogOptionExtended u32 option; // OrbisImeDialogOptionExtended
OrbisImeColor colorBase; OrbisImeColor colorBase;
OrbisImeColor colorLine; OrbisImeColor colorLine;
OrbisImeColor colorTextField; OrbisImeColor colorTextField;

116
src/core/libraries/dialogs/ime_dialog_ui.cpp Executable file → Normal file
View File

@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <cwchar>
#include <string>
#include <imgui.h> #include <imgui.h>
#include <magic_enum.hpp> #include <magic_enum.hpp>
#include <string>
#include <cwchar>
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
@ -27,8 +27,10 @@ static constexpr ImVec2 BUTTON_SIZE{100.0f, 30.0f};
namespace Libraries::ImeDialog { namespace Libraries::ImeDialog {
ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param, const OrbisImeParamExtended* extended) { ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param,
if (!param) return; const OrbisImeParamExtended* extended) {
if (!param)
return;
userId = param->userId; userId = param->userId;
is_multiLine = True(param->option & OrbisImeDialogOption::MULTILINE); is_multiLine = True(param->option & OrbisImeDialogOption::MULTILINE);
@ -42,7 +44,7 @@ ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param, const OrbisImeP
#ifndef _WIN32 #ifndef _WIN32
orbis_to_utf8 = iconv_open(IME_UTF8_ENCODING, IME_ORBIS_ENCODING); orbis_to_utf8 = iconv_open(IME_UTF8_ENCODING, IME_ORBIS_ENCODING);
utf8_to_orbis = iconv_open(IME_ORBIS_ENCODING , IME_UTF8_ENCODING); utf8_to_orbis = iconv_open(IME_ORBIS_ENCODING, IME_UTF8_ENCODING);
ASSERT_MSG(orbis_to_utf8 != (iconv_t)-1, "Failed to open iconv orbis_to_utf8"); ASSERT_MSG(orbis_to_utf8 != (iconv_t)-1, "Failed to open iconv orbis_to_utf8");
ASSERT_MSG(utf8_to_orbis != (iconv_t)-1, "Failed to open iconv utf8_to_orbis"); ASSERT_MSG(utf8_to_orbis != (iconv_t)-1, "Failed to open iconv utf8_to_orbis");
@ -61,7 +63,8 @@ ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param, const OrbisImeP
std::size_t placeholder_len = std::char_traits<char16_t>::length(param->placeholder); std::size_t placeholder_len = std::char_traits<char16_t>::length(param->placeholder);
placeholder = new char[placeholder_len * 4 + 1]; placeholder = new char[placeholder_len * 4 + 1];
if (!ConvertOrbisToUTF8(param->placeholder, placeholder_len, placeholder, placeholder_len)) { if (!ConvertOrbisToUTF8(param->placeholder, placeholder_len, placeholder,
placeholder_len)) {
LOG_ERROR(Lib_ImeDialog, "Failed to convert placeholder to utf8 encoding"); LOG_ERROR(Lib_ImeDialog, "Failed to convert placeholder to utf8 encoding");
} }
} }
@ -77,17 +80,10 @@ ImeDialogState::~ImeDialogState() {
} }
ImeDialogState::ImeDialogState(ImeDialogState&& other) noexcept ImeDialogState::ImeDialogState(ImeDialogState&& other) noexcept
: userId(other.userId), : userId(other.userId), is_multiLine(other.is_multiLine), is_numeric(other.is_numeric),
is_multiLine(other.is_multiLine), type(other.type), enter_label(other.enter_label), text_filter(other.text_filter),
is_numeric(other.is_numeric), keyboard_filter(other.keyboard_filter), max_text_length(other.max_text_length),
type(other.type), text_buffer(other.text_buffer), title(other.title), placeholder(other.placeholder),
enter_label(other.enter_label),
text_filter(other.text_filter),
keyboard_filter(other.keyboard_filter),
max_text_length(other.max_text_length),
text_buffer(other.text_buffer),
title(other.title),
placeholder(other.placeholder),
input_changed(other.input_changed) { input_changed(other.input_changed) {
std::memcpy(current_text, other.current_text, sizeof(current_text)); std::memcpy(current_text, other.current_text, sizeof(current_text));
@ -161,19 +157,22 @@ bool ImeDialogState::CallTextFilter() {
char16_t out_text[ORBIS_IME_DIALOG_MAX_TEXT_LENGTH + 1] = {0}; char16_t out_text[ORBIS_IME_DIALOG_MAX_TEXT_LENGTH + 1] = {0};
u32 out_text_length = ORBIS_IME_DIALOG_MAX_TEXT_LENGTH; u32 out_text_length = ORBIS_IME_DIALOG_MAX_TEXT_LENGTH;
if (!ConvertUTF8ToOrbis(current_text, src_text_length, src_text, ORBIS_IME_DIALOG_MAX_TEXT_LENGTH)) { if (!ConvertUTF8ToOrbis(current_text, src_text_length, src_text,
ORBIS_IME_DIALOG_MAX_TEXT_LENGTH)) {
LOG_ERROR(Lib_ImeDialog, "Failed to convert text to orbis encoding"); LOG_ERROR(Lib_ImeDialog, "Failed to convert text to orbis encoding");
return false; return false;
} }
auto* linker = Common::Singleton<Core::Linker>::Instance(); auto* linker = Common::Singleton<Core::Linker>::Instance();
int ret = linker->ExecuteGuest(text_filter, out_text, &out_text_length, src_text, src_text_length); int ret =
linker->ExecuteGuest(text_filter, out_text, &out_text_length, src_text, src_text_length);
if (ret != 0) { if (ret != 0) {
return false; return false;
} }
if (!ConvertOrbisToUTF8(out_text, out_text_length, current_text, ORBIS_IME_DIALOG_MAX_TEXT_LENGTH)) { if (!ConvertOrbisToUTF8(out_text, out_text_length, current_text,
ORBIS_IME_DIALOG_MAX_TEXT_LENGTH)) {
LOG_ERROR(Lib_ImeDialog, "Failed to convert text to utf8 encoding"); LOG_ERROR(Lib_ImeDialog, "Failed to convert text to utf8 encoding");
return false; return false;
} }
@ -200,7 +199,8 @@ void ImeDialogState::Free() {
} }
} }
bool ImeDialogState::CallKeyboardFilter(const OrbisImeKeycode* src_keycode, u16* out_keycode, u32* out_status) { bool ImeDialogState::CallKeyboardFilter(const OrbisImeKeycode* src_keycode, u16* out_keycode,
u32* out_status) {
if (!keyboard_filter) { if (!keyboard_filter) {
return true; return true;
} }
@ -211,7 +211,8 @@ bool ImeDialogState::CallKeyboardFilter(const OrbisImeKeycode* src_keycode, u16*
return ret == 0; return ret == 0;
} }
bool ImeDialogState::ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len, char* utf8_text, std::size_t utf8_text_len) { bool ImeDialogState::ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len,
char* utf8_text, std::size_t utf8_text_len) {
#ifndef _WIN32 #ifndef _WIN32
std::size_t orbis_text_len_bytes = orbis_text_len * sizeof(char16_t); std::size_t orbis_text_len_bytes = orbis_text_len * sizeof(char16_t);
std::size_t utf8_text_len_bytes = utf8_text_len * sizeof(char); std::size_t utf8_text_len_bytes = utf8_text_len * sizeof(char);
@ -219,7 +220,8 @@ bool ImeDialogState::ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t
char16_t* orbis_text_ptr = const_cast<char16_t*>(orbis_text); char16_t* orbis_text_ptr = const_cast<char16_t*>(orbis_text);
char* utf8_text_ptr = utf8_text; char* utf8_text_ptr = utf8_text;
std::size_t result = iconv(orbis_to_utf8, (char**)&orbis_text_ptr, &orbis_text_len_bytes, (char**)&utf8_text_ptr, &utf8_text_len_bytes); std::size_t result = iconv(orbis_to_utf8, (char**)&orbis_text_ptr, &orbis_text_len_bytes,
(char**)&utf8_text_ptr, &utf8_text_len_bytes);
if (result == (std::size_t)-1) { if (result == (std::size_t)-1) {
return false; return false;
@ -228,12 +230,16 @@ bool ImeDialogState::ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t
*utf8_text_ptr = '\0'; // Null-terminate the string *utf8_text_ptr = '\0'; // Null-terminate the string
return true; return true;
#else #else
int required_size = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<const wchar_t*>(orbis_text), orbis_text_len, nullptr, 0, nullptr, nullptr); int required_size =
WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<const wchar_t*>(orbis_text),
orbis_text_len, nullptr, 0, nullptr, nullptr);
if (required_size > utf8_text_len) { if (required_size > utf8_text_len) {
return false; return false;
} }
int converted_size = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<const wchar_t*>(orbis_text), orbis_text_len, utf8_text, utf8_text_len, nullptr, nullptr); int converted_size =
WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<const wchar_t*>(orbis_text),
orbis_text_len, utf8_text, utf8_text_len, nullptr, nullptr);
if (required_size == 0) { if (required_size == 0) {
return false; return false;
@ -245,7 +251,8 @@ bool ImeDialogState::ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t
#endif #endif
} }
bool ImeDialogState::ConvertUTF8ToOrbis(const char* utf8_text, std::size_t utf8_text_len, char16_t* orbis_text, std::size_t orbis_text_len) { bool ImeDialogState::ConvertUTF8ToOrbis(const char* utf8_text, std::size_t utf8_text_len,
char16_t* orbis_text, std::size_t orbis_text_len) {
#ifndef _WIN32 #ifndef _WIN32
std::size_t utf8_text_len_bytes = utf8_text_len * sizeof(char); std::size_t utf8_text_len_bytes = utf8_text_len * sizeof(char);
std::size_t orbis_text_len_bytes = orbis_text_len * sizeof(char16_t); std::size_t orbis_text_len_bytes = orbis_text_len * sizeof(char16_t);
@ -253,7 +260,8 @@ bool ImeDialogState::ConvertUTF8ToOrbis(const char* utf8_text, std::size_t utf8_
char* utf8_text_ptr = const_cast<char*>(utf8_text); char* utf8_text_ptr = const_cast<char*>(utf8_text);
char16_t* orbis_text_ptr = orbis_text; char16_t* orbis_text_ptr = orbis_text;
std::size_t result = iconv(utf8_to_orbis, (char**)&utf8_text_ptr, &utf8_text_len_bytes, (char**)&orbis_text_ptr, &orbis_text_len_bytes); std::size_t result = iconv(utf8_to_orbis, (char**)&utf8_text_ptr, &utf8_text_len_bytes,
(char**)&orbis_text_ptr, &orbis_text_len_bytes);
if (result == (std::size_t)-1) { if (result == (std::size_t)-1) {
return false; return false;
@ -267,7 +275,9 @@ bool ImeDialogState::ConvertUTF8ToOrbis(const char* utf8_text, std::size_t utf8_
return false; return false;
} }
int converted_size = MultiByteToWideChar(CP_UTF8, 0, utf8_text, utf8_text_len, reinterpret_cast<wchar_t*>(orbis_text), orbis_text_len); int converted_size =
MultiByteToWideChar(CP_UTF8, 0, utf8_text, utf8_text_len,
reinterpret_cast<wchar_t*>(orbis_text), orbis_text_len);
if (required_size == 0) { if (required_size == 0) {
return false; return false;
@ -279,7 +289,8 @@ bool ImeDialogState::ConvertUTF8ToOrbis(const char* utf8_text, std::size_t utf8_
#endif #endif
} }
bool ImeDialogState::ConvertOrbisCharToUTF8(const char16_t orbis_char, char* utf8_char, std::size_t& utf8_char_len) { bool ImeDialogState::ConvertOrbisCharToUTF8(const char16_t orbis_char, char* utf8_char,
std::size_t& utf8_char_len) {
std::fill(utf8_char, utf8_char + 4, '\0'); std::fill(utf8_char, utf8_char + 4, '\0');
#ifndef _WIN32 #ifndef _WIN32
std::size_t orbis_char_len_bytes = sizeof(char16_t); std::size_t orbis_char_len_bytes = sizeof(char16_t);
@ -288,7 +299,8 @@ bool ImeDialogState::ConvertOrbisCharToUTF8(const char16_t orbis_char, char* utf
char16_t orbis_char_ptr = orbis_char; char16_t orbis_char_ptr = orbis_char;
char* utf8_char_ptr = utf8_char; char* utf8_char_ptr = utf8_char;
std::size_t result = iconv(orbis_to_utf8, (char**)&orbis_char_ptr, &orbis_char_len_bytes, (char**)&utf8_char_ptr, &utf8_char_len_bytes); std::size_t result = iconv(orbis_to_utf8, (char**)&orbis_char_ptr, &orbis_char_len_bytes,
(char**)&utf8_char_ptr, &utf8_char_len_bytes);
if (result == (std::size_t)-1) { if (result == (std::size_t)-1) {
utf8_char_len = 0; utf8_char_len = 0;
@ -298,12 +310,14 @@ bool ImeDialogState::ConvertOrbisCharToUTF8(const char16_t orbis_char, char* utf
utf8_char_len = 4 - utf8_char_len_bytes; utf8_char_len = 4 - utf8_char_len_bytes;
return true; return true;
#else #else
int required_size = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<const wchar_t*>(&orbis_char), 1, nullptr, 0, nullptr, nullptr); int required_size = WideCharToMultiByte(
CP_UTF8, 0, reinterpret_cast<const wchar_t*>(&orbis_char), 1, nullptr, 0, nullptr, nullptr);
if (required_size > 4) { if (required_size > 4) {
UNREACHABLE_MSG("UTF-8 character is never more than 4 bytes"); UNREACHABLE_MSG("UTF-8 character is never more than 4 bytes");
} }
utf8_char_len = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<const wchar_t*>(&orbis_char), 1, utf8_char, 4, nullptr, nullptr); utf8_char_len = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<const wchar_t*>(&orbis_char),
1, utf8_char, 4, nullptr, nullptr);
return utf8_char_len != 0; return utf8_char_len != 0;
#endif #endif
@ -317,7 +331,8 @@ bool ImeDialogState::ConvertUTF8CharToOrbis(const char* utf8_char, char16_t& orb
char* utf8_char_ptr = const_cast<char*>(utf8_char); char* utf8_char_ptr = const_cast<char*>(utf8_char);
char16_t* orbis_char_ptr = &orbis_char; char16_t* orbis_char_ptr = &orbis_char;
std::size_t result = iconv(utf8_to_orbis, (char**)&utf8_char_ptr, &utf8_char_len_bytes, (char**)&orbis_char_ptr, &orbis_char_len_bytes); std::size_t result = iconv(utf8_to_orbis, (char**)&utf8_char_ptr, &utf8_char_len_bytes,
(char**)&orbis_char_ptr, &orbis_char_len_bytes);
if (result == (std::size_t)-1) { if (result == (std::size_t)-1) {
return false; return false;
@ -325,12 +340,14 @@ bool ImeDialogState::ConvertUTF8CharToOrbis(const char* utf8_char, char16_t& orb
return true; return true;
#else #else
int required_size = MultiByteToWideChar(CP_UTF8, 0, utf8_char, std::strlen(utf8_char), reinterpret_cast<wchar_t*>(&orbis_char), 1); int required_size = MultiByteToWideChar(CP_UTF8, 0, utf8_char, std::strlen(utf8_char),
reinterpret_cast<wchar_t*>(&orbis_char), 1);
return required_size != 0; return required_size != 0;
#endif #endif
} }
ImeDialogUi::ImeDialogUi(ImeDialogState* state, OrbisImeDialogStatus* status, OrbisImeDialogResult* result) ImeDialogUi::ImeDialogUi(ImeDialogState* state, OrbisImeDialogStatus* status,
OrbisImeDialogResult* result)
: state(state), status(status), result(result) { : state(state), status(status), result(result) {
if (state && *status == OrbisImeDialogStatus::RUNNING) { if (state && *status == OrbisImeDialogStatus::RUNNING) {
@ -345,7 +362,8 @@ ImeDialogUi::~ImeDialogUi() {
} }
ImeDialogUi::ImeDialogUi(ImeDialogUi&& other) noexcept ImeDialogUi::ImeDialogUi(ImeDialogUi&& other) noexcept
: state(other.state), status(other.status), result(other.result), first_render(other.first_render) { : state(other.state), status(other.status), result(other.result),
first_render(other.first_render) {
std::scoped_lock lock(draw_mutex, other.draw_mutex); std::scoped_lock lock(draw_mutex, other.draw_mutex);
other.state = nullptr; other.state = nullptr;
@ -410,7 +428,8 @@ void ImeDialogUi::Draw() {
SetNextWindowFocus(); SetNextWindowFocus();
} }
if (Begin("IME Dialog##ImeDialog", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings)) { if (Begin("IME Dialog##ImeDialog", nullptr,
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings)) {
DrawPrettyBackground(); DrawPrettyBackground();
if (state->title) { if (state->title) {
@ -474,7 +493,9 @@ void ImeDialogUi::DrawInputText() {
if (first_render) { if (first_render) {
SetKeyboardFocusHere(); SetKeyboardFocusHere();
} }
if (InputTextEx("##ImeDialogInput", state->placeholder, state->current_text, state->max_text_length, input_size, ImGuiInputTextFlags_CallbackCharFilter, InputTextCallback, this)) { if (InputTextEx("##ImeDialogInput", state->placeholder, state->current_text,
state->max_text_length, input_size, ImGuiInputTextFlags_CallbackCharFilter,
InputTextCallback, this)) {
state->input_changed = true; state->input_changed = true;
} }
} }
@ -482,11 +503,13 @@ void ImeDialogUi::DrawInputText() {
void ImeDialogUi::DrawMultiLineInputText() { void ImeDialogUi::DrawMultiLineInputText() {
ImVec2 input_size = {GetWindowWidth() - 40.0f, 200.0f}; ImVec2 input_size = {GetWindowWidth() - 40.0f, 200.0f};
SetCursorPosX(20.0f); SetCursorPosX(20.0f);
ImGuiInputTextFlags flags = ImGuiInputTextFlags_CallbackCharFilter | static_cast<ImGuiInputTextFlags>(ImGuiInputTextFlags_Multiline); ImGuiInputTextFlags flags = ImGuiInputTextFlags_CallbackCharFilter |
static_cast<ImGuiInputTextFlags>(ImGuiInputTextFlags_Multiline);
if (first_render) { if (first_render) {
SetKeyboardFocusHere(); SetKeyboardFocusHere();
} }
if (InputTextEx("##ImeDialogInput", state->placeholder, state->current_text, state->max_text_length, input_size, flags, InputTextCallback, this)) { if (InputTextEx("##ImeDialogInput", state->placeholder, state->current_text,
state->max_text_length, input_size, flags, InputTextCallback, this)) {
state->input_changed = true; state->input_changed = true;
} }
} }
@ -497,7 +520,8 @@ int ImeDialogUi::InputTextCallback(ImGuiInputTextCallbackData* data) {
ASSERT(ui); ASSERT(ui);
// Should we filter punctuation? // Should we filter punctuation?
if (ui->state->is_numeric && (data->EventChar < '0' || data->EventChar > '9') && data->EventChar != '\b' && data->EventChar != ',' && data->EventChar != '.') { if (ui->state->is_numeric && (data->EventChar < '0' || data->EventChar > '9') &&
data->EventChar != '\b' && data->EventChar != ',' && data->EventChar != '.') {
return 1; return 1;
} }
@ -513,24 +537,24 @@ int ImeDialogUi::InputTextCallback(ImGuiInputTextCallbackData* data) {
.keycode = 0, .keycode = 0,
.character = 0, .character = 0,
.status = 1, // ??? 1 = key pressed, 0 = key released .status = 1, // ??? 1 = key pressed, 0 = key released
.type = OrbisImeKeyboardType::ENGLISH_US, //TODO set this to the correct value (maybe use the current language?) .type = OrbisImeKeyboardType::ENGLISH_US, // TODO set this to the correct value (maybe use
// the current language?)
.userId = ui->state->userId, .userId = ui->state->userId,
.resourceId = 0, .resourceId = 0,
.timestamp = 0 .timestamp = 0};
};
if (!ui->state->ConvertUTF8CharToOrbis(event_char, src_keycode.character)) { if (!ui->state->ConvertUTF8CharToOrbis(event_char, src_keycode.character)) {
LOG_ERROR(Lib_ImeDialog, "Failed to convert orbis char to utf8"); LOG_ERROR(Lib_ImeDialog, "Failed to convert orbis char to utf8");
return 0; return 0;
} }
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); ui->state->CallKeyboardFilter(&src_keycode, &out_keycode, &out_status);
//TODO. set the keycode // TODO. set the keycode
return 0; return 0;
} }

19
src/core/libraries/dialogs/ime_dialog_ui.h Executable file → Normal file
View File

@ -8,8 +8,8 @@
#include <iconv.h> #include <iconv.h>
#endif #endif
#include <imgui.h> #include <imgui.h>
#include "core/libraries/dialogs/ime_dialog.h"
#include "common/types.h" #include "common/types.h"
#include "core/libraries/dialogs/ime_dialog.h"
#include "imgui/imgui_layer.h" #include "imgui/imgui_layer.h"
namespace Libraries::ImeDialog { namespace Libraries::ImeDialog {
@ -40,7 +40,8 @@ class ImeDialogState final {
iconv_t utf8_to_orbis = (iconv_t)-1; iconv_t utf8_to_orbis = (iconv_t)-1;
#endif #endif
public: public:
ImeDialogState(const OrbisImeDialogParam* param = nullptr, const OrbisImeParamExtended* extended = nullptr); ImeDialogState(const OrbisImeDialogParam* param = nullptr,
const OrbisImeParamExtended* extended = nullptr);
ImeDialogState(const ImeDialogState& other) = delete; ImeDialogState(const ImeDialogState& other) = delete;
ImeDialogState(ImeDialogState&& other) noexcept; ImeDialogState(ImeDialogState&& other) noexcept;
ImeDialogState& operator=(ImeDialogState&& other); ImeDialogState& operator=(ImeDialogState&& other);
@ -49,13 +50,17 @@ public:
bool CopyTextToOrbisBuffer(); bool CopyTextToOrbisBuffer();
bool CallTextFilter(); bool CallTextFilter();
private: private:
void Free(); void Free();
bool CallKeyboardFilter(const OrbisImeKeycode* src_keycode, u16* out_keycode, u32* out_status); bool CallKeyboardFilter(const OrbisImeKeycode* src_keycode, u16* out_keycode, u32* out_status);
bool ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len, char* utf8_text, std::size_t native_text_len); bool ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len, char* utf8_text,
bool ConvertUTF8ToOrbis(const char* native_text, std::size_t utf8_text_len, char16_t* orbis_text, std::size_t orbis_text_len); std::size_t native_text_len);
bool ConvertOrbisCharToUTF8(const char16_t orbis_char, char* utf8_char, std::size_t& utf8_char_len); bool ConvertUTF8ToOrbis(const char* native_text, std::size_t utf8_text_len,
char16_t* orbis_text, std::size_t orbis_text_len);
bool ConvertOrbisCharToUTF8(const char16_t orbis_char, char* utf8_char,
std::size_t& utf8_char_len);
bool ConvertUTF8CharToOrbis(const char* utf8_char, char16_t& orbis_char); bool ConvertUTF8CharToOrbis(const char* utf8_char, char16_t& orbis_char);
}; };
@ -66,8 +71,10 @@ class ImeDialogUi final : public ImGui::Layer {
bool first_render = true; bool first_render = true;
std::mutex draw_mutex; std::mutex draw_mutex;
public: public:
explicit ImeDialogUi(ImeDialogState* state = nullptr, OrbisImeDialogStatus* status = nullptr, OrbisImeDialogResult* result = nullptr); explicit ImeDialogUi(ImeDialogState* state = nullptr, OrbisImeDialogStatus* status = nullptr,
OrbisImeDialogResult* result = nullptr);
~ImeDialogUi() override; ~ImeDialogUi() override;
ImeDialogUi(const ImeDialogUi& other) = delete; ImeDialogUi(const ImeDialogUi& other) = delete;
ImeDialogUi(ImeDialogUi&& other) noexcept; ImeDialogUi(ImeDialogUi&& other) noexcept;