feat(libSceIme): implement sceImeKeyboardGetResourceId
The resource id array is cleared and given the user. A null array returns INVALID_ADDRESS and an invalid user INVALID_USER_ID without writing it; a user whose keyboard is not open gets NOT_OPENED, and an open one gets CONNECTION_FAILED, as no USB keyboard is reported through the IME, as in shadPS4. The missing IME keyboard events are recorded in TechnicalDebt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
481c85e7c9
commit
54f0e03cde
|
|
@ -11,6 +11,7 @@
|
|||
namespace {
|
||||
|
||||
constexpr int ErrorNotOpened = static_cast<int>(0x80bc0002u);
|
||||
constexpr int ErrorConnectionFailed = static_cast<int>(0x80bc0004u);
|
||||
constexpr int ErrorInvalidUserId = static_cast<int>(0x80bc0010u);
|
||||
constexpr int ErrorInvalidType = static_cast<int>(0x80bc0011u);
|
||||
constexpr int ErrorInvalidOption = static_cast<int>(0x80bc0015u);
|
||||
|
|
@ -58,10 +59,12 @@ int APS5_VABI sceImeKeyboardGetInfo(uint32_t resource_id, KeyboardInfo* info) {
|
|||
}
|
||||
|
||||
int APS5_VABI sceImeKeyboardGetResourceId(int32_t user_id, KeyboardResourceIdArray* resource_ids) {
|
||||
(void)user_id;
|
||||
(void)resource_ids;
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
if (!resource_ids) return ErrorInvalidAddress;
|
||||
if (user_id == UserIdInvalid) return ErrorInvalidUserId;
|
||||
*resource_ids = {};
|
||||
resource_ids->user_id = user_id;
|
||||
std::lock_guard lock(g_keyboardMutex);
|
||||
return g_openKeyboards.contains(user_id) ? ErrorConnectionFailed : ErrorNotOpened;
|
||||
}
|
||||
|
||||
int APS5_VABI sceImeKeyboardOpen(int32_t user_id, const KeyboardParam* param) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ int APS5_VABI sceImeClose_nid_postfix(void);
|
|||
int APS5_VABI sceImeSetCaret(const Caret* caret);
|
||||
int APS5_VABI sceImeSetText(const char16_t* text, uint32_t length);
|
||||
int APS5_VABI sceImeSetTextGeometry(TextAreaMode mode, const TextGeometry* geometry);
|
||||
int APS5_VABI sceImeKeyboardOpen(int32_t user_id, const KeyboardParam* param);
|
||||
int APS5_VABI sceImeKeyboardClose(int32_t user_id);
|
||||
int APS5_VABI sceImeKeyboardGetResourceId(int32_t user_id, KeyboardResourceIdArray* resource_ids);
|
||||
}
|
||||
|
||||
static_assert(sizeof(Param) == 96);
|
||||
|
|
@ -118,9 +121,36 @@ static void CheckClosedPanel() {
|
|||
Require(sceImeClose_nid_postfix() == notOpened, "closing needs an open panel");
|
||||
}
|
||||
|
||||
static void CheckKeyboardResourceIds() {
|
||||
constexpr int NotOpened = static_cast<int>(0x80bc0002u);
|
||||
constexpr int ConnectionFailed = static_cast<int>(0x80bc0004u);
|
||||
constexpr int InvalidUserId = static_cast<int>(0x80bc0010u);
|
||||
constexpr int InvalidAddress = static_cast<int>(0x80bc0031u);
|
||||
KeyboardResourceIdArray ids;
|
||||
std::memset(&ids, 0xa5, sizeof(ids));
|
||||
Require(sceImeKeyboardGetResourceId(1, nullptr) == InvalidAddress, "null resource id array");
|
||||
Require(sceImeKeyboardGetResourceId(-1, &ids) == InvalidUserId, "invalid user");
|
||||
const auto* bytes = reinterpret_cast<const unsigned char*>(&ids);
|
||||
for (size_t i = 0; i < sizeof(ids); ++i) Require(bytes[i] == 0xa5, "outputs changed on argument error");
|
||||
Require(sceImeKeyboardGetResourceId(1, &ids) == NotOpened, "keyboard not opened");
|
||||
Require(ids.user_id == 1, "user not reported for an unopened keyboard");
|
||||
for (uint32_t id : ids.resource_id) Require(id == 0, "resource id reported for an unopened keyboard");
|
||||
KeyboardParam param{};
|
||||
Require(sceImeKeyboardOpen(1, ¶m) == 0, "keyboard open failed");
|
||||
std::memset(&ids, 0xa5, sizeof(ids));
|
||||
Require(sceImeKeyboardGetResourceId(1, &ids) == ConnectionFailed, "a keyboard was reported as connected");
|
||||
Require(ids.user_id == 1, "user not reported");
|
||||
for (uint32_t id : ids.resource_id) Require(id == 0, "resource id reported without a keyboard");
|
||||
Require(sceImeKeyboardGetResourceId(2, &ids) == NotOpened, "keyboard of another user reported as opened");
|
||||
Require(ids.user_id == 2, "other user not reported");
|
||||
Require(sceImeKeyboardClose(1) == 0, "keyboard close failed");
|
||||
Require(sceImeKeyboardGetResourceId(1, &ids) == NotOpened, "closed keyboard reported as opened");
|
||||
}
|
||||
|
||||
int main() {
|
||||
CheckInitialization();
|
||||
CheckPanelSizes();
|
||||
CheckErrors();
|
||||
CheckClosedPanel();
|
||||
CheckKeyboardResourceIds();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,3 +166,4 @@ Throughout the project, every function at every stage either **does exactly what
|
|||
- [Thread exit destructors](../../core/libs/prx/libSceLibcInternal/Export.cpp) (libSceLibcInternal) run when a libkernel thread finishes; on the main or a host thread only `_sceLibcInternalThreadDtors` runs them, as `exit` does, else they are dropped
|
||||
- [sceFontOpenFontSet](../../core/libs/prx/libSceFont/src/SystemFont.cpp) (libSceFont) opens only the primary file of a system font set. Characters the console takes from the set's other files (Hangul, Thai and Arabic in Japanese and Chinese sets, Arabic in European sets) are reported as unsupported glyphs. The console file names are those of the PS4 firmware; the names of the PS5-only JG2 sets (`0x1A......`) are unknown, so they use the SSTJpPro files. When a console file is missing, an openly licensed substitute (Noto Sans, Noto Sans Mono, Noto Sans Thai, Noto Sans CJK) is loaded instead. It is not the system font: its metrics differ, so text width, line height and wrapping differ from the console. System font faces are loaded by FreeType in host memory, not in the font memory the title passes to the library: FreeType needs about 1 MiB per CJK face, which the title's font memory is not sized for.
|
||||
- [Font writing lines](../../core/libs/prx/libSceFont/src/WritingLine.cpp) (libSceFont) - `sceFontCreateWritingLine`, `sceFontWritingLineWritesOrder`, `sceFontWritingLineRefersRenderStep`, `sceFontWritingLineGetRenderMetrics` and `sceFontWritingLineClear` follow [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/main/src/libs/libFont.cpp): runs are placed left to right, each at the line's advance so far, with no spacing or adjustment. Only horizontal and left-to-right lines, writing attribute 0 and non-null run metrics are modelled; other values, the metrics of an empty line and unknown or null handles throw, since no reference gives their result or error code. `sceFontWritingLineGetOrderingSpace` still throws (KytyPS5's values are placeholders). Lines are allocated on the host, not in the font memory
|
||||
- [sceImeKeyboardGetResourceId](../../core/libs/prx/libSceIme/Export.cpp) (libSceIme) reports that no USB keyboard is connected (`0x80bc0004`, as [shadPS4](https://github.com/shadps4-emu/shadPS4) does) because IME keyboard events are not delivered to the handler, although [libSceKeyboard](../../core/libs/prx/libSceKeyboard/src/keyboard_impl.cpp) exposes the host keyboard
|
||||
|
|
|
|||
Loading…
Reference in New Issue