feat(videoout): implement sceVideoOutDeleteOutputModeEvent

Unsubscribe an event queue from the output mode events that
sceVideoOutAddOutputModeEvent registers, the same way the flip and
vblank events are removed. Deleting a registration that does not exist
succeeds, and a null queue or an invalid handle throws.

Co-Authored-By: Gemini 3.8 Flash <noreply@google.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Alex 2026-10-10 20:08:38 -04:00
parent 1690db9a24
commit b6cc4fe7f9
3 changed files with 15 additions and 0 deletions

View File

@ -15,6 +15,7 @@ int APS5_VABI sceVideoOutAddVblankEvent(KernelEqueue eq, int handle, void* udata
int APS5_VABI sceVideoOutAddVrrActiveStatusEvent(KernelEqueue eq, int handle, void* udata);
int APS5_VABI sceVideoOutDeleteFlipEvent(KernelEqueue eq, int handle);
int APS5_VABI sceVideoOutDeleteOutputModeEvent(KernelEqueue eq, int handle);
int APS5_VABI sceVideoOutDeletePreVblankStartEvent(KernelEqueue eq, int handle);
int APS5_VABI sceVideoOutDeleteVblankEvent(KernelEqueue eq, int handle);

View File

@ -144,6 +144,12 @@ int APS5_VABI sceVideoOutDeleteFlipEvent(KernelEqueue eq, int handle) try {
LibcAwaitExit_nid_postfix();
}
int APS5_VABI sceVideoOutDeleteOutputModeEvent(KernelEqueue eq, int handle) try {
return deleteVideoOutEvent(handle, eq, VIDEO_OUT_EVENT_SET_MODE);
} catch (const ProcessShutdown&) {
LibcAwaitExit_nid_postfix();
}
int APS5_VABI sceVideoOutDeleteVblankEvent(KernelEqueue eq, int handle) try {
return deleteVideoOutEvent(handle, eq, VIDEO_OUT_EVENT_VBLANK);
} catch (const ProcessShutdown&) {

View File

@ -307,6 +307,14 @@ void testControls() {
check(owner->GetTriggeredEvents(&event, 1) == 1, "initial output mode event missing");
int64_t mode = 0;
check(sceVideoOutGetEventData(&event, &mode) == 0 && mode == VIDEO_OUT_OUTPUT_MODE_DEFAULT && sceVideoOutGetEventCount(&event) == 1, "initial output mode event encoding is wrong");
check(sceVideoOutDeleteOutputModeEvent(queue, handle) == 0, "output mode unsubscription failed");
{
std::lock_guard lock(cfg->mutex);
check(cfg->outputModeEvents.empty(), "output mode unsubscription did not clear registration");
}
check(sceVideoOutDeleteOutputModeEvent(queue, handle) == 0, "duplicate output mode unsubscription failed");
expectFailure([&] { sceVideoOutDeleteOutputModeEvent(0, handle); });
expectFailure([&] { sceVideoOutDeleteOutputModeEvent(queue, -1); });
check(sceVideoOutAddVblankEvent(queue, handle, nullptr) == 0 && sceVideoOutAddVblankEvent(queue, handle, &settings) == 0, "vblank subscription failed");
{
std::lock_guard lock(cfg->mutex);