adds GDK suspend/resume basic handling (#6596)

This commit is contained in:
Ciro Mondueri 2022-11-23 16:41:14 -03:00 committed by GitHub
parent ac2fcfcb62
commit f6144dfe03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 55 additions and 0 deletions

View File

@ -263,6 +263,12 @@ extern DECLSPEC int SDLCALL SDL_UIKitRunApp(int argc, char *argv[], SDL_main_fun
*/
extern DECLSPEC int SDLCALL SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved);
/**
* Callback from the application to let the suspend continue.
*
*/
extern DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void);
#endif /* __GDK__ */
#ifdef __cplusplus

View File

@ -20,16 +20,24 @@
*/
#include "../../SDL_internal.h"
extern "C" {
#include "SDL_system.h"
#include "../windows/SDL_windows.h"
#include "SDL_messagebox.h"
#include "SDL_main.h"
#include "SDL_events.h"
#include "../../events/SDL_events_c.h"
}
#include <XGameRuntime.h>
#include <xsapi-c/services_c.h>
#include <shellapi.h> /* CommandLineToArgvW() */
#include <appnotify.h>
static XTaskQueueHandle GDK_GlobalTaskQueue;
PAPPSTATE_REGISTRATION hPLM = {};
HANDLE plmSuspendComplete = nullptr;
extern "C" DECLSPEC int
SDL_GDKGetTaskQueue(XTaskQueueHandle * outTaskQueue)
{
@ -144,9 +152,40 @@ SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved)
SDL_SetMainReady();
/* Register suspend/resume handling */
plmSuspendComplete = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
if (!plmSuspendComplete ) {
SDL_SetError("[GDK] Unable to create plmSuspendComplete event");
return -1;
}
auto rascn = [](BOOLEAN quiesced, PVOID context)
{
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler");
if (quiesced) {
ResetEvent(plmSuspendComplete);
SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
// To defer suspension, we must wait to exit this callback.
// IMPORTANT: The app must call SDL_GDKSuspendComplete() to release this lock.
(void)WaitForSingleObject(plmSuspendComplete, INFINITE);
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler: plmSuspendComplete event signaled.");
} else {
SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
}
};
if (RegisterAppStateChangeNotification(rascn, NULL, &hPLM)) {
SDL_SetError("[GDK] Unable to call RegisterAppStateChangeNotification");
return -1;
}
/* Run the application main() code */
result = mainFunction(argc, argv);
/* Unregister suspend/resume handling */
UnregisterAppStateChangeNotification(hPLM);
CloseHandle(plmSuspendComplete);
/* !!! FIXME: This follows the docs exactly, but for some reason still leaks handles on exit? */
/* Terminate the task queue and dispatch any pending tasks */
XTaskQueueTerminate(taskQueue, false, nullptr, nullptr);
@ -173,3 +212,10 @@ SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved)
return result;
}
extern "C" DECLSPEC void
SDL_GDKSuspendComplete() {
if (plmSuspendComplete) {
SetEvent(plmSuspendComplete);
}
}

View File

@ -851,6 +851,7 @@
++'_SDL_utf8strnlen'.'SDL2.dll'.'SDL_utf8strnlen'
# ++'_SDL_GDKGetTaskQueue'.'SDL2.dll'.'SDL_GDKGetTaskQueue'
# ++'_SDL_GDKRunApp'.'SDL2.dll'.'SDL_GDKRunApp'
# ++'_SDL_GDKSuspendComplete'.'SDL2.dll'.'SDL_GDKSuspendComplete'
++'_SDL_GetOriginalMemoryFunctions'.'SDL2.dll'.'SDL_GetOriginalMemoryFunctions'
++'_SDL_ResetKeyboard'.'SDL2.dll'.'SDL_ResetKeyboard'
++'_SDL_GetDefaultAudioInfo'.'SDL2.dll'.'SDL_GetDefaultAudioInfo'

View File

@ -877,6 +877,7 @@
#define SDL_utf8strnlen SDL_utf8strnlen_REAL
#define SDL_GDKGetTaskQueue SDL_GDKGetTaskQueue_REAL
#define SDL_GDKRunApp SDL_GDKRunApp_REAL
#define SDL_GDKSuspendComplete SDL_GDKSuspendComplete_REAL
#define SDL_GetOriginalMemoryFunctions SDL_GetOriginalMemoryFunctions_REAL
#define SDL_ResetKeyboard SDL_ResetKeyboard_REAL
#define SDL_GetDefaultAudioInfo SDL_GetDefaultAudioInfo_REAL

View File

@ -959,6 +959,7 @@ SDL_DYNAPI_PROC(size_t,SDL_utf8strnlen,(const char *a, size_t b),(a,b),return)
#if defined(__GDK__)
SDL_DYNAPI_PROC(int,SDL_GDKGetTaskQueue,(XTaskQueueHandle *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GDKRunApp,(SDL_main_func a, void *b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_GDKSuspendComplete,(void),(),return)
#endif
SDL_DYNAPI_PROC(void,SDL_GetOriginalMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),)
SDL_DYNAPI_PROC(void,SDL_ResetKeyboard,(void),(),)