diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp index a5e16f8cd2..8fc7137a59 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp @@ -181,6 +181,7 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr dia } // Get the OSK options + auto& info = g_fxo->get(); u32 maxLength = (inputFieldInfo->limit_length >= CELL_OSKDIALOG_STRING_SIZE) ? 511 : u32{inputFieldInfo->limit_length}; const u32 prohibitFlgs = dialogParam->prohibitFlgs; const u32 allowOskPanelFlg = dialogParam->allowOskPanelFlg; @@ -192,7 +193,6 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr dia // Also clear the info text just to be sure (it should be zeroed at this point anyway) { - auto& info = g_fxo->get(); std::lock_guard lock(info.text_mtx); info.valid_text = {}; } @@ -340,14 +340,23 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr dia input::SetIntercepted(false); }; - if (auto& info = g_fxo->get(); info.osk_continuous_mode == CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE) + if (info.osk_continuous_mode == CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE) { info.last_dialog_state = CELL_SYSUTIL_OSKDIALOG_LOADED; sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_LOADED, 0); return CELL_OK; } - input::SetIntercepted(true); + // Set device mask and event lock + osk->ignore_input_events = info.lock_ext_input.load(); + + if (info.use_separate_windows) + { + osk->pad_input_enabled = (info.device_mask != CELL_OSKDIALOG_DEVICE_MASK_PAD); + osk->mouse_input_enabled = (info.device_mask != CELL_OSKDIALOG_DEVICE_MASK_PAD); + } + + input::SetIntercepted(osk->pad_input_enabled, osk->keyboard_input_enabled, osk->mouse_input_enabled); Emu.CallFromMainThread([=, &result]() { @@ -550,9 +559,19 @@ error_code cellOskDialogSetDeviceMask(u32 deviceMask) return CELL_OSKDIALOG_ERROR_PARAM; } - g_fxo->get().device_mask = deviceMask; + auto& info = g_fxo->get(); + info.device_mask = deviceMask; - // TODO: change osk device input + if (info.use_separate_windows) + { + if (const auto osk = _get_osk_dialog(false)) + { + osk->pad_input_enabled = (deviceMask != CELL_OSKDIALOG_DEVICE_MASK_PAD); + osk->mouse_input_enabled = (deviceMask != CELL_OSKDIALOG_DEVICE_MASK_PAD); + + input::SetIntercepted(osk->pad_input_enabled, osk->keyboard_input_enabled, osk->mouse_input_enabled); + } + } return CELL_OK; } @@ -569,7 +588,12 @@ error_code cellOskDialogSetSeparateWindowOption(vm::ptrget(); osk.use_separate_windows = true; osk.osk_continuous_mode = static_cast(+windowOption->continuousMode); + osk.device_mask = windowOption->deviceMask; // TODO: handle rest of windowOption + // inputFieldWindowWidth; + // inputFieldBackgroundTrans; + // inputFieldLayoutInfo; + // inputPanelLayoutInfo; cellOskDialog.warning("cellOskDialogSetSeparateWindowOption: continuousMode=%s)", osk.osk_continuous_mode.load()); @@ -801,7 +825,10 @@ error_code cellOskDialogExtInputDeviceLock() g_fxo->get().lock_ext_input = true; - // TODO: change osk device input + if (const auto osk = _get_osk_dialog(false)) + { + osk->ignore_input_events = true; + } return CELL_OK; } @@ -814,7 +841,10 @@ error_code cellOskDialogExtInputDeviceUnlock() g_fxo->get().lock_ext_input = false; - // TODO: change osk device input + if (const auto osk = _get_osk_dialog(false)) + { + osk->ignore_input_events = false; + } return CELL_OK; } @@ -888,7 +918,7 @@ error_code cellOskDialogExtSetPointerEnable(b8 enable) g_fxo->get().pointer_enabled = enable; - // TODO: use new value in osk + // TODO: Show/hide pointer at the specified position in the OSK overlay. return CELL_OK; } @@ -904,7 +934,7 @@ error_code cellOskDialogExtUpdatePointerDisplayPos(vm::cptr g_fxo->get().pointer_pos = *pos; } - // TODO: use new value in osk + // TODO: Update pointer position in the OSK overlay. return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.h b/rpcs3/Emu/Cell/Modules/cellOskDialog.h index b363de22f9..aa5253109c 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.h +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.h @@ -265,6 +265,10 @@ public: std::function on_osk_input_entered; atomic_t state{ OskDialogState::Unloaded }; + atomic_t pad_input_enabled{ true }; // Determines if the OSK consumes the device's events. + atomic_t mouse_input_enabled{ true }; // Determines if the OSK consumes the device's events. + atomic_t keyboard_input_enabled{ true }; // Determines if the OSK consumes the device's events. + atomic_t ignore_input_events{ false }; // Determines if the OSK ignores all consumed events. atomic_t osk_input_result{ CellOskDialogInputFieldResult::CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK }; char16_t osk_text[CELL_OSKDIALOG_STRING_SIZE]{}; diff --git a/rpcs3/Emu/Io/interception.cpp b/rpcs3/Emu/Io/interception.cpp index 3cbc3fa625..b260ff239a 100644 --- a/rpcs3/Emu/Io/interception.cpp +++ b/rpcs3/Emu/Io/interception.cpp @@ -7,22 +7,31 @@ namespace input { - atomic_t g_intercepted{false}; + atomic_t g_pads_intercepted{false}; + atomic_t g_keyboards_intercepted{false}; + atomic_t g_mice_intercepted{false}; - void SetIntercepted(bool intercepted) + void SetIntercepted(bool pads_intercepted, bool keyboards_intercepted, bool mice_intercepted) { - g_intercepted = intercepted; + g_pads_intercepted = pads_intercepted; + g_keyboards_intercepted = keyboards_intercepted; + g_mice_intercepted = mice_intercepted; - pad::SetIntercepted(intercepted); + pad::SetIntercepted(pads_intercepted); if (const auto handler = g_fxo->try_get()) { - handler->SetIntercepted(intercepted); + handler->SetIntercepted(keyboards_intercepted); } if (const auto handler = g_fxo->try_get()) { - handler->SetIntercepted(intercepted); + handler->SetIntercepted(mice_intercepted); } } + + void SetIntercepted(bool all_intercepted) + { + SetIntercepted(all_intercepted, all_intercepted, all_intercepted); + } } diff --git a/rpcs3/Emu/Io/interception.h b/rpcs3/Emu/Io/interception.h index 72a88308de..8e07f7f7ab 100644 --- a/rpcs3/Emu/Io/interception.h +++ b/rpcs3/Emu/Io/interception.h @@ -4,7 +4,10 @@ namespace input { - extern atomic_t g_intercepted; + extern atomic_t g_pads_intercepted; + extern atomic_t g_keyboards_intercepted; + extern atomic_t g_mice_intercepted; - void SetIntercepted(bool intercepted); + void SetIntercepted(bool pads_intercepted, bool keyboards_intercepted, bool mice_intercepted); + void SetIntercepted(bool all_intercepted); } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp index fb4d248acb..4bc49d430b 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp @@ -393,6 +393,9 @@ namespace rsx void osk_dialog::on_button_pressed(pad_button button_press) { + if (!pad_input_enabled || ignore_input_events) + return; + const auto index_limit = (num_columns * num_rows) - 1; const auto on_accept = [this]() @@ -588,7 +591,7 @@ namespace rsx void osk_dialog::on_key_pressed(u32 led, u32 mkey, u32 key_code, u32 out_key_code, bool pressed) { - if (!pressed) + if (!pressed || !keyboard_input_enabled || ignore_input_events) return; osk.notice("osk_dialog::on_key_pressed(led=%d, mkey=%d, key_code=%d, out_key_code=%d, pressed=%d)", led, mkey, key_code, out_key_code, pressed); diff --git a/rpcs3/Emu/RSX/Overlays/overlays.h b/rpcs3/Emu/RSX/Overlays/overlays.h index 4f457a480a..d699eee79a 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.h +++ b/rpcs3/Emu/RSX/Overlays/overlays.h @@ -112,7 +112,7 @@ namespace rsx compiled_resource get_compiled() override = 0; virtual void on_button_pressed(pad_button /*button_press*/) {} - virtual void on_key_pressed(u32 led, u32 mkey, u32 key_code, u32 out_key_code, bool pressed) {} + virtual void on_key_pressed(u32 /*led*/, u32 /*mkey*/, u32 /*key_code*/, u32 /*out_key_code*/, bool /*pressed*/) {} virtual void close(bool use_callback, bool stop_pad_interception); diff --git a/rpcs3/Input/basic_keyboard_handler.cpp b/rpcs3/Input/basic_keyboard_handler.cpp index e7e2eb9ee4..98de1e0854 100644 --- a/rpcs3/Input/basic_keyboard_handler.cpp +++ b/rpcs3/Input/basic_keyboard_handler.cpp @@ -26,7 +26,7 @@ void basic_keyboard_handler::Init(const u32 max_connect) memset(&m_info, 0, sizeof(KbInfo)); m_info.max_connect = max_connect; m_info.now_connect = std::min(::size32(m_keyboards), max_connect); - m_info.info = input::g_intercepted ? CELL_KB_INFO_INTERCEPTED : 0; // Ownership of keyboard data: 0=Application, 1=System + m_info.info = input::g_keyboards_intercepted ? CELL_KB_INFO_INTERCEPTED : 0; // Ownership of keyboard data: 0=Application, 1=System m_info.status[0] = CELL_KB_STATUS_CONNECTED; // (TODO: Support for more keyboards) } @@ -53,7 +53,7 @@ void basic_keyboard_handler::SetTargetWindow(QWindow* target) bool basic_keyboard_handler::eventFilter(QObject* watched, QEvent* event) { - if (!event || input::g_intercepted) + if (!event || input::g_keyboards_intercepted) { return false; } diff --git a/rpcs3/Input/basic_mouse_handler.cpp b/rpcs3/Input/basic_mouse_handler.cpp index 17900bf8b5..1535e0fb74 100644 --- a/rpcs3/Input/basic_mouse_handler.cpp +++ b/rpcs3/Input/basic_mouse_handler.cpp @@ -16,7 +16,7 @@ void basic_mouse_handler::Init(const u32 max_connect) memset(&m_info, 0, sizeof(MouseInfo)); m_info.max_connect = max_connect; m_info.now_connect = std::min(::size32(m_mice), max_connect); - m_info.info = input::g_intercepted ? CELL_MOUSE_INFO_INTERCEPTED : 0; // Ownership of mouse data: 0=Application, 1=System + m_info.info = input::g_mice_intercepted ? CELL_MOUSE_INFO_INTERCEPTED : 0; // Ownership of mouse data: 0=Application, 1=System for (u32 i = 1; i < max_connect; i++) { m_info.status[i] = CELL_MOUSE_STATUS_DISCONNECTED; @@ -50,7 +50,7 @@ void basic_mouse_handler::SetTargetWindow(QWindow* target) bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev) { - if (!ev || input::g_intercepted) + if (!ev || input::g_mice_intercepted) { return false; }