mirror of
https://github.com/debauchee/barrier.git
synced 2024-12-19 08:51:41 +03:00
synergy.cpp and server.cpp into cmd/synergyd as synergyd.cpp. Moved and renamed related files. Moved remaining source files into lib/.... Modified and added makefiles as appropriate. Result is that library files are under lib with each library in its own directory and program files are under cmd with each command in its own directory.
299 lines
7.6 KiB
C++
Executable File
299 lines
7.6 KiB
C++
Executable File
#include "CMSWindowsScreenSaver.h"
|
|
#include "CThread.h"
|
|
#include "CLog.h"
|
|
#include "TMethodJob.h"
|
|
|
|
#if !defined(SPI_GETSCREENSAVERRUNNING)
|
|
#define SPI_GETSCREENSAVERRUNNING 114
|
|
#endif
|
|
|
|
//
|
|
// CMSWindowsScreenSaver
|
|
//
|
|
|
|
CMSWindowsScreenSaver::CMSWindowsScreenSaver() :
|
|
m_process(NULL),
|
|
m_threadID(0),
|
|
m_watch(NULL)
|
|
{
|
|
// detect OS
|
|
m_is95Family = false;
|
|
m_is95 = false;
|
|
m_isNT = false;
|
|
OSVERSIONINFO info;
|
|
info.dwOSVersionInfoSize = sizeof(info);
|
|
if (GetVersionEx(&info)) {
|
|
m_is95Family = (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
|
|
if (info.dwPlatformId == VER_PLATFORM_WIN32_NT &&
|
|
info.dwMajorVersion <= 4) {
|
|
m_isNT = true;
|
|
}
|
|
else if (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS &&
|
|
info.dwMajorVersion == 4 &&
|
|
info.dwMinorVersion == 0) {
|
|
m_is95 = true;
|
|
}
|
|
}
|
|
|
|
// check if screen saver is enabled
|
|
SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &m_wasEnabled, 0);
|
|
}
|
|
|
|
CMSWindowsScreenSaver::~CMSWindowsScreenSaver()
|
|
{
|
|
unwatchProcess();
|
|
}
|
|
|
|
bool
|
|
CMSWindowsScreenSaver::checkStarted(UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// screen saver may have started. look for it and get
|
|
// the process. if we can't find it then assume it
|
|
// didn't really start. we wait a moment before
|
|
// looking to give the screen saver a chance to start.
|
|
// this shouldn't be a problem since we only get here
|
|
// if the screen saver wants to kick in, meaning that
|
|
// the system is idle or the user deliberately started
|
|
// the screen saver.
|
|
Sleep(250);
|
|
HWND hwnd = findScreenSaver();
|
|
if (hwnd == NULL) {
|
|
// didn't start
|
|
log((CLOG_DEBUG "can't find screen saver window"));
|
|
return false;
|
|
}
|
|
|
|
// get the process
|
|
DWORD processID;
|
|
GetWindowThreadProcessId(hwnd, &processID);
|
|
HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, processID);
|
|
if (process == NULL) {
|
|
// didn't start
|
|
log((CLOG_DEBUG "can't open screen saver process"));
|
|
return false;
|
|
}
|
|
|
|
// watch for the process to exit
|
|
m_threadID = GetCurrentThreadId();
|
|
m_msg = msg;
|
|
m_wParam = wParam;
|
|
m_lParam = lParam;
|
|
watchProcess(process);
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
CMSWindowsScreenSaver::enable()
|
|
{
|
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, m_wasEnabled, 0, 0);
|
|
}
|
|
|
|
void
|
|
CMSWindowsScreenSaver::disable()
|
|
{
|
|
SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &m_wasEnabled, 0);
|
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, 0, 0);
|
|
}
|
|
|
|
void
|
|
CMSWindowsScreenSaver::activate()
|
|
{
|
|
// don't activate if already active
|
|
if (!isActive()) {
|
|
HWND hwnd = GetForegroundWindow();
|
|
if (hwnd != NULL) {
|
|
PostMessage(hwnd, WM_SYSCOMMAND, SC_SCREENSAVE, 0);
|
|
}
|
|
else {
|
|
// no foreground window. pretend we got the event instead.
|
|
DefWindowProc(NULL, WM_SYSCOMMAND, SC_SCREENSAVE, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
CMSWindowsScreenSaver::deactivate()
|
|
{
|
|
bool killed = false;
|
|
if (!m_is95Family) {
|
|
// NT runs screen saver in another desktop
|
|
HDESK desktop = OpenDesktop("screen-saver", 0, FALSE,
|
|
DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS);
|
|
if (desktop != NULL) {
|
|
EnumDesktopWindows(desktop,
|
|
&CMSWindowsScreenSaver::killScreenSaverFunc,
|
|
reinterpret_cast<LPARAM>(&killed));
|
|
CloseDesktop(desktop);
|
|
}
|
|
}
|
|
|
|
// if above failed or wasn't tried, try the windows 95 way
|
|
if (!killed) {
|
|
// find screen saver window and close it
|
|
HWND hwnd = FindWindow("WindowsScreenSaverClass", NULL);
|
|
if (hwnd != NULL) {
|
|
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
|
}
|
|
}
|
|
|
|
// force timer to restart
|
|
SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &m_wasEnabled, 0);
|
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,
|
|
!m_wasEnabled, 0, SPIF_SENDWININICHANGE);
|
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,
|
|
m_wasEnabled, 0, SPIF_SENDWININICHANGE);
|
|
}
|
|
|
|
bool
|
|
CMSWindowsScreenSaver::isActive() const
|
|
{
|
|
if (m_is95) {
|
|
return (FindWindow("WindowsScreenSaverClass", NULL) != NULL);
|
|
}
|
|
else if (m_isNT) {
|
|
// screen saver runs on a separate desktop
|
|
HDESK desktop = OpenDesktop("screen-saver", 0, FALSE, MAXIMUM_ALLOWED);
|
|
if (desktop == NULL && GetLastError() != ERROR_ACCESS_DENIED) {
|
|
// desktop doesn't exist so screen saver is not running
|
|
return false;
|
|
}
|
|
|
|
// desktop exists. this should indicate that the screen saver
|
|
// is running but an OS bug can cause a valid handle to be
|
|
// returned even if the screen saver isn't running (Q230117).
|
|
// we'll try to enumerate the windows on the desktop and, if
|
|
// there are any, we assume the screen saver is running. (note
|
|
// that if we don't have permission to enumerate then we'll
|
|
// assume that the screen saver is not running.) that'd be
|
|
// easy enough except there's another OS bug (Q198590) that can
|
|
// cause EnumDesktopWindows() to enumerate the windows of
|
|
// another desktop if the requested desktop has no windows. to
|
|
// work around that we have to verify that the enumerated
|
|
// windows are, in fact, on the expected desktop.
|
|
CFindScreenSaverInfo info;
|
|
info.m_desktop = desktop;
|
|
info.m_window = NULL;
|
|
EnumDesktopWindows(desktop,
|
|
&CMSWindowsScreenSaver::findScreenSaverFunc,
|
|
reinterpret_cast<LPARAM>(&info));
|
|
|
|
// done with desktop
|
|
CloseDesktop(desktop);
|
|
|
|
// screen saver is running if a window was found
|
|
return (info.m_window != NULL);
|
|
}
|
|
else {
|
|
BOOL running;
|
|
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &running, 0);
|
|
return (running != FALSE);
|
|
}
|
|
}
|
|
|
|
BOOL CALLBACK
|
|
CMSWindowsScreenSaver::findScreenSaverFunc(HWND hwnd, LPARAM arg)
|
|
{
|
|
CFindScreenSaverInfo* info = reinterpret_cast<CFindScreenSaverInfo*>(arg);
|
|
|
|
if (info->m_desktop != NULL) {
|
|
DWORD threadID = GetWindowThreadProcessId(hwnd, NULL);
|
|
HDESK desktop = GetThreadDesktop(threadID);
|
|
if (desktop != NULL && desktop != info->m_desktop) {
|
|
// stop enumerating -- wrong desktop
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// found a window
|
|
info->m_window = hwnd;
|
|
|
|
// don't need to enumerate further
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CALLBACK
|
|
CMSWindowsScreenSaver::killScreenSaverFunc(HWND hwnd, LPARAM arg)
|
|
{
|
|
if (IsWindowVisible(hwnd)) {
|
|
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
|
*reinterpret_cast<bool*>(arg) = true;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
HWND
|
|
CMSWindowsScreenSaver::findScreenSaver()
|
|
{
|
|
if (!m_is95Family) {
|
|
// screen saver runs on a separate desktop
|
|
HDESK desktop = OpenDesktop("screen-saver", 0, FALSE, MAXIMUM_ALLOWED);
|
|
if (desktop != NULL) {
|
|
// search
|
|
CFindScreenSaverInfo info;
|
|
info.m_desktop = desktop;
|
|
info.m_window = NULL;
|
|
EnumDesktopWindows(desktop,
|
|
&CMSWindowsScreenSaver::findScreenSaverFunc,
|
|
reinterpret_cast<LPARAM>(&info));
|
|
|
|
// done with desktop
|
|
CloseDesktop(desktop);
|
|
|
|
// return window if found
|
|
if (info.m_window != NULL) {
|
|
return info.m_window;
|
|
}
|
|
}
|
|
}
|
|
|
|
// try windows 95 way
|
|
return FindWindow("WindowsScreenSaverClass", NULL);
|
|
}
|
|
|
|
void
|
|
CMSWindowsScreenSaver::watchProcess(HANDLE process)
|
|
{
|
|
// stop watching previous process
|
|
unwatchProcess();
|
|
|
|
// watch new process in another thread
|
|
if (process != NULL) {
|
|
log((CLOG_DEBUG "watching screen saver process"));
|
|
m_process = process;
|
|
m_watch = new CThread(new TMethodJob<CMSWindowsScreenSaver>(this,
|
|
&CMSWindowsScreenSaver::watchProcessThread));
|
|
}
|
|
}
|
|
|
|
void
|
|
CMSWindowsScreenSaver::unwatchProcess()
|
|
{
|
|
if (m_watch != NULL) {
|
|
log((CLOG_DEBUG "stopped watching screen saver process"));
|
|
m_watch->cancel();
|
|
m_watch->wait();
|
|
delete m_watch;
|
|
m_watch = NULL;
|
|
}
|
|
if (m_process != NULL) {
|
|
CloseHandle(m_process);
|
|
m_process = NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
CMSWindowsScreenSaver::watchProcessThread(void*)
|
|
{
|
|
for (;;) {
|
|
CThread::testCancel();
|
|
if (WaitForSingleObject(m_process, 50) == WAIT_OBJECT_0) {
|
|
// process terminated. send screen saver deactivation
|
|
// message.
|
|
log((CLOG_DEBUG "screen saver died"));
|
|
PostThreadMessage(m_threadID, m_msg, m_wParam, m_lParam);
|
|
return;
|
|
}
|
|
}
|
|
}
|