2020-12-05 13:08:24 +01:00
|
|
|
|
#include "stdafx.h"
|
2016-03-21 20:43:03 +01:00
|
|
|
|
#include "Emu/IdManager.h"
|
|
|
|
|
|
#include "Emu/Cell/PPUModule.h"
|
2014-08-23 22:40:04 +02:00
|
|
|
|
|
2016-03-21 20:43:03 +01:00
|
|
|
|
#include "Emu/Io/KeyboardHandler.h"
|
2014-09-03 18:33:30 +02:00
|
|
|
|
#include "cellKb.h"
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
2020-09-26 09:08:12 +02:00
|
|
|
|
extern void libio_sys_config_init();
|
|
|
|
|
|
extern void libio_sys_config_end();
|
|
|
|
|
|
|
2020-01-31 10:01:17 +01:00
|
|
|
|
LOG_CHANNEL(sys_io);
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
2017-05-15 13:30:14 +02:00
|
|
|
|
template<>
|
|
|
|
|
|
void fmt_class_string<CellKbError>::format(std::string& out, u64 arg)
|
|
|
|
|
|
{
|
|
|
|
|
|
format_enum(out, arg, [](auto error)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (error)
|
|
|
|
|
|
{
|
|
|
|
|
|
STR_CASE(CELL_KB_ERROR_FATAL);
|
|
|
|
|
|
STR_CASE(CELL_KB_ERROR_INVALID_PARAMETER);
|
|
|
|
|
|
STR_CASE(CELL_KB_ERROR_ALREADY_INITIALIZED);
|
|
|
|
|
|
STR_CASE(CELL_KB_ERROR_UNINITIALIZED);
|
|
|
|
|
|
STR_CASE(CELL_KB_ERROR_RESOURCE_ALLOCATION_FAILED);
|
|
|
|
|
|
STR_CASE(CELL_KB_ERROR_READ_FAILED);
|
|
|
|
|
|
STR_CASE(CELL_KB_ERROR_NO_DEVICE);
|
|
|
|
|
|
STR_CASE(CELL_KB_ERROR_SYS_SETTING_FAILED);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return unknown;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
error_code cellKbInit(u32 max_connect)
|
2013-09-11 22:49:49 +02:00
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
|
sys_io.warning("cellKbInit(max_connect=%d)", max_connect);
|
2015-01-26 20:01:47 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto handler = g_fxo->get<KeyboardHandlerBase>();
|
2016-03-21 20:43:03 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto init = handler->init.init();
|
|
|
|
|
|
|
|
|
|
|
|
if (!init)
|
2016-03-21 20:43:03 +01:00
|
|
|
|
return CELL_KB_ERROR_ALREADY_INITIALIZED;
|
|
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
if (max_connect == 0 || max_connect > CELL_KB_MAX_KEYBOARDS)
|
|
|
|
|
|
return CELL_KB_ERROR_INVALID_PARAMETER;
|
|
|
|
|
|
|
2020-09-26 09:08:12 +02:00
|
|
|
|
libio_sys_config_init();
|
2017-06-03 04:42:34 +02:00
|
|
|
|
handler->Init(std::min(max_connect, 7u));
|
2015-01-26 20:01:47 +01:00
|
|
|
|
|
2013-09-11 22:49:49 +02:00
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-15 13:30:14 +02:00
|
|
|
|
error_code cellKbEnd()
|
2013-09-11 22:49:49 +02:00
|
|
|
|
{
|
2016-03-21 20:43:03 +01:00
|
|
|
|
sys_io.notice("cellKbEnd()");
|
2015-01-26 20:01:47 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto handler = g_fxo->get<KeyboardHandlerBase>();
|
|
|
|
|
|
|
|
|
|
|
|
const auto init = handler->init.reset();
|
|
|
|
|
|
|
|
|
|
|
|
if (!init)
|
2015-01-26 20:01:47 +01:00
|
|
|
|
return CELL_KB_ERROR_UNINITIALIZED;
|
|
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
// TODO
|
2020-09-26 09:08:12 +02:00
|
|
|
|
libio_sys_config_end();
|
2013-09-11 22:49:49 +02:00
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-15 13:30:14 +02:00
|
|
|
|
error_code cellKbClearBuf(u32 port_no)
|
2013-09-11 22:49:49 +02:00
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
|
sys_io.trace("cellKbClearBuf(port_no=%d)", port_no);
|
2015-01-26 20:01:47 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto handler = g_fxo->get<KeyboardHandlerBase>();
|
2016-03-21 20:43:03 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto init = handler->init.access();
|
|
|
|
|
|
|
|
|
|
|
|
if (!init)
|
2015-01-26 20:01:47 +01:00
|
|
|
|
return CELL_KB_ERROR_UNINITIALIZED;
|
|
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
if (port_no >= CELL_KB_MAX_KEYBOARDS)
|
2015-01-26 20:01:47 +01:00
|
|
|
|
return CELL_KB_ERROR_INVALID_PARAMETER;
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
2018-07-17 01:23:14 +02:00
|
|
|
|
std::lock_guard<std::mutex> lock(handler->m_mutex);
|
|
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
const KbInfo& current_info = handler->GetInfo();
|
|
|
|
|
|
|
|
|
|
|
|
if (port_no >= handler->GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
|
|
|
|
|
|
return CELL_KB_ERROR_NO_DEVICE;
|
|
|
|
|
|
|
|
|
|
|
|
KbData& current_data = handler->GetData(port_no);
|
|
|
|
|
|
current_data.len = 0;
|
|
|
|
|
|
current_data.led = 0;
|
|
|
|
|
|
current_data.mkey = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < CELL_KB_MAX_KEYCODES; i++)
|
|
|
|
|
|
{
|
2018-07-17 01:23:14 +02:00
|
|
|
|
current_data.keycode[i] = { 0, 0 };
|
2018-07-24 21:58:30 +02:00
|
|
|
|
}
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode)
|
|
|
|
|
|
{
|
2019-08-17 16:21:37 +02:00
|
|
|
|
sys_io.trace("cellKbCnvRawCode(arrange=%d, mkey=%d, led=%d, rawcode=0x%x)", arrange, mkey, led, rawcode);
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
|
|
|
|
|
// CELL_KB_RAWDAT
|
2015-01-26 20:01:47 +01:00
|
|
|
|
if (rawcode <= 0x03 || rawcode == 0x29 || rawcode == 0x35 || (rawcode >= 0x39 && rawcode <= 0x53) || rawcode == 0x65 || rawcode == 0x88 || rawcode == 0x8A || rawcode == 0x8B)
|
|
|
|
|
|
{
|
|
|
|
|
|
return rawcode | 0x8000;
|
|
|
|
|
|
}
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
2019-08-17 16:21:37 +02:00
|
|
|
|
const bool is_alt = mkey & (CELL_KB_MKEY_L_ALT | CELL_KB_MKEY_R_ALT);
|
|
|
|
|
|
const bool is_shift = mkey & (CELL_KB_MKEY_L_SHIFT | CELL_KB_MKEY_R_SHIFT);
|
|
|
|
|
|
const bool is_caps_lock = led & (CELL_KB_LED_CAPS_LOCK);
|
|
|
|
|
|
const bool is_num_lock = led & (CELL_KB_LED_NUM_LOCK);
|
|
|
|
|
|
|
2013-09-11 22:49:49 +02:00
|
|
|
|
// CELL_KB_NUMPAD
|
|
|
|
|
|
|
2019-08-17 16:21:37 +02:00
|
|
|
|
if (is_num_lock)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (rawcode == CELL_KEYC_KPAD_NUMLOCK) return 0x00 | 0x4000; // 'Num Lock'
|
|
|
|
|
|
if (rawcode == CELL_KEYC_KPAD_SLASH) return 0x2F | 0x4000; // '/'
|
|
|
|
|
|
if (rawcode == CELL_KEYC_KPAD_ASTERISK) return 0x2A | 0x4000; // '*'
|
|
|
|
|
|
if (rawcode == CELL_KEYC_KPAD_MINUS) return 0x2D | 0x4000; // '-'
|
|
|
|
|
|
if (rawcode == CELL_KEYC_KPAD_PLUS) return 0x2B | 0x4000; // '+'
|
|
|
|
|
|
if (rawcode == CELL_KEYC_KPAD_ENTER) return 0x0A | 0x4000; // '\n'
|
|
|
|
|
|
if (rawcode == CELL_KEYC_KPAD_0) return 0x30 | 0x4000; // '0'
|
|
|
|
|
|
if (rawcode >= CELL_KEYC_KPAD_1 && rawcode <= CELL_KEYC_KPAD_9) return (rawcode - 0x28) | 0x4000; // '1' - '9'
|
|
|
|
|
|
}
|
2018-07-17 01:23:14 +02:00
|
|
|
|
|
2019-08-17 16:21:37 +02:00
|
|
|
|
// ASCII
|
2018-07-17 01:23:14 +02:00
|
|
|
|
|
2019-08-17 16:21:37 +02:00
|
|
|
|
const auto get_ascii = [is_alt, is_shift, is_caps_lock](u16 raw, u16 shifted = 0, u16 altered = 0)
|
2018-07-17 01:23:14 +02:00
|
|
|
|
{
|
2019-08-17 16:21:37 +02:00
|
|
|
|
if ((is_shift || is_caps_lock) && shifted)
|
|
|
|
|
|
{
|
|
|
|
|
|
return shifted;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (is_alt && altered)
|
|
|
|
|
|
{
|
|
|
|
|
|
return altered;
|
|
|
|
|
|
}
|
|
|
|
|
|
return raw;
|
2018-07-17 01:23:14 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (arrange == CELL_KB_MAPPING_106) // (Japanese)
|
|
|
|
|
|
{
|
2019-08-17 16:21:37 +02:00
|
|
|
|
if (rawcode == CELL_KEYC_1) return get_ascii('1', '!');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_2) return get_ascii('2', '"');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_3) return get_ascii('3', '#');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_4) return get_ascii('4', '$');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_5) return get_ascii('5', '%');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_6) return get_ascii('6', '&');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_7) return get_ascii('7', '\'');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_8) return get_ascii('8', '(');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_9) return get_ascii('9', ')');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_0) return get_ascii('0', '~');
|
|
|
|
|
|
|
|
|
|
|
|
if (rawcode == CELL_KEYC_ACCENT_CIRCONFLEX_106) return get_ascii('^', '~');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_ATMARK_106) return get_ascii('@', '`');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_LEFT_BRACKET_106) return get_ascii('[', '{');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_RIGHT_BRACKET_106) return get_ascii(']', '}');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_SEMICOLON) return get_ascii(';', '+');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_COLON_106) return get_ascii(':', '*');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_COMMA) return get_ascii(',', '<');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_PERIOD) return get_ascii('.', '>');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_SLASH) return get_ascii('/', '?');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_BACKSLASH_106) return get_ascii('\\', '_');
|
2019-08-17 21:28:01 +02:00
|
|
|
|
if (rawcode == CELL_KEYC_YEN_106) return get_ascii(190, '|'); // ¥
|
2018-07-17 01:23:14 +02:00
|
|
|
|
}
|
|
|
|
|
|
else if (arrange == CELL_KB_MAPPING_101) // (US)
|
|
|
|
|
|
{
|
2019-08-17 16:21:37 +02:00
|
|
|
|
if (rawcode == CELL_KEYC_1) return get_ascii('1', '!');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_2) return get_ascii('2', '@');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_3) return get_ascii('3', '#');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_4) return get_ascii('4', '$');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_5) return get_ascii('5', '%');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_6) return get_ascii('6', '^');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_7) return get_ascii('7', '&');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_8) return get_ascii('8', '*');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_9) return get_ascii('9', '(');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_0) return get_ascii('0', ')');
|
|
|
|
|
|
|
|
|
|
|
|
if (rawcode == CELL_KEYC_MINUS) return get_ascii('-', '_');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_EQUAL_101) return get_ascii('=', '+');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_LEFT_BRACKET_101) return get_ascii('[', '{');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_RIGHT_BRACKET_101) return get_ascii(']', '}');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_BACKSLASH_101) return get_ascii('\\', '|');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_SEMICOLON) return get_ascii(';', ':');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_QUOTATION_101) return get_ascii('\'', '"');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_COMMA) return get_ascii(',', '<');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_PERIOD) return get_ascii('.', '>');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_SLASH) return get_ascii('/', '?');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_BACK_QUOTE) return get_ascii('`', '~');
|
2018-07-17 01:23:14 +02:00
|
|
|
|
}
|
|
|
|
|
|
else if (arrange == CELL_KB_MAPPING_GERMAN_GERMANY)
|
|
|
|
|
|
{
|
2019-08-17 16:21:37 +02:00
|
|
|
|
if (rawcode == CELL_KEYC_1) return get_ascii('1', '!');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_2) return get_ascii('2', '"');
|
2019-08-17 21:28:01 +02:00
|
|
|
|
if (rawcode == CELL_KEYC_3) return get_ascii('3', 245); // §
|
2019-08-17 16:21:37 +02:00
|
|
|
|
if (rawcode == CELL_KEYC_4) return get_ascii('4', '$');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_5) return get_ascii('5', '%');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_6) return get_ascii('6', '&');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_7) return get_ascii('7', '/', '{');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_8) return get_ascii('8', '(', '[');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_9) return get_ascii('9', ')', ']');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_0) return get_ascii('0', '=', '}');
|
|
|
|
|
|
|
|
|
|
|
|
if (rawcode == CELL_KEYC_MINUS) return get_ascii('-', '_');
|
2019-08-17 21:28:01 +02:00
|
|
|
|
if (rawcode == CELL_KEYC_ACCENT_CIRCONFLEX_106) return get_ascii('^', 248); // °
|
2019-08-17 16:21:37 +02:00
|
|
|
|
if (rawcode == CELL_KEYC_COMMA) return get_ascii(',', ';');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_PERIOD) return get_ascii('.', ':');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_KPAD_PLUS) return get_ascii('+', '*', '~');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_LESS) return get_ascii('<', '>', '|');
|
|
|
|
|
|
if (rawcode == CELL_KEYC_HASHTAG) return get_ascii('#', '\'');
|
2019-08-17 21:28:01 +02:00
|
|
|
|
if (rawcode == CELL_KEYC_SSHARP) return get_ascii(225, '?', '\\'); // ß
|
|
|
|
|
|
if (rawcode == CELL_KEYC_BACK_QUOTE) return get_ascii(239, '`'); // ´
|
2019-08-17 16:21:37 +02:00
|
|
|
|
if (rawcode == CELL_KEYC_Q) return get_ascii('q', 'Q', '@');
|
2018-07-17 01:23:14 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2014-04-04 15:25:38 +02:00
|
|
|
|
if (rawcode >= 0x04 && rawcode <= 0x1D) // 'A' - 'Z'
|
2013-09-13 19:29:54 +02:00
|
|
|
|
{
|
2018-02-09 15:49:37 +01:00
|
|
|
|
rawcode -=
|
2018-07-17 01:23:14 +02:00
|
|
|
|
(is_shift)
|
|
|
|
|
|
? ((led & (CELL_KB_LED_CAPS_LOCK)) ? 0 : 0x20)
|
|
|
|
|
|
: ((led & (CELL_KB_LED_CAPS_LOCK)) ? 0x20 : 0);
|
2013-09-13 19:29:54 +02:00
|
|
|
|
return rawcode + 0x5D;
|
2017-12-31 12:01:11 +01:00
|
|
|
|
}
|
2014-04-04 15:25:38 +02:00
|
|
|
|
if (rawcode >= 0x1E && rawcode <= 0x26) return rawcode + 0x13; // '1' - '9'
|
|
|
|
|
|
if (rawcode == 0x27) return 0x30; // '0'
|
|
|
|
|
|
if (rawcode == 0x28) return 0x0A; // '\n'
|
2018-07-17 01:23:14 +02:00
|
|
|
|
if (rawcode == 0x29) return 0x1B; // 'ESC'
|
|
|
|
|
|
if (rawcode == 0x2A) return 0x08; // '\b'
|
2014-04-04 15:25:38 +02:00
|
|
|
|
if (rawcode == 0x2B) return 0x09; // '\t'
|
2018-07-17 01:23:14 +02:00
|
|
|
|
if (rawcode == 0x2C) return 0x20; // 'space'
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
2019-08-17 16:21:37 +02:00
|
|
|
|
// TODO: Add more keys and layouts
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
|
|
|
|
|
return 0x0000;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-15 13:30:14 +02:00
|
|
|
|
error_code cellKbGetInfo(vm::ptr<CellKbInfo> info)
|
2013-09-11 22:49:49 +02:00
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
|
sys_io.trace("cellKbGetInfo(info=*0x%x)", info);
|
2015-01-26 20:01:47 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto handler = g_fxo->get<KeyboardHandlerBase>();
|
|
|
|
|
|
|
|
|
|
|
|
const auto init = handler->init.access();
|
2016-03-21 20:43:03 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
if (!init)
|
2015-01-26 20:01:47 +01:00
|
|
|
|
return CELL_KB_ERROR_UNINITIALIZED;
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
if (!info)
|
|
|
|
|
|
return CELL_KB_ERROR_INVALID_PARAMETER;
|
|
|
|
|
|
|
2019-12-20 04:51:16 +01:00
|
|
|
|
std::memset(info.get_ptr(), 0, info.size());
|
|
|
|
|
|
|
2018-07-17 01:23:14 +02:00
|
|
|
|
std::lock_guard<std::mutex> lock(handler->m_mutex);
|
|
|
|
|
|
|
2016-03-21 20:43:03 +01:00
|
|
|
|
const KbInfo& current_info = handler->GetInfo();
|
2014-08-28 03:18:35 +02:00
|
|
|
|
info->max_connect = current_info.max_connect;
|
|
|
|
|
|
info->now_connect = current_info.now_connect;
|
|
|
|
|
|
info->info = current_info.info;
|
2015-01-26 20:01:47 +01:00
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
for (u32 i = 0; i < CELL_KB_MAX_KEYBOARDS; i++)
|
2013-09-11 22:49:49 +02:00
|
|
|
|
{
|
2014-08-28 03:18:35 +02:00
|
|
|
|
info->status[i] = current_info.status[i];
|
2013-09-11 22:49:49 +02:00
|
|
|
|
}
|
2017-12-31 12:01:11 +01:00
|
|
|
|
|
2013-09-11 22:49:49 +02:00
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-15 13:30:14 +02:00
|
|
|
|
error_code cellKbRead(u32 port_no, vm::ptr<CellKbData> data)
|
2013-09-11 22:49:49 +02:00
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
|
sys_io.trace("cellKbRead(port_no=%d, data=*0x%x)", port_no, data);
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto handler = g_fxo->get<KeyboardHandlerBase>();
|
2016-03-21 20:43:03 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto init = handler->init.access();
|
|
|
|
|
|
|
|
|
|
|
|
if (!init)
|
2015-01-26 20:01:47 +01:00
|
|
|
|
return CELL_KB_ERROR_UNINITIALIZED;
|
|
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
if (port_no >= CELL_KB_MAX_KEYBOARDS || !data)
|
2015-01-26 20:01:47 +01:00
|
|
|
|
return CELL_KB_ERROR_INVALID_PARAMETER;
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
2018-07-17 01:23:14 +02:00
|
|
|
|
std::lock_guard<std::mutex> lock(handler->m_mutex);
|
|
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
const KbInfo& current_info = handler->GetInfo();
|
|
|
|
|
|
|
|
|
|
|
|
if (port_no >= handler->GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
|
|
|
|
|
|
return CELL_KB_ERROR_NO_DEVICE;
|
|
|
|
|
|
|
2016-03-21 20:43:03 +01:00
|
|
|
|
KbData& current_data = handler->GetData(port_no);
|
2014-08-28 03:18:35 +02:00
|
|
|
|
data->led = current_data.led;
|
|
|
|
|
|
data->mkey = current_data.mkey;
|
2019-12-01 18:14:58 +01:00
|
|
|
|
data->len = std::min<s32>(CELL_KB_MAX_KEYCODES, current_data.len);
|
2015-01-26 20:01:47 +01:00
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
for (s32 i = 0; i < current_data.len; i++)
|
2013-09-11 22:49:49 +02:00
|
|
|
|
{
|
2018-07-17 01:23:14 +02:00
|
|
|
|
data->keycode[i] = current_data.keycode[i].first;
|
2013-09-11 22:49:49 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-15 13:30:14 +02:00
|
|
|
|
error_code cellKbSetCodeType(u32 port_no, u32 type)
|
2013-09-11 22:49:49 +02:00
|
|
|
|
{
|
2017-05-15 13:30:14 +02:00
|
|
|
|
sys_io.trace("cellKbSetCodeType(port_no=%d, type=%d)", port_no, type);
|
2015-01-26 20:01:47 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto handler = g_fxo->get<KeyboardHandlerBase>();
|
|
|
|
|
|
|
|
|
|
|
|
const auto init = handler->init.access();
|
2016-03-21 20:43:03 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
if (!init)
|
2015-01-26 20:01:47 +01:00
|
|
|
|
return CELL_KB_ERROR_UNINITIALIZED;
|
2017-10-01 03:00:56 +02:00
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
if (port_no >= CELL_KB_MAX_KEYBOARDS || type > CELL_KB_CODETYPE_ASCII)
|
2017-10-01 03:00:56 +02:00
|
|
|
|
return CELL_KB_ERROR_INVALID_PARAMETER;
|
2017-12-31 12:01:11 +01:00
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
if (port_no >= handler->GetKeyboards().size())
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
|
2018-07-17 01:23:14 +02:00
|
|
|
|
std::lock_guard<std::mutex> lock(handler->m_mutex);
|
|
|
|
|
|
|
2016-03-21 20:43:03 +01:00
|
|
|
|
KbConfig& current_config = handler->GetConfig(port_no);
|
2013-09-11 22:49:49 +02:00
|
|
|
|
current_config.code_type = type;
|
2018-07-24 21:58:30 +02:00
|
|
|
|
|
|
|
|
|
|
// can also return CELL_KB_ERROR_SYS_SETTING_FAILED
|
|
|
|
|
|
|
2013-09-11 22:49:49 +02:00
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-15 13:30:14 +02:00
|
|
|
|
error_code cellKbSetLEDStatus(u32 port_no, u8 led)
|
2013-09-11 22:49:49 +02:00
|
|
|
|
{
|
2018-07-24 21:58:30 +02:00
|
|
|
|
sys_io.trace("cellKbSetLEDStatus(port_no=%d, led=%d)", port_no, led);
|
|
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto handler = g_fxo->get<KeyboardHandlerBase>();
|
|
|
|
|
|
|
|
|
|
|
|
const auto init = handler->init.access();
|
2018-07-24 21:58:30 +02:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
if (!init)
|
2018-07-24 21:58:30 +02:00
|
|
|
|
return CELL_KB_ERROR_UNINITIALIZED;
|
|
|
|
|
|
|
|
|
|
|
|
if (port_no >= CELL_KB_MAX_KEYBOARDS)
|
|
|
|
|
|
return CELL_KB_ERROR_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
|
|
|
|
if (led > 7)
|
|
|
|
|
|
return CELL_KB_ERROR_SYS_SETTING_FAILED;
|
|
|
|
|
|
|
|
|
|
|
|
if (port_no >= handler->GetKeyboards().size() || handler->GetInfo().status[port_no] != CELL_KB_STATUS_CONNECTED)
|
|
|
|
|
|
return CELL_KB_ERROR_FATAL;
|
|
|
|
|
|
|
2018-07-17 01:23:14 +02:00
|
|
|
|
std::lock_guard<std::mutex> lock(handler->m_mutex);
|
|
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
KbData& current_data = handler->GetData(port_no);
|
|
|
|
|
|
current_data.led = static_cast<u32>(led);
|
|
|
|
|
|
|
2013-09-11 22:49:49 +02:00
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-15 13:30:14 +02:00
|
|
|
|
error_code cellKbSetReadMode(u32 port_no, u32 rmode)
|
2013-09-11 22:49:49 +02:00
|
|
|
|
{
|
2017-05-15 13:30:14 +02:00
|
|
|
|
sys_io.trace("cellKbSetReadMode(port_no=%d, rmode=%d)", port_no, rmode);
|
2015-01-26 20:01:47 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto handler = g_fxo->get<KeyboardHandlerBase>();
|
2016-03-21 20:43:03 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto init = handler->init.access();
|
|
|
|
|
|
|
|
|
|
|
|
if (!init)
|
2015-01-26 20:01:47 +01:00
|
|
|
|
return CELL_KB_ERROR_UNINITIALIZED;
|
2017-10-01 03:00:56 +02:00
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
if (port_no >= CELL_KB_MAX_KEYBOARDS || rmode > CELL_KB_RMODE_PACKET)
|
2017-10-01 03:00:56 +02:00
|
|
|
|
return CELL_KB_ERROR_INVALID_PARAMETER;
|
2017-12-31 12:01:11 +01:00
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
if (port_no >= handler->GetKeyboards().size())
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
|
2018-07-17 01:23:14 +02:00
|
|
|
|
std::lock_guard<std::mutex> lock(handler->m_mutex);
|
|
|
|
|
|
|
2016-03-21 20:43:03 +01:00
|
|
|
|
KbConfig& current_config = handler->GetConfig(port_no);
|
2013-09-11 22:49:49 +02:00
|
|
|
|
current_config.read_mode = rmode;
|
|
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
// can also return CELL_KB_ERROR_SYS_SETTING_FAILED
|
|
|
|
|
|
|
2013-09-11 22:49:49 +02:00
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-15 13:30:14 +02:00
|
|
|
|
error_code cellKbGetConfiguration(u32 port_no, vm::ptr<CellKbConfig> config)
|
2013-09-11 22:49:49 +02:00
|
|
|
|
{
|
2016-01-12 22:57:16 +01:00
|
|
|
|
sys_io.trace("cellKbGetConfiguration(port_no=%d, config=*0x%x)", port_no, config);
|
2015-01-26 20:01:47 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
const auto handler = g_fxo->get<KeyboardHandlerBase>();
|
|
|
|
|
|
|
|
|
|
|
|
const auto init = handler->init.access();
|
2016-03-21 20:43:03 +01:00
|
|
|
|
|
2019-09-19 00:50:08 +02:00
|
|
|
|
if (!init)
|
2015-01-26 20:01:47 +01:00
|
|
|
|
return CELL_KB_ERROR_UNINITIALIZED;
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
if (port_no >= CELL_KB_MAX_KEYBOARDS)
|
|
|
|
|
|
return CELL_KB_ERROR_INVALID_PARAMETER;
|
|
|
|
|
|
|
2018-07-17 01:23:14 +02:00
|
|
|
|
std::lock_guard<std::mutex> lock(handler->m_mutex);
|
|
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
const KbInfo& current_info = handler->GetInfo();
|
|
|
|
|
|
|
|
|
|
|
|
if (port_no >= handler->GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
|
|
|
|
|
|
return CELL_KB_ERROR_NO_DEVICE;
|
|
|
|
|
|
|
|
|
|
|
|
// tests show that config is checked only after the device's status
|
|
|
|
|
|
if (!config)
|
2017-10-01 03:00:56 +02:00
|
|
|
|
return CELL_KB_ERROR_INVALID_PARAMETER;
|
|
|
|
|
|
|
2016-03-21 20:43:03 +01:00
|
|
|
|
const KbConfig& current_config = handler->GetConfig(port_no);
|
2014-08-28 03:18:35 +02:00
|
|
|
|
config->arrange = current_config.arrange;
|
|
|
|
|
|
config->read_mode = current_config.read_mode;
|
|
|
|
|
|
config->code_type = current_config.code_type;
|
2013-09-11 22:49:49 +02:00
|
|
|
|
|
2018-07-24 21:58:30 +02:00
|
|
|
|
// can also return CELL_KB_ERROR_SYS_SETTING_FAILED
|
|
|
|
|
|
|
2013-09-11 22:49:49 +02:00
|
|
|
|
return CELL_OK;
|
|
|
|
|
|
}
|
2014-09-03 18:33:30 +02:00
|
|
|
|
|
|
|
|
|
|
void cellKb_init()
|
|
|
|
|
|
{
|
2015-02-20 14:58:40 +01:00
|
|
|
|
REG_FUNC(sys_io, cellKbInit);
|
|
|
|
|
|
REG_FUNC(sys_io, cellKbEnd);
|
|
|
|
|
|
REG_FUNC(sys_io, cellKbClearBuf);
|
|
|
|
|
|
REG_FUNC(sys_io, cellKbCnvRawCode);
|
|
|
|
|
|
REG_FUNC(sys_io, cellKbGetInfo);
|
|
|
|
|
|
REG_FUNC(sys_io, cellKbRead);
|
|
|
|
|
|
REG_FUNC(sys_io, cellKbSetCodeType);
|
|
|
|
|
|
REG_FUNC(sys_io, cellKbSetLEDStatus);
|
|
|
|
|
|
REG_FUNC(sys_io, cellKbSetReadMode);
|
|
|
|
|
|
REG_FUNC(sys_io, cellKbGetConfiguration);
|
2014-09-03 18:33:30 +02:00
|
|
|
|
}
|