Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically toggle listen mode in UltraVNC Viewer when the PC is idle/not idle #197

Open
panreyes opened this issue Jun 26, 2024 · 2 comments
Assignees
Labels
Rudi Rudi answer is needed

Comments

@panreyes
Copy link
Contributor

panreyes commented Jun 26, 2024

It would be a nice feature to automatically disable listen mode in UltraVNC Viewer then the PC is idle and enable it back again when the user gets back.

It would be helpful to:

  • Find out if the user is available to receive the connection.
  • Improve security in PCs that are never shut down.

I believe it could be done with GetLastInputInfo from windows.h:
https://learn.microsoft.com/bs-latn-ba/windows/win32/api/winuser/nf-winuser-getlastinputinfo

Here's an example snippet:

#include <iostream>
#include <windows.h>

// Function to get the idle time in seconds
DWORD GetIdleTime() {
    LASTINPUTINFO lastInputInfo;
    lastInputInfo.cbSize = sizeof(LASTINPUTINFO);
    if (GetLastInputInfo(&lastInputInfo)) {
        DWORD currentTime = GetTickCount();
        return (currentTime - lastInputInfo.dwTime) / 1000;
    }
    return 0;
}

int main() {
    while (true) {
        DWORD idleTime = GetIdleTime();
        std::cout << "Idle time in seconds: " << idleTime << std::endl;
        Sleep(1000);  // Sleep for 1 second before checking again
    }
    return 0;
}
@Neustradamus Neustradamus added the Rudi Rudi answer is needed label Jun 27, 2024
@RudiDeVos
Copy link
Member

The it would be better to disable it when the screenlock get into action and start back when unlocked.
Idle is also watching a youtube.

@panreyes
Copy link
Contributor Author

That would be really useful too for most cases, although I never use screen lock in my home PC (which is also my work PC).

About the case of "idle + watching YouTube", it looks like there's no public API to check if there are any Video Wake Locks active, but it might be good enough to check if the current monitor has gone to sleep mode:

#include <Windows.h>
#include <iostream>
#include <powrprof.h>
#pragma comment(lib, "PowrProf.lib")

// GUID for session display status changes.
const GUID GUID_SESSION_DISPLAY_STATUS = { 0x2b84c20e, 0xad23, 0x4ddf, {0x93, 0xdb, 0x05, 0xff, 0xbd, 0x7e, 0xfc, 0xa5} };

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_POWERBROADCAST:
        if (wParam == PBT_POWERSETTINGCHANGE) {
            POWERBROADCAST_SETTING* pbs = (POWERBROADCAST_SETTING*)lParam;
            if (pbs && IsEqualGUID(pbs->PowerSetting, GUID_SESSION_DISPLAY_STATUS)) {
                DWORD displayStatus = *(DWORD*)pbs->Data;
                if (displayStatus == 0) {
                    std::cout << "Display is off" << std::endl;
                }
                else {
                    std::cout << "Display is on" << std::endl;
                }
            }
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

int main() {
    HINSTANCE hInstance = GetModuleHandle(nullptr);

    WNDCLASS wc = { 0 };
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = L"SessionDisplayStatusWindowClass";

    if (!RegisterClass(&wc)) {
        std::cerr << "Window registration failed!" << std::endl;
        return 1;
    }

    HWND hWnd = CreateWindowEx(0, wc.lpszClassName, L"Hidden Display Status Monitor",
        0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, hInstance, nullptr);

    if (!hWnd) {
        std::cerr << "Message-only window creation failed!" << std::endl;
        return 1;
    }

    // Register for session display status notifications
    HPOWERNOTIFY hPowerNotify = RegisterPowerSettingNotification(hWnd, &GUID_SESSION_DISPLAY_STATUS, DEVICE_NOTIFY_WINDOW_HANDLE);
    if (!hPowerNotify) {
        std::cerr << "Power setting notification registration failed!" << std::endl;
    }

    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    // Unregister the power setting notification
    if (hPowerNotify) {
        UnregisterPowerSettingNotification(hPowerNotify);
    }

    return static_cast<int>(msg.wParam);
}

(Sorry if that snippet is not good enough, I'm not too good with C++ and I'm consulting ChatGPT!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Rudi Rudi answer is needed
Development

No branches or pull requests

3 participants