mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-12-29 11:06:07 +00:00
core/libraries: Misc. Ime fixes
This commit is contained in:
parent
36044043bc
commit
83d08bf96b
|
@ -49,7 +49,11 @@ public:
|
||||||
openEvent.param.resourceIdArray.resourceId[0] = 1;
|
openEvent.param.resourceIdArray.resourceId[0] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Execute(nullptr, &openEvent, true);
|
// Are we supposed to call the event handler on init with
|
||||||
|
// ADD_OSK?
|
||||||
|
if (!ime_mode && False(m_param.key.option & OrbisImeKeyboardOption::ADD_OSK)) {
|
||||||
|
Execute(nullptr, &openEvent, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (ime_mode) {
|
if (ime_mode) {
|
||||||
g_ime_state = ImeState(&m_param.ime);
|
g_ime_state = ImeState(&m_param.ime);
|
||||||
|
@ -58,6 +62,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Update(OrbisImeEventHandler handler) {
|
s32 Update(OrbisImeEventHandler handler) {
|
||||||
|
if (!m_ime_mode) {
|
||||||
|
/* We don't handle any events for ImeKeyboard */
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_lock lock{g_ime_state.queue_mutex};
|
std::unique_lock lock{g_ime_state.queue_mutex};
|
||||||
|
|
||||||
while (!g_ime_state.event_queue.empty()) {
|
while (!g_ime_state.event_queue.empty()) {
|
||||||
|
@ -87,6 +96,16 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 SetText(const char16_t* text, u32 length) {
|
||||||
|
g_ime_state.SetText(text, length);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 SetCaret(const OrbisImeCaret* caret) {
|
||||||
|
g_ime_state.SetCaret(caret->index);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsIme() {
|
bool IsIme() {
|
||||||
return m_ime_mode;
|
return m_ime_mode;
|
||||||
}
|
}
|
||||||
|
@ -100,6 +119,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::unique_ptr<ImeHandler> g_ime_handler;
|
static std::unique_ptr<ImeHandler> g_ime_handler;
|
||||||
|
static std::unique_ptr<ImeHandler> g_keyboard_handler;
|
||||||
|
|
||||||
int PS4_SYSV_ABI FinalizeImeModule() {
|
int PS4_SYSV_ABI FinalizeImeModule() {
|
||||||
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
||||||
|
@ -132,9 +152,6 @@ s32 PS4_SYSV_ABI sceImeClose() {
|
||||||
if (!g_ime_handler) {
|
if (!g_ime_handler) {
|
||||||
return ORBIS_IME_ERROR_NOT_OPENED;
|
return ORBIS_IME_ERROR_NOT_OPENED;
|
||||||
}
|
}
|
||||||
if (!g_ime_handler->IsIme()) {
|
|
||||||
return ORBIS_IME_ERROR_NOT_OPENED;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_ime_handler.release();
|
g_ime_handler.release();
|
||||||
g_ime_ui = ImeUi();
|
g_ime_ui = ImeUi();
|
||||||
|
@ -235,14 +252,11 @@ s32 PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32*
|
||||||
s32 PS4_SYSV_ABI sceImeKeyboardClose(s32 userId) {
|
s32 PS4_SYSV_ABI sceImeKeyboardClose(s32 userId) {
|
||||||
LOG_INFO(Lib_Ime, "(STUBBED) called");
|
LOG_INFO(Lib_Ime, "(STUBBED) called");
|
||||||
|
|
||||||
if (!g_ime_handler) {
|
if (!g_keyboard_handler) {
|
||||||
return ORBIS_IME_ERROR_NOT_OPENED;
|
|
||||||
}
|
|
||||||
if (g_ime_handler->IsIme()) {
|
|
||||||
return ORBIS_IME_ERROR_NOT_OPENED;
|
return ORBIS_IME_ERROR_NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ime_handler.release();
|
g_keyboard_handler.release();
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,18 +271,17 @@ int PS4_SYSV_ABI sceImeKeyboardGetResourceId() {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceImeKeyboardOpen(s32 userId, const OrbisImeKeyboardParam* param) {
|
s32 PS4_SYSV_ABI sceImeKeyboardOpen(s32 userId, const OrbisImeKeyboardParam* param) {
|
||||||
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
LOG_INFO(Lib_Ime, "called");
|
||||||
|
|
||||||
if (!param) {
|
if (!param) {
|
||||||
return ORBIS_IME_ERROR_INVALID_ADDRESS;
|
return ORBIS_IME_ERROR_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
if (g_ime_handler) {
|
if (g_keyboard_handler) {
|
||||||
return ORBIS_IME_ERROR_BUSY;
|
return ORBIS_IME_ERROR_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// g_ime_handler = std::make_unique<ImeHandler>(param);
|
g_keyboard_handler = std::make_unique<ImeHandler>(param);
|
||||||
// return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
return ORBIS_IME_ERROR_CONNECTION_FAILED; // Fixup
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeKeyboardOpenInternal() {
|
int PS4_SYSV_ABI sceImeKeyboardOpenInternal() {
|
||||||
|
@ -289,16 +302,14 @@ int PS4_SYSV_ABI sceImeKeyboardUpdate() {
|
||||||
s32 PS4_SYSV_ABI sceImeOpen(const OrbisImeParam* param, const void* extended) {
|
s32 PS4_SYSV_ABI sceImeOpen(const OrbisImeParam* param, const void* extended) {
|
||||||
LOG_INFO(Lib_Ime, "called");
|
LOG_INFO(Lib_Ime, "called");
|
||||||
|
|
||||||
if (!g_ime_handler) {
|
if (!param) {
|
||||||
g_ime_handler = std::make_unique<ImeHandler>(param);
|
return ORBIS_IME_ERROR_INVALID_ADDRESS;
|
||||||
} else {
|
}
|
||||||
if (g_ime_handler->IsIme()) {
|
if (g_ime_handler) {
|
||||||
return ORBIS_IME_ERROR_BUSY;
|
return ORBIS_IME_ERROR_BUSY;
|
||||||
}
|
|
||||||
|
|
||||||
g_ime_handler->Init((void*)param, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_ime_handler = std::make_unique<ImeHandler>(param);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,13 +335,29 @@ int PS4_SYSV_ABI sceImeSetCandidateIndex() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeSetCaret(const OrbisImeCaret* caret) {
|
int PS4_SYSV_ABI sceImeSetCaret(const OrbisImeCaret* caret) {
|
||||||
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
LOG_TRACE(Lib_Ime, "called");
|
||||||
return ORBIS_OK;
|
|
||||||
|
if (!g_ime_handler) {
|
||||||
|
return ORBIS_IME_ERROR_NOT_OPENED;
|
||||||
|
}
|
||||||
|
if (!caret) {
|
||||||
|
return ORBIS_IME_ERROR_INVALID_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_ime_handler->SetCaret(caret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeSetText() {
|
s32 PS4_SYSV_ABI sceImeSetText(const char16_t* text, u32 length) {
|
||||||
LOG_ERROR(Lib_Ime, "(STUBBED) called");
|
LOG_TRACE(Lib_Ime, "called");
|
||||||
return ORBIS_OK;
|
|
||||||
|
if (!g_ime_handler) {
|
||||||
|
return ORBIS_IME_ERROR_NOT_OPENED;
|
||||||
|
}
|
||||||
|
if (!text) {
|
||||||
|
return ORBIS_IME_ERROR_INVALID_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_ime_handler->SetText(text, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeSetTextGeometry() {
|
int PS4_SYSV_ABI sceImeSetTextGeometry() {
|
||||||
|
@ -339,13 +366,19 @@ int PS4_SYSV_ABI sceImeSetTextGeometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceImeUpdate(OrbisImeEventHandler handler) {
|
s32 PS4_SYSV_ABI sceImeUpdate(OrbisImeEventHandler handler) {
|
||||||
LOG_TRACE(Lib_Ime, "called");
|
if (g_ime_handler) {
|
||||||
|
g_ime_handler->Update(handler);
|
||||||
|
}
|
||||||
|
|
||||||
if (!g_ime_handler) {
|
if (g_keyboard_handler) {
|
||||||
|
g_keyboard_handler->Update(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_ime_handler || !g_keyboard_handler) {
|
||||||
return ORBIS_IME_ERROR_NOT_OPENED;
|
return ORBIS_IME_ERROR_NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_ime_handler->Update(handler);
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeVshClearPreedit() {
|
int PS4_SYSV_ABI sceImeVshClearPreedit() {
|
||||||
|
|
|
@ -26,6 +26,24 @@ enum class OrbisImeKeyboardOption : u32 {
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeKeyboardOption)
|
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 {
|
struct OrbisImeKeyboardParam {
|
||||||
OrbisImeKeyboardOption option;
|
OrbisImeKeyboardOption option;
|
||||||
s8 reserved1[4];
|
s8 reserved1[4];
|
||||||
|
@ -41,7 +59,7 @@ struct OrbisImeParam {
|
||||||
OrbisImeEnterLabel enterLabel;
|
OrbisImeEnterLabel enterLabel;
|
||||||
OrbisImeInputMethod inputMethod;
|
OrbisImeInputMethod inputMethod;
|
||||||
OrbisImeTextFilter filter;
|
OrbisImeTextFilter filter;
|
||||||
u32 option;
|
OrbisImeOption option;
|
||||||
u32 maxTextLength;
|
u32 maxTextLength;
|
||||||
char16_t* inputTextBuffer;
|
char16_t* inputTextBuffer;
|
||||||
float posx;
|
float posx;
|
||||||
|
@ -93,7 +111,7 @@ 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);
|
s32 PS4_SYSV_ABI sceImeSetCaret(const OrbisImeCaret* caret);
|
||||||
int PS4_SYSV_ABI sceImeSetText();
|
s32 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);
|
s32 PS4_SYSV_ABI sceImeUpdate(OrbisImeEventHandler handler);
|
||||||
int PS4_SYSV_ABI sceImeVshClearPreedit();
|
int PS4_SYSV_ABI sceImeVshClearPreedit();
|
||||||
|
|
|
@ -143,7 +143,7 @@ struct OrbisImeKeycode {
|
||||||
|
|
||||||
struct OrbisImeKeyboardResourceIdArray {
|
struct OrbisImeKeyboardResourceIdArray {
|
||||||
s32 userId;
|
s32 userId;
|
||||||
u32 resourceId[6];
|
u32 resourceId[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class OrbisImeCaretMovementDirection : u32 {
|
enum class OrbisImeCaretMovementDirection : u32 {
|
||||||
|
|
|
@ -26,15 +26,13 @@ ImeState::ImeState(const OrbisImeParam* param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ImeState::ImeState(ImeState&& other) noexcept
|
ImeState::ImeState(ImeState&& other) noexcept
|
||||||
: input_changed(other.input_changed), work_buffer(other.work_buffer),
|
: work_buffer(other.work_buffer), text_buffer(other.text_buffer),
|
||||||
text_buffer(other.text_buffer), current_text(std::move(other.current_text)),
|
current_text(std::move(other.current_text)), event_queue(std::move(other.event_queue)) {
|
||||||
event_queue(std::move(other.event_queue)) {
|
|
||||||
other.text_buffer = nullptr;
|
other.text_buffer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImeState& ImeState::operator=(ImeState&& other) noexcept {
|
ImeState& ImeState::operator=(ImeState&& other) noexcept {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
input_changed = other.input_changed;
|
|
||||||
work_buffer = other.work_buffer;
|
work_buffer = other.work_buffer;
|
||||||
text_buffer = other.text_buffer;
|
text_buffer = other.text_buffer;
|
||||||
current_text = std::move(other.current_text);
|
current_text = std::move(other.current_text);
|
||||||
|
@ -63,6 +61,10 @@ void ImeState::SendCloseEvent() {
|
||||||
SendEvent(&closeEvent);
|
SendEvent(&closeEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImeState::SetText(const char16_t* text, u32 length) {}
|
||||||
|
|
||||||
|
void ImeState::SetCaret(u32 position) {}
|
||||||
|
|
||||||
bool ImeState::ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len,
|
bool ImeState::ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len,
|
||||||
char* utf8_text, std::size_t utf8_text_len) {
|
char* utf8_text, std::size_t utf8_text_len) {
|
||||||
std::fill(utf8_text, utf8_text + utf8_text_len, '\0');
|
std::fill(utf8_text, utf8_text + utf8_text_len, '\0');
|
||||||
|
@ -182,7 +184,6 @@ void ImeUi::DrawInputText() {
|
||||||
}
|
}
|
||||||
if (InputTextEx("##ImeInput", nullptr, state->current_text.begin(), ime_param->maxTextLength,
|
if (InputTextEx("##ImeInput", nullptr, state->current_text.begin(), ime_param->maxTextLength,
|
||||||
input_size, ImGuiInputTextFlags_CallbackAlways, InputTextCallback, this)) {
|
input_size, ImGuiInputTextFlags_CallbackAlways, InputTextCallback, this)) {
|
||||||
state->input_changed = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,25 +191,6 @@ int ImeUi::InputTextCallback(ImGuiInputTextCallbackData* data) {
|
||||||
ImeUi* ui = static_cast<ImeUi*>(data->UserData);
|
ImeUi* ui = static_cast<ImeUi*>(data->UserData);
|
||||||
ASSERT(ui);
|
ASSERT(ui);
|
||||||
|
|
||||||
static int lastCaretPos = -1;
|
|
||||||
if (lastCaretPos == -1) {
|
|
||||||
lastCaretPos = data->CursorPos;
|
|
||||||
} else if (data->CursorPos != lastCaretPos) {
|
|
||||||
OrbisImeCaretMovementDirection caretDirection = OrbisImeCaretMovementDirection::STILL;
|
|
||||||
if (data->CursorPos < lastCaretPos) {
|
|
||||||
caretDirection = OrbisImeCaretMovementDirection::LEFT;
|
|
||||||
} else if (data->CursorPos > lastCaretPos) {
|
|
||||||
caretDirection = OrbisImeCaretMovementDirection::RIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
OrbisImeEvent event{};
|
|
||||||
event.id = OrbisImeEventId::UPDATE_CARET;
|
|
||||||
event.param.caretMove = caretDirection;
|
|
||||||
|
|
||||||
lastCaretPos = data->CursorPos;
|
|
||||||
ui->state->SendEvent(&event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string lastText;
|
static std::string lastText;
|
||||||
std::string currentText(data->Buf, data->BufTextLen);
|
std::string currentText(data->Buf, data->BufTextLen);
|
||||||
if (currentText != lastText) {
|
if (currentText != lastText) {
|
||||||
|
@ -242,6 +224,25 @@ int ImeUi::InputTextCallback(ImGuiInputTextCallbackData* data) {
|
||||||
ui->state->SendEvent(&event);
|
ui->state->SendEvent(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lastCaretPos = -1;
|
||||||
|
if (lastCaretPos == -1) {
|
||||||
|
lastCaretPos = data->CursorPos;
|
||||||
|
} else if (data->CursorPos != lastCaretPos) {
|
||||||
|
OrbisImeCaretMovementDirection caretDirection = OrbisImeCaretMovementDirection::STILL;
|
||||||
|
if (data->CursorPos < lastCaretPos) {
|
||||||
|
caretDirection = OrbisImeCaretMovementDirection::LEFT;
|
||||||
|
} else if (data->CursorPos > lastCaretPos) {
|
||||||
|
caretDirection = OrbisImeCaretMovementDirection::RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrbisImeEvent event{};
|
||||||
|
event.id = OrbisImeEventId::UPDATE_CARET;
|
||||||
|
event.param.caretMove = caretDirection;
|
||||||
|
|
||||||
|
lastCaretPos = data->CursorPos;
|
||||||
|
ui->state->SendEvent(&event);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,7 @@ class ImeState {
|
||||||
friend class ImeHandler;
|
friend class ImeHandler;
|
||||||
friend class ImeUi;
|
friend class ImeUi;
|
||||||
|
|
||||||
bool input_changed = false;
|
|
||||||
|
|
||||||
void* work_buffer{};
|
void* work_buffer{};
|
||||||
|
|
||||||
char16_t* text_buffer{};
|
char16_t* text_buffer{};
|
||||||
|
|
||||||
// A character can hold up to 4 bytes in UTF-8
|
// A character can hold up to 4 bytes in UTF-8
|
||||||
|
@ -43,6 +40,9 @@ public:
|
||||||
void SendEnterEvent();
|
void SendEnterEvent();
|
||||||
void SendCloseEvent();
|
void SendCloseEvent();
|
||||||
|
|
||||||
|
void SetText(const char16_t* text, u32 length);
|
||||||
|
void SetCaret(u32 position);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len, char* utf8_text,
|
bool ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len, char* utf8_text,
|
||||||
std::size_t native_text_len);
|
std::size_t native_text_len);
|
||||||
|
|
Loading…
Reference in a new issue