From 8e98f863b6a7c802f7808fdff2ca77b9b1b940f0 Mon Sep 17 00:00:00 2001 From: Quantum Date: Wed, 3 Feb 2021 17:42:54 -0500 Subject: [PATCH] [host] windows: detect whether screensaver is disabled in the guest This will allow us to add an option to disable the screensaver on the client when an application in the guest requests it. This behaviour may be useful when the guest is doing media playback. --- common/include/common/KVMFR.h | 4 +++- host/include/interface/platform.h | 2 ++ host/platform/Linux/src/platform.c | 5 +++++ host/platform/Windows/CMakeLists.txt | 1 + host/platform/Windows/src/platform.c | 23 +++++++++++++++++++++++ host/src/app.c | 1 + 6 files changed, 35 insertions(+), 1 deletion(-) diff --git a/common/include/common/KVMFR.h b/common/include/common/KVMFR.h index 1981202a..4b1fd34d 100644 --- a/common/include/common/KVMFR.h +++ b/common/include/common/KVMFR.h @@ -23,10 +23,11 @@ Place, Suite 330, Boston, MA 02111-1307 USA #pragma once #include +#include #include "types.h" #define KVMFR_MAGIC "KVMFR---" -#define KVMFR_VERSION 8 +#define KVMFR_VERSION 9 #define LGMP_Q_POINTER 1 #define LGMP_Q_FRAME 2 @@ -73,6 +74,7 @@ typedef struct KVMFRFrame uint32_t pitch; // the row pitch (stride in bytes or the compressed frame size) uint32_t offset; // offset from the start of this header to the FrameBuffer header uint32_t mouseScalePercent; // movement scale factor of the mouse (relates to DPI of display, 100 = no scale) + bool blockScreensaver; // whether the guest has requested to block screensavers } KVMFRFrame; diff --git a/host/include/interface/platform.h b/host/include/interface/platform.h index 00dd1279..4331ab44 100644 --- a/host/include/interface/platform.h +++ b/host/include/interface/platform.h @@ -38,3 +38,5 @@ void app_quit(); // these must be implemented for each OS const char * os_getExecutable(); const char * os_getDataPath(); + +bool os_blockScreensaver(); diff --git a/host/platform/Linux/src/platform.c b/host/platform/Linux/src/platform.c index 933171b4..0316339e 100644 --- a/host/platform/Linux/src/platform.c +++ b/host/platform/Linux/src/platform.c @@ -72,3 +72,8 @@ const char * os_getDataPath(void) { return app.dataPath; } + +bool os_blockScreensaver() +{ + return false; +} diff --git a/host/platform/Windows/CMakeLists.txt b/host/platform/Windows/CMakeLists.txt index 18fe746e..71bcfa3d 100644 --- a/host/platform/Windows/CMakeLists.txt +++ b/host/platform/Windows/CMakeLists.txt @@ -33,6 +33,7 @@ target_link_libraries(platform_Windows wtsapi32 psapi shlwapi + powrprof ) target_include_directories(platform_Windows diff --git a/host/platform/Windows/src/platform.c b/host/platform/Windows/src/platform.c index 3ed3c74c..e7bf0a0d 100644 --- a/host/platform/Windows/src/platform.c +++ b/host/platform/Windows/src/platform.c @@ -25,6 +25,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include #include +#include +#include #include "interface/platform.h" #include "common/debug.h" @@ -397,3 +399,24 @@ HWND os_getMessageWnd(void) { return app.messageWnd; } + +bool os_blockScreensaver() +{ + static bool lastResult = false; + static ULONGLONG lastCheck = 0; + + ULONGLONG now = GetTickCount64(); + if (now - lastCheck >= 1000) + { + ULONG executionState; + NTSTATUS status = CallNtPowerInformation(SystemExecutionState, NULL, 0, + &executionState, sizeof executionState); + + if (status == STATUS_SUCCESS) + lastResult = executionState & ES_DISPLAY_REQUIRED; + else + DEBUG_ERROR("Failed to call CallNtPowerInformation(SystemExecutionState): %ld", status); + lastCheck = now; + } + return lastResult; +} diff --git a/host/src/app.c b/host/src/app.c index 466b94fa..b38d1dab 100644 --- a/host/src/app.c +++ b/host/src/app.c @@ -206,6 +206,7 @@ static int frameThread(void * opaque) fi->pitch = frame.pitch; fi->offset = pageSize - FrameBufferStructSize; fi->mouseScalePercent = app.iface->getMouseScale(); + fi->blockScreensaver = os_blockScreensaver(); frameValid = true; // put the framebuffer on the border of the next page