diff --git a/Common/System/Request.cpp b/Common/System/Request.cpp index d6368c1042..436a02d216 100644 --- a/Common/System/Request.cpp +++ b/Common/System/Request.cpp @@ -144,3 +144,9 @@ void System_ShowFileInFolder(const Path &path) { void System_BrowseForFolder(RequesterToken token, std::string_view title, const Path &initialPath, RequestCallback callback, RequestFailedCallback failedCallback) { g_requestManager.MakeSystemRequest(SystemRequestType::BROWSE_FOR_FOLDER, token, callback, failedCallback, title, initialPath.ToCString(), 0); } + +void System_RunCallbackInWndProc(void (*callback)(void *, void *), void *userdata) { + int64_t castPtr = (int64_t)callback; + int64_t castUserData = (int64_t)userdata; + g_requestManager.MakeSystemRequest(SystemRequestType::RUN_CALLBACK_IN_WNDPROC, NO_REQUESTER_TOKEN, nullptr, nullptr, "", "", castPtr, castUserData); +} diff --git a/Common/System/Request.h b/Common/System/Request.h index 6e6e922b2a..e9f23bab8b 100644 --- a/Common/System/Request.h +++ b/Common/System/Request.h @@ -176,6 +176,8 @@ inline void System_SendDebugScreenshot(std::string_view data, int height) { g_requestManager.MakeSystemRequest(SystemRequestType::SEND_DEBUG_SCREENSHOT, NO_REQUESTER_TOKEN, nullptr, nullptr, data, "", height); } +void System_RunCallbackInWndProc(void (*callback)(void *, void *), void *userdata); + // Non-inline to avoid including Path.h void System_CreateGameShortcut(const Path &path, std::string_view title); void System_ShowFileInFolder(const Path &path); diff --git a/Common/System/System.h b/Common/System/System.h index 6763f79dc4..763c31f517 100644 --- a/Common/System/System.h +++ b/Common/System/System.h @@ -86,6 +86,8 @@ enum class SystemRequestType { GPS_COMMAND, INFRARED_COMMAND, MICROPHONE_COMMAND, + + RUN_CALLBACK_IN_WNDPROC, }; // Implementations are supposed to process the request, and post the response to the g_RequestManager (see Message.h). diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 0bfb82a7bf..c162a510ee 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -764,6 +764,13 @@ namespace MainWindow } break; + case WM_USER_RUN_CALLBACK: + { + auto callback = reinterpret_cast(wParam); + void *userdata = reinterpret_cast(lParam); + callback(hWnd, userdata); + break; + } case WM_USER_GET_BASE_POINTER: Reporting::NotifyDebugger(); switch (lParam) { @@ -1135,4 +1142,8 @@ namespace MainWindow return g_isFullscreen; } + void RunCallbackInWndProc(void (*callback)(void *, void *), void *userdata) { + PostMessage(hwndMain, WM_USER_RUN_CALLBACK, reinterpret_cast(callback), reinterpret_cast(userdata)); + } + } // namespace diff --git a/Windows/MainWindow.h b/Windows/MainWindow.h index c4ed9f81fd..b79a10b2af 100644 --- a/Windows/MainWindow.h +++ b/Windows/MainWindow.h @@ -18,7 +18,8 @@ namespace MainWindow WM_USER_WINDOW_TITLE_CHANGED = WM_USER + 103, WM_USER_TOGGLE_FULLSCREEN = WM_USER + 105, WM_USER_RESTART_EMUTHREAD = WM_USER + 106, - WM_USER_SWITCHUMD_UPDATED = WM_USER + 107 + WM_USER_SWITCHUMD_UPDATED = WM_USER + 107, + WM_USER_RUN_CALLBACK = WM_USER + 108, }; enum { @@ -79,6 +80,7 @@ namespace MainWindow void ToggleDebugConsoleVisibility(); void SetInternalResolution(int res = -1); void SetWindowSize(int zoom); + void RunCallbackInWndProc(void (*callback)(void *window, void *userdata), void *userdata); } #endif diff --git a/Windows/main.cpp b/Windows/main.cpp index 7bdda88582..5e273b423e 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -636,7 +636,13 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string } case SystemRequestType::CREATE_GAME_SHORTCUT: return W32Util::CreateDesktopShortcut(param1, param2); - + case SystemRequestType::RUN_CALLBACK_IN_WNDPROC: + { + auto func = reinterpret_cast(param3); + void *userdata = reinterpret_cast(param4); + MainWindow::RunCallbackInWndProc(func, userdata); + return true; + } default: return false; }