OSK: allow device input during interception

This commit is contained in:
Megamouse 2022-04-19 22:30:20 +02:00
parent 9adab801ac
commit 0ff293707a
11 changed files with 89 additions and 93 deletions

View File

@ -304,9 +304,19 @@ error_code cellKbRead(u32 port_no, vm::ptr<CellKbData> data)
return CELL_KB_ERROR_NO_DEVICE;
KbData& current_data = handler.GetData(port_no);
if (current_info.is_null_handler || (current_info.info & CELL_KB_INFO_INTERCEPTED))
{
data->led = 0;
data->mkey = 0;
data->len = 0;
}
else
{
data->led = current_data.led;
data->mkey = current_data.mkey;
data->len = std::min<s32>(CELL_KB_MAX_KEYCODES, current_data.len);
}
if (current_data.len > 0)
{

View File

@ -209,8 +209,9 @@ error_code cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
MouseDataList& data_list = handler.GetDataList(port_no);
if (data_list.empty())
if (data_list.empty() || current_info.is_null_handler || (current_info.info & CELL_MOUSE_INFO_INTERCEPTED))
{
data_list.clear();
return CELL_OK;
}
@ -252,9 +253,18 @@ error_code cellMouseGetDataList(u32 port_no, vm::ptr<CellMouseDataList> data)
return CELL_MOUSE_ERROR_NO_DEVICE;
}
std::memset(data.get_ptr(), 0, data.size());
// TODO: check if (current_info.mode[port_no] != CELL_MOUSE_INFO_TABLET_MOUSE_MODE) has any impact
auto& list = handler.GetDataList(port_no);
if (list.empty() || current_info.is_null_handler || (current_info.info & CELL_MOUSE_INFO_INTERCEPTED))
{
list.clear();
return CELL_OK;
}
data->list_num = std::min<u32>(CELL_MOUSE_MAX_DATA_LIST_NUM, static_cast<u32>(list.size()));
int i = 0;
@ -332,10 +342,19 @@ error_code cellMouseGetTabletDataList(u32 port_no, vm::ptr<CellMouseTabletDataLi
return CELL_MOUSE_ERROR_NO_DEVICE;
}
std::memset(data.get_ptr(), 0, data.size());
// TODO: decr tests show that CELL_MOUSE_ERROR_DATA_READ_FAILED is returned when a mouse is connected
// TODO: check if (current_info.mode[port_no] != CELL_MOUSE_INFO_TABLET_TABLET_MODE) has any impact
auto& list = handler.GetTabletDataList(port_no);
if (list.empty() || current_info.is_null_handler || (current_info.info & CELL_MOUSE_INFO_INTERCEPTED))
{
list.clear();
return CELL_OK;
}
data->list_num = std::min<u32>(CELL_MOUSE_MAX_DATA_LIST_NUM, static_cast<u32>(list.size()));
int i = 0;
@ -351,6 +370,8 @@ error_code cellMouseGetTabletDataList(u32 port_no, vm::ptr<CellMouseTabletDataLi
}
}
list.clear();
return CELL_OK;
}
@ -377,10 +398,19 @@ error_code cellMouseGetRawData(u32 port_no, vm::ptr<CellMouseRawData> data)
return CELL_MOUSE_ERROR_NO_DEVICE;
}
std::memset(data.get_ptr(), 0, data.size());
// TODO: decr tests show that CELL_MOUSE_ERROR_DATA_READ_FAILED is returned when a mouse is connected
// TODO: check if (current_info.mode[port_no] != CELL_MOUSE_INFO_TABLET_MOUSE_MODE) has any impact
MouseRawData& current_data = handler.GetRawData(port_no);
if (current_info.is_null_handler || (current_info.info & CELL_MOUSE_INFO_INTERCEPTED))
{
current_data = {};
return CELL_OK;
}
data->len = current_data.len;
current_data.len = 0;

View File

@ -612,6 +612,7 @@ error_code cellOskDialogSetInitialInputDevice(u32 inputDevice)
g_fxo->get<osk_info>().initial_input_device = static_cast<CellOskDialogInputDevice>(inputDevice);
// TODO: use value
// TODO: Signal CELL_SYSUTIL_OSKDIALOG_INPUT_DEVICE_CHANGED if the input device changed (probably only when the dialog is already open)
return CELL_OK;
}

View File

@ -27,6 +27,7 @@ struct KbInfo
u32 max_connect = 0;
u32 now_connect = 0;
u32 info = 0;
bool is_null_handler = false;
std::array<u8, CELL_KB_MAX_KEYBOARDS> status{};
};
@ -47,31 +48,17 @@ struct KbButton
struct KbData
{
u32 led; // Active led lights
u32 mkey; // Active key modifiers
s32 len; // Number of key codes (0 means no data available)
u32 led = 0; // Active led lights TODO: Set initial state of led
u32 mkey = 0; // Active key modifiers
s32 len = 0; // Number of key codes (0 means no data available)
std::array<KbButton, CELL_KB_MAX_KEYCODES> buttons{};
KbData()
: led(0)
, mkey(0)
, len(0)
{ // (TODO: Set initial state of led)
}
};
struct KbConfig
{
u32 arrange;
u32 read_mode;
u32 code_type;
KbConfig()
: arrange(CELL_KB_MAPPING_101)
, read_mode(CELL_KB_RMODE_INPUTCHAR)
, code_type(CELL_KB_CODETYPE_ASCII)
{
}
u32 arrange = CELL_KB_MAPPING_101;
u32 read_mode = CELL_KB_RMODE_INPUTCHAR;
u32 code_type = CELL_KB_CODETYPE_ASCII;
};
struct Keyboard
@ -80,10 +67,6 @@ struct Keyboard
KbData m_data{};
KbConfig m_config{};
std::vector<KbButton> m_buttons;
Keyboard()
{
}
};
class KeyboardHandlerBase

View File

@ -54,58 +54,37 @@ static const u32 MOUSE_MAX_CODES = 64;
struct MouseInfo
{
u32 max_connect;
u32 now_connect;
u32 info;
u32 mode[MAX_MICE]; // TODO: tablet support
u32 tablet_is_supported[MAX_MICE]; // TODO: tablet support
u16 vendor_id[MAX_MICE];
u16 product_id[MAX_MICE];
u8 status[MAX_MICE];
u32 max_connect = 0;
u32 now_connect = 0;
u32 info = 0;
u32 mode[MAX_MICE]{}; // TODO: tablet support
u32 tablet_is_supported[MAX_MICE]{}; // TODO: tablet support
u16 vendor_id[MAX_MICE]{};
u16 product_id[MAX_MICE]{};
u8 status[MAX_MICE]{};
bool is_null_handler = false;
};
struct MouseRawData
{
s32 len;
u8 data[MOUSE_MAX_CODES];
MouseRawData()
: len(0)
, data()
{
}
s32 len = 0;
u8 data[MOUSE_MAX_CODES]{};
};
struct MouseData
{
u8 update;
u8 buttons;
s8 x_axis;
s8 y_axis;
s8 wheel;
s8 tilt; // (TODO)
MouseData()
: update(0)
, buttons(0)
, x_axis(0)
, y_axis(0)
, wheel(0)
, tilt(0)
{
}
u8 update = 0;
u8 buttons = 0;
s8 x_axis = 0;
s8 y_axis = 0;
s8 wheel = 0;
s8 tilt = 0; // (TODO)
};
struct MouseTabletData
{
s32 len;
u8 data[MOUSE_MAX_CODES];
MouseTabletData()
: len(0)
, data()
{
}
s32 len = 0;
u8 data[MOUSE_MAX_CODES]{};
};
using MouseTabletDataList = std::list<MouseTabletData>;
@ -113,32 +92,23 @@ using MouseDataList = std::list<MouseData>;
struct Mouse
{
s32 x_pos;
s32 y_pos;
s32 x_max;
s32 y_max;
u8 buttons; // actual mouse button positions
s32 x_pos = 0;
s32 y_pos = 0;
s32 x_max = 0;
s32 y_max = 0;
u8 buttons = 0; // actual mouse button positions
MouseTabletDataList m_tablet_datalist;
MouseDataList m_datalist;
MouseRawData m_rawdata;
Mouse()
: x_pos(0)
, y_pos(0)
, x_max(0)
, y_max(0)
, buttons(0)
{
}
MouseTabletDataList m_tablet_datalist{};
MouseDataList m_datalist{};
MouseRawData m_rawdata{};
};
class MouseHandlerBase
{
protected:
MouseInfo m_info;
MouseInfo m_info{};
std::vector<Mouse> m_mice;
steady_clock::time_point last_update;
steady_clock::time_point last_update{};
bool is_time_for_update(double elapsed_time = 10.0) // 4-10 ms, let's use 10 for now
{

View File

@ -9,6 +9,7 @@ public:
{
m_info = {};
m_info.max_connect = max_connect;
m_info.is_null_handler = true;
m_keyboards.clear();
for (u32 i = 0; i < max_connect; i++)
{

View File

@ -9,6 +9,7 @@ public:
{
m_info = {};
m_info.max_connect = max_connect;
m_info.is_null_handler = true;
m_mice.clear();
}
};

View File

@ -125,7 +125,7 @@ namespace rsx
continue;
// Get keyboard input
if (m_keyboard_input_enabled)
if (m_keyboard_input_enabled && input::g_keyboards_intercepted)
{
auto& handler = g_fxo->get<KeyboardHandlerBase>();
std::lock_guard<std::mutex> lock(handler.m_mutex);
@ -173,7 +173,7 @@ namespace rsx
const auto handler = pad::get_current_handler();
const PadInfo& rinfo = handler->GetInfo();
if (!rinfo.now_connect)
if (!rinfo.now_connect || !input::g_pads_intercepted)
{
refresh();
continue;

View File

@ -96,7 +96,7 @@ namespace rsx
atomic_t<bool> m_interactive = false;
atomic_t<bool> m_stop_pad_interception = false;
atomic_t<u64> thread_bits = 0;
bool m_keyboard_input_enabled = false;
bool m_keyboard_input_enabled = false; // Allow keyboard events
static thread_local u64 g_thread_bit;

View File

@ -15,7 +15,7 @@ void basic_keyboard_handler::Init(const u32 max_connect)
{
for (u32 i = 0; i < max_connect; i++)
{
Keyboard kb;
Keyboard kb{};
kb.m_config.arrange = g_cfg.sys.keyboard_type;
@ -53,7 +53,7 @@ void basic_keyboard_handler::SetTargetWindow(QWindow* target)
bool basic_keyboard_handler::eventFilter(QObject* watched, QEvent* event)
{
if (!event || input::g_keyboards_intercepted)
if (!event)
{
return false;
}

View File

@ -50,7 +50,7 @@ void basic_mouse_handler::SetTargetWindow(QWindow* target)
bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev)
{
if (!ev || input::g_mice_intercepted)
if (!ev)
{
return false;
}