Added win32 support for power management.
This commit is contained in:
parent
a1c807ba67
commit
a6e858a208
|
@ -13,17 +13,17 @@
|
|||
#define IDR_TASKBAR 107
|
||||
#define IDD_TASKBAR_STATUS 108
|
||||
#define IDC_TASKBAR_STATUS_STATUS 1000
|
||||
#define IDC_TASKBAR_QUIT 40003
|
||||
#define IDC_TASKBAR_STATUS 40004
|
||||
#define IDC_TASKBAR_LOG 40005
|
||||
#define IDC_TASKBAR_QUIT 40001
|
||||
#define IDC_TASKBAR_STATUS 40002
|
||||
#define IDC_TASKBAR_LOG 40003
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_RESOURCE_VALUE 109
|
||||
#define _APS_NEXT_COMMAND_VALUE 40004
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "CThread.h"
|
||||
#include "CEventQueue.h"
|
||||
#include "CFunctionEventJob.h"
|
||||
#include "CFunctionJob.h"
|
||||
#include "CLog.h"
|
||||
#include "CString.h"
|
||||
#include "CStringUtil.h"
|
||||
|
@ -54,7 +55,12 @@
|
|||
#endif
|
||||
|
||||
typedef int (*StartupFunc)(int, char**);
|
||||
static bool startClient();
|
||||
static void parse(int argc, const char* const* argv);
|
||||
#if WINDOWS_LIKE
|
||||
static void handleSystemSuspend(void*);
|
||||
static void handleSystemResume(void*);
|
||||
#endif
|
||||
|
||||
//
|
||||
// program arguments
|
||||
|
@ -97,7 +103,9 @@ CScreen*
|
|||
createScreen()
|
||||
{
|
||||
#if WINDOWS_LIKE
|
||||
return new CScreen(new CMSWindowsScreen(false));
|
||||
return new CScreen(new CMSWindowsScreen(false,
|
||||
new CFunctionJob(&handleSystemSuspend),
|
||||
new CFunctionJob(&handleSystemResume)));
|
||||
#elif UNIX_LIKE
|
||||
return new CScreen(new CXWindowsScreen(false));
|
||||
#endif
|
||||
|
@ -124,6 +132,7 @@ static CClient* s_client = NULL;
|
|||
static CScreen* s_clientScreen = NULL;
|
||||
static CClientTaskBarReceiver* s_taskBarReceiver = NULL;
|
||||
static double s_retryTime = 0.0;
|
||||
static bool s_suspened = false;
|
||||
|
||||
static
|
||||
void
|
||||
|
@ -181,6 +190,26 @@ handleScreenError(const CEvent&, void*)
|
|||
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
|
||||
}
|
||||
|
||||
#if WINDOWS_LIKE
|
||||
static
|
||||
void
|
||||
handleSystemSuspend(void*)
|
||||
{
|
||||
LOG((CLOG_NOTE "system suspending"));
|
||||
s_suspened = true;
|
||||
s_client->disconnect(NULL);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
handleSystemResume(void*)
|
||||
{
|
||||
LOG((CLOG_NOTE "system resuming"));
|
||||
s_suspened = false;
|
||||
startClient();
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
CScreen*
|
||||
openClientScreen()
|
||||
|
@ -211,11 +240,12 @@ handleClientRestart(const CEvent&, void* vtimer)
|
|||
// discard old timer
|
||||
CEventQueueTimer* timer = reinterpret_cast<CEventQueueTimer*>(vtimer);
|
||||
EVENTQUEUE->deleteTimer(timer);
|
||||
EVENTQUEUE->removeHandler(CEvent::kTimer, NULL);
|
||||
EVENTQUEUE->removeHandler(CEvent::kTimer, timer);
|
||||
|
||||
// reconnect
|
||||
s_client->connect();
|
||||
updateStatus();
|
||||
if (!s_suspened) {
|
||||
startClient();
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -251,7 +281,9 @@ handleClientFailed(const CEvent& e, void*)
|
|||
}
|
||||
else {
|
||||
LOG((CLOG_WARN "failed to connect to server: %s", info->m_what));
|
||||
scheduleClientRestart(nextRestartTimeout());
|
||||
if (!s_suspened) {
|
||||
scheduleClientRestart(nextRestartTimeout());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,7 +295,7 @@ handleClientDisconnected(const CEvent&, void*)
|
|||
if (!ARG->m_restartable) {
|
||||
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
|
||||
}
|
||||
else {
|
||||
else if (!s_suspened) {
|
||||
s_client->connect();
|
||||
}
|
||||
updateStatus();
|
||||
|
@ -308,11 +340,13 @@ startClient()
|
|||
double retryTime;
|
||||
CScreen* clientScreen = NULL;
|
||||
try {
|
||||
clientScreen = openClientScreen();
|
||||
s_client = openClient(ARG->m_name,
|
||||
if (s_clientScreen == NULL) {
|
||||
clientScreen = openClientScreen();
|
||||
s_client = openClient(ARG->m_name,
|
||||
*ARG->m_serverAddress, clientScreen);
|
||||
s_clientScreen = clientScreen;
|
||||
LOG((CLOG_NOTE "started client"));
|
||||
s_clientScreen = clientScreen;
|
||||
LOG((CLOG_NOTE "started client"));
|
||||
}
|
||||
s_client->connect();
|
||||
updateStatus();
|
||||
return true;
|
||||
|
|
|
@ -114,7 +114,7 @@ CScreen*
|
|||
createScreen()
|
||||
{
|
||||
#if WINDOWS_LIKE
|
||||
return new CScreen(new CMSWindowsScreen(true));
|
||||
return new CScreen(new CMSWindowsScreen(true, NULL, NULL));
|
||||
#elif UNIX_LIKE
|
||||
return new CScreen(new CXWindowsScreen(true));
|
||||
#endif
|
||||
|
|
|
@ -15,11 +15,24 @@
|
|||
#include "CArchMiscWindows.h"
|
||||
#include "CArchDaemonWindows.h"
|
||||
|
||||
#ifndef ES_SYSTEM_REQUIRED
|
||||
#define ES_SYSTEM_REQUIRED ((DWORD)0x00000001)
|
||||
#endif
|
||||
#ifndef ES_DISPLAY_REQUIRED
|
||||
#define ES_DISPLAY_REQUIRED ((DWORD)0x00000002)
|
||||
#endif
|
||||
#ifndef ES_CONTINUOUS
|
||||
#define ES_CONTINUOUS ((DWORD)0x80000000)
|
||||
#endif
|
||||
typedef DWORD EXECUTION_STATE;
|
||||
|
||||
//
|
||||
// CArchMiscWindows
|
||||
//
|
||||
|
||||
CArchMiscWindows::CDialogs* CArchMiscWindows::s_dialogs = NULL;
|
||||
CArchMiscWindows::CDialogs* CArchMiscWindows::s_dialogs = NULL;
|
||||
DWORD CArchMiscWindows::s_busyState = 0;
|
||||
CArchMiscWindows::STES_t CArchMiscWindows::s_stes = NULL;
|
||||
|
||||
void
|
||||
CArchMiscWindows::init()
|
||||
|
@ -143,6 +156,29 @@ CArchMiscWindows::hasValue(HKEY key, const TCHAR* name)
|
|||
(type == REG_DWORD || type == REG_SZ));
|
||||
}
|
||||
|
||||
CArchMiscWindows::EValueType
|
||||
CArchMiscWindows::typeOfValue(HKEY key, const TCHAR* name)
|
||||
{
|
||||
DWORD type;
|
||||
LONG result = RegQueryValueEx(key, name, 0, &type, NULL, NULL);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return kNO_VALUE;
|
||||
}
|
||||
switch (type) {
|
||||
case REG_DWORD:
|
||||
return kUINT;
|
||||
|
||||
case REG_SZ:
|
||||
return kSTRING;
|
||||
|
||||
case REG_BINARY:
|
||||
return kBINARY;
|
||||
|
||||
default:
|
||||
return kUNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CArchMiscWindows::setValue(HKEY key,
|
||||
const TCHAR* name, const std::string& value)
|
||||
|
@ -164,14 +200,25 @@ CArchMiscWindows::setValue(HKEY key, const TCHAR* name, DWORD value)
|
|||
sizeof(DWORD));
|
||||
}
|
||||
|
||||
void
|
||||
CArchMiscWindows::setValueBinary(HKEY key,
|
||||
const TCHAR* name, const std::string& value)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(name != NULL);
|
||||
RegSetValueEx(key, name, 0, REG_BINARY,
|
||||
reinterpret_cast<const BYTE*>(value.data()),
|
||||
value.size());
|
||||
}
|
||||
|
||||
std::string
|
||||
CArchMiscWindows::readValueString(HKEY key, const TCHAR* name)
|
||||
CArchMiscWindows::readBinaryOrString(HKEY key, const TCHAR* name, DWORD type)
|
||||
{
|
||||
// get the size of the string
|
||||
DWORD type;
|
||||
DWORD actualType;
|
||||
DWORD size = 0;
|
||||
LONG result = RegQueryValueEx(key, name, 0, &type, NULL, &size);
|
||||
if (result != ERROR_SUCCESS || type != REG_SZ) {
|
||||
LONG result = RegQueryValueEx(key, name, 0, &actualType, NULL, &size);
|
||||
if (result != ERROR_SUCCESS || actualType != type) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
@ -179,19 +226,31 @@ CArchMiscWindows::readValueString(HKEY key, const TCHAR* name)
|
|||
char* buffer = new char[size];
|
||||
|
||||
// read it
|
||||
result = RegQueryValueEx(key, name, 0, &type,
|
||||
result = RegQueryValueEx(key, name, 0, &actualType,
|
||||
reinterpret_cast<BYTE*>(buffer), &size);
|
||||
if (result != ERROR_SUCCESS || type != REG_SZ) {
|
||||
if (result != ERROR_SUCCESS || actualType != type) {
|
||||
delete[] buffer;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// clean up and return value
|
||||
std::string value(buffer);
|
||||
std::string value(buffer, size);
|
||||
delete[] buffer;
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string
|
||||
CArchMiscWindows::readValueString(HKEY key, const TCHAR* name)
|
||||
{
|
||||
return readBinaryOrString(key, name, REG_SZ);
|
||||
}
|
||||
|
||||
std::string
|
||||
CArchMiscWindows::readValueBinary(HKEY key, const TCHAR* name)
|
||||
{
|
||||
return readBinaryOrString(key, name, REG_BINARY);
|
||||
}
|
||||
|
||||
DWORD
|
||||
CArchMiscWindows::readValueInt(HKEY key, const TCHAR* name)
|
||||
{
|
||||
|
@ -229,3 +288,55 @@ CArchMiscWindows::processDialog(MSG* msg)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CArchMiscWindows::addBusyState(DWORD busyModes)
|
||||
{
|
||||
s_busyState |= busyModes;
|
||||
setThreadExecutionState(s_busyState);
|
||||
}
|
||||
|
||||
void
|
||||
CArchMiscWindows::removeBusyState(DWORD busyModes)
|
||||
{
|
||||
s_busyState &= ~busyModes;
|
||||
setThreadExecutionState(s_busyState);
|
||||
}
|
||||
|
||||
void
|
||||
CArchMiscWindows::setThreadExecutionState(DWORD busyModes)
|
||||
{
|
||||
// look up function dynamically so we work on older systems
|
||||
if (s_stes == NULL) {
|
||||
HINSTANCE kernel = LoadLibrary("kernel32.dll");
|
||||
if (kernel != NULL) {
|
||||
s_stes = reinterpret_cast<STES_t>(GetProcAddress(kernel,
|
||||
"SetThreadExecutionState"));
|
||||
}
|
||||
if (s_stes == NULL) {
|
||||
s_stes = &CArchMiscWindows::dummySetThreadExecutionState;
|
||||
}
|
||||
}
|
||||
|
||||
// convert to STES form
|
||||
EXECUTION_STATE state = 0;
|
||||
if ((busyModes & kSYSTEM) != 0) {
|
||||
state |= ES_SYSTEM_REQUIRED;
|
||||
}
|
||||
if ((busyModes & kDISPLAY) != 0) {
|
||||
state |= ES_DISPLAY_REQUIRED;
|
||||
}
|
||||
if (state != 0) {
|
||||
state |= ES_CONTINUOUS;
|
||||
}
|
||||
|
||||
// do it
|
||||
s_stes(state);
|
||||
}
|
||||
|
||||
DWORD
|
||||
CArchMiscWindows::dummySetThreadExecutionState(DWORD)
|
||||
{
|
||||
// do nothing
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,19 @@
|
|||
//! Miscellaneous win32 functions.
|
||||
class CArchMiscWindows {
|
||||
public:
|
||||
enum EValueType {
|
||||
kUNKNOWN,
|
||||
kNO_VALUE,
|
||||
kUINT,
|
||||
kSTRING,
|
||||
kBINARY
|
||||
};
|
||||
enum EBusyModes {
|
||||
kIDLE = 0x0000,
|
||||
kSYSTEM = 0x0001,
|
||||
kDISPLAY = 0x0002
|
||||
};
|
||||
|
||||
typedef int (*RunFunc)(void);
|
||||
|
||||
//! Initialize
|
||||
|
@ -78,6 +91,9 @@ public:
|
|||
//! Test if a value exists
|
||||
static bool hasValue(HKEY key, const TCHAR* name);
|
||||
|
||||
//! Get type of value
|
||||
static EValueType typeOfValue(HKEY key, const TCHAR* name);
|
||||
|
||||
//! Set a string value in the registry
|
||||
static void setValue(HKEY key, const TCHAR* name,
|
||||
const std::string& value);
|
||||
|
@ -85,12 +101,22 @@ public:
|
|||
//! Set a DWORD value in the registry
|
||||
static void setValue(HKEY key, const TCHAR* name, DWORD value);
|
||||
|
||||
//! Set a BINARY value in the registry
|
||||
/*!
|
||||
Sets the \p name value of \p key to \p value.data().
|
||||
*/
|
||||
static void setValueBinary(HKEY key, const TCHAR* name,
|
||||
const std::string& value);
|
||||
|
||||
//! Read a string value from the registry
|
||||
static std::string readValueString(HKEY, const TCHAR* name);
|
||||
|
||||
//! Read a DWORD value from the registry
|
||||
static DWORD readValueInt(HKEY, const TCHAR* name);
|
||||
|
||||
//! Read a BINARY value from the registry
|
||||
static std::string readValueBinary(HKEY, const TCHAR* name);
|
||||
|
||||
//! Add a dialog
|
||||
static void addDialog(HWND);
|
||||
|
||||
|
@ -104,10 +130,28 @@ public:
|
|||
*/
|
||||
static bool processDialog(MSG*);
|
||||
|
||||
//! Disable power saving
|
||||
static void addBusyState(DWORD busyModes);
|
||||
|
||||
//! Enable power saving
|
||||
static void removeBusyState(DWORD busyModes);
|
||||
|
||||
private:
|
||||
//! Read a string value from the registry
|
||||
static std::string readBinaryOrString(HKEY, const TCHAR* name, DWORD type);
|
||||
|
||||
//! Set thread busy state
|
||||
static void setThreadExecutionState(DWORD);
|
||||
|
||||
static DWORD WINAPI dummySetThreadExecutionState(DWORD);
|
||||
|
||||
private:
|
||||
typedef std::set<HWND> CDialogs;
|
||||
typedef DWORD (WINAPI *STES_t)(DWORD);
|
||||
|
||||
static CDialogs* s_dialogs;
|
||||
static DWORD s_busyState;
|
||||
static STES_t s_stes;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -113,7 +113,8 @@
|
|||
HINSTANCE CMSWindowsScreen::s_instance = NULL;
|
||||
CMSWindowsScreen* CMSWindowsScreen::s_screen = NULL;
|
||||
|
||||
CMSWindowsScreen::CMSWindowsScreen(bool isPrimary) :
|
||||
CMSWindowsScreen::CMSWindowsScreen(bool isPrimary,
|
||||
IJob* suspend, IJob* resume) :
|
||||
m_isPrimary(isPrimary),
|
||||
m_is95Family(CArchMiscWindows::isWindows95Family()),
|
||||
m_isOnScreen(m_isPrimary),
|
||||
|
@ -137,16 +138,29 @@ CMSWindowsScreen::CMSWindowsScreen(bool isPrimary) :
|
|||
m_activeDesk(NULL),
|
||||
m_activeDeskName(),
|
||||
m_hookLibrary(NULL),
|
||||
m_init(NULL),
|
||||
m_cleanup(NULL),
|
||||
m_install(NULL),
|
||||
m_uninstall(NULL),
|
||||
m_setSides(NULL),
|
||||
m_setZone(NULL),
|
||||
m_setMode(NULL),
|
||||
m_installScreensaver(NULL),
|
||||
m_uninstallScreensaver(NULL),
|
||||
m_keyState(NULL),
|
||||
m_mutex(),
|
||||
m_deskReady(&m_mutex, false)
|
||||
m_deskReady(&m_mutex, false),
|
||||
m_suspend(suspend),
|
||||
m_resume(resume)
|
||||
{
|
||||
assert(s_instance != NULL);
|
||||
assert(s_screen == NULL);
|
||||
|
||||
s_screen = this;
|
||||
try {
|
||||
m_hookLibrary = openHookLibrary("synrgyhk");
|
||||
if (m_isPrimary) {
|
||||
m_hookLibrary = openHookLibrary("synrgyhk");
|
||||
}
|
||||
m_cursor = createBlankCursor();
|
||||
m_class = createWindowClass();
|
||||
m_deskClass = createDeskWindowClass(m_isPrimary);
|
||||
|
@ -171,9 +185,6 @@ CMSWindowsScreen::CMSWindowsScreen(bool isPrimary) :
|
|||
throw;
|
||||
}
|
||||
|
||||
// install our clipboard snooper
|
||||
m_nextClipboardWindow = SetClipboardViewer(m_window);
|
||||
|
||||
// install event handlers
|
||||
EVENTQUEUE->adoptHandler(CEvent::kSystem, IEventQueue::getSystemTarget(),
|
||||
new TMethodEventJob<CMSWindowsScreen>(this,
|
||||
|
@ -190,14 +201,14 @@ CMSWindowsScreen::~CMSWindowsScreen()
|
|||
disable();
|
||||
EVENTQUEUE->adoptBuffer(NULL);
|
||||
EVENTQUEUE->removeHandler(CEvent::kSystem, IEventQueue::getSystemTarget());
|
||||
removeDesks();
|
||||
ChangeClipboardChain(m_window, m_nextClipboardWindow);
|
||||
delete m_screensaver;
|
||||
destroyWindow(m_window);
|
||||
destroyClass(m_deskClass);
|
||||
destroyClass(m_class);
|
||||
destroyCursor(m_cursor);
|
||||
closeHookLibrary(m_hookLibrary);
|
||||
delete m_suspend;
|
||||
delete m_resume;
|
||||
s_screen = NULL;
|
||||
}
|
||||
|
||||
|
@ -229,6 +240,9 @@ CMSWindowsScreen::enable()
|
|||
{
|
||||
assert(m_isOnScreen == m_isPrimary);
|
||||
|
||||
// install our clipboard snooper
|
||||
m_nextClipboardWindow = SetClipboardViewer(m_window);
|
||||
|
||||
if (m_isPrimary) {
|
||||
// update shadow key state
|
||||
m_keyMapper.update(NULL);
|
||||
|
@ -239,6 +253,12 @@ CMSWindowsScreen::enable()
|
|||
// watch jump zones
|
||||
m_setMode(kHOOK_WATCH_JUMP_ZONE);
|
||||
}
|
||||
else {
|
||||
// prevent the system from entering power saving modes. if
|
||||
// it did we'd be forced to disconnect from the server and
|
||||
// the server would not be able to wake us up.
|
||||
CArchMiscWindows::addBusyState(CArchMiscWindows::kSYSTEM);
|
||||
}
|
||||
|
||||
// set the active desk and (re)install the hooks
|
||||
checkDesk();
|
||||
|
@ -263,10 +283,27 @@ CMSWindowsScreen::disable()
|
|||
m_timer = NULL;
|
||||
}
|
||||
|
||||
// disable hooks
|
||||
if (m_isPrimary) {
|
||||
// disable hooks
|
||||
m_setMode(kHOOK_DISABLE);
|
||||
|
||||
// enable special key sequences on win95 family
|
||||
enableSpecialKeys(true);
|
||||
}
|
||||
else {
|
||||
// allow the system to enter power saving mode
|
||||
CArchMiscWindows::removeBusyState(CArchMiscWindows::kSYSTEM |
|
||||
CArchMiscWindows::kDISPLAY);
|
||||
}
|
||||
|
||||
// destroy desks
|
||||
removeDesks();
|
||||
|
||||
// stop snooping the clipboard
|
||||
ChangeClipboardChain(m_window, m_nextClipboardWindow);
|
||||
m_nextClipboardWindow = NULL;
|
||||
|
||||
m_isOnScreen = m_isPrimary;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -973,6 +1010,25 @@ CMSWindowsScreen::onEvent(HWND, UINT msg,
|
|||
|
||||
case WM_DISPLAYCHANGE:
|
||||
return onDisplayChange();
|
||||
|
||||
case WM_POWERBROADCAST:
|
||||
switch (wParam) {
|
||||
case PBT_APMRESUMEAUTOMATIC:
|
||||
case PBT_APMRESUMECRITICAL:
|
||||
case PBT_APMRESUMESUSPEND:
|
||||
if (m_resume != NULL) {
|
||||
m_resume->run();
|
||||
}
|
||||
break;
|
||||
|
||||
case PBT_APMSUSPEND:
|
||||
if (m_suspend != NULL) {
|
||||
m_suspend->run();
|
||||
}
|
||||
break;
|
||||
}
|
||||
*result = TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1316,10 +1372,16 @@ CMSWindowsScreen::onScreensaver(bool activated)
|
|||
if (activated) {
|
||||
if (m_screensaver->checkStarted(SYNERGY_MSG_SCREEN_SAVER, FALSE, 0)) {
|
||||
sendEvent(getScreensaverActivatedEvent());
|
||||
|
||||
// enable display power down
|
||||
CArchMiscWindows::removeBusyState(CArchMiscWindows::kDISPLAY);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sendEvent(getScreensaverDeactivatedEvent());
|
||||
|
||||
// disable display power down
|
||||
CArchMiscWindows::addBusyState(CArchMiscWindows::kDISPLAY);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1616,7 +1678,6 @@ LRESULT CALLBACK
|
|||
CMSWindowsScreen::primaryDeskProc(
|
||||
HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// FIXME
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
@ -1893,6 +1954,7 @@ CMSWindowsScreen::deskThread(void* vdesk)
|
|||
}
|
||||
|
||||
// clean up
|
||||
deskEnter(desk);
|
||||
if (desk->m_window != NULL) {
|
||||
DestroyWindow(desk->m_window);
|
||||
}
|
||||
|
@ -1927,6 +1989,8 @@ CMSWindowsScreen::removeDesks()
|
|||
delete desk;
|
||||
}
|
||||
m_desks.clear();
|
||||
m_activeDesk = NULL;
|
||||
m_activeDeskName = "";
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1952,7 +2016,6 @@ CMSWindowsScreen::checkDesk()
|
|||
// active becaue we'd most likely switch to the screensaver desktop
|
||||
// which would have the side effect of forcing the screensaver to
|
||||
// stop.
|
||||
// FIXME -- really not switch if screensaver is active?
|
||||
if (name != m_activeDeskName && !m_screensaver->isActive()) {
|
||||
// show cursor on previous desk
|
||||
if (!m_isOnScreen) {
|
||||
|
@ -1987,24 +2050,6 @@ CMSWindowsScreen::checkDesk()
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME -- may want some of following when we switch desks. calling
|
||||
// nextMark() for isPrimary may lead to loss of events. updateKeys()
|
||||
// is to catch any key events lost between switching and detecting the
|
||||
// switch. neither are strictly necessary.
|
||||
/*
|
||||
if (m_isPrimary) {
|
||||
if (m_isOnScreen) {
|
||||
// all messages prior to now are invalid
|
||||
// FIXME -- is this necessary; couldn't we lose key releases?
|
||||
nextMark();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// update key state
|
||||
updateKeys();
|
||||
}
|
||||
*/
|
||||
|
||||
bool
|
||||
CMSWindowsScreen::isDeskAccessible(const CDesk* desk) const
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@ class CThread;
|
|||
//! Implementation of IPlatformScreen for Microsoft Windows
|
||||
class CMSWindowsScreen : public IPlatformScreen {
|
||||
public:
|
||||
CMSWindowsScreen(bool isPrimary);
|
||||
CMSWindowsScreen(bool isPrimary, IJob* suspend, IJob* resume);
|
||||
virtual ~CMSWindowsScreen();
|
||||
|
||||
//! @name manipulators
|
||||
|
@ -112,7 +112,7 @@ private:
|
|||
};
|
||||
typedef std::map<CString, CDesk*> CDesks;
|
||||
|
||||
// FIXME -- comment
|
||||
// initialization and shutdown operations
|
||||
HINSTANCE openHookLibrary(const char* name);
|
||||
void closeHookLibrary(HINSTANCE hookLibrary) const;
|
||||
HCURSOR createBlankCursor() const;
|
||||
|
@ -122,8 +122,12 @@ private:
|
|||
void destroyClass(ATOM windowClass) const;
|
||||
HWND createWindow(ATOM windowClass, const char* name) const;
|
||||
void destroyWindow(HWND) const;
|
||||
|
||||
// convenience function to send events
|
||||
void sendEvent(CEvent::Type type, void* = NULL);
|
||||
void sendClipboardEvent(CEvent::Type type, ClipboardID id);
|
||||
|
||||
// system event handler (does DispatchMessage)
|
||||
void handleSystemEvent(const CEvent& event, void*);
|
||||
|
||||
// handle message before it gets dispatched. returns true iff
|
||||
|
@ -148,7 +152,6 @@ private:
|
|||
bool onDisplayChange();
|
||||
bool onClipboardChange();
|
||||
|
||||
// XXX
|
||||
// warp cursor without discarding queued events
|
||||
void warpCursorNoFlush(SInt32 x, SInt32 y);
|
||||
|
||||
|
@ -157,7 +160,6 @@ private:
|
|||
|
||||
// test if event should be ignored
|
||||
bool ignore() const;
|
||||
// XXX
|
||||
|
||||
// update screen size cache
|
||||
void updateScreenShape();
|
||||
|
@ -278,6 +280,10 @@ private:
|
|||
// map of button state
|
||||
BYTE m_buttons[1 + kButtonExtra0 + 1];
|
||||
|
||||
// suspend/resume callbacks
|
||||
IJob* m_suspend;
|
||||
IJob* m_resume;
|
||||
|
||||
static CMSWindowsScreen* s_screen;
|
||||
};
|
||||
|
||||
|
|
|
@ -13,10 +13,12 @@
|
|||
*/
|
||||
|
||||
#include "CMSWindowsScreenSaver.h"
|
||||
#include "CMSWindowsScreen.h"
|
||||
#include "CThread.h"
|
||||
#include "CLog.h"
|
||||
#include "TMethodJob.h"
|
||||
#include "CArch.h"
|
||||
#include "CArchMiscWindows.h"
|
||||
#include <malloc.h>
|
||||
#include <tchar.h>
|
||||
|
||||
|
@ -24,11 +26,21 @@
|
|||
#define SPI_GETSCREENSAVERRUNNING 114
|
||||
#endif
|
||||
|
||||
static const TCHAR* g_isSecureNT = "ScreenSaverIsSecure";
|
||||
static const TCHAR* g_isSecure9x = "ScreenSaverUsePassword";
|
||||
static const TCHAR* const g_pathScreenSaverIsSecure[] = {
|
||||
"Control Panel",
|
||||
"Desktop",
|
||||
NULL
|
||||
};
|
||||
|
||||
//
|
||||
// CMSWindowsScreenSaver
|
||||
//
|
||||
|
||||
CMSWindowsScreenSaver::CMSWindowsScreenSaver() :
|
||||
m_wasSecure(false),
|
||||
m_wasSecureAnInt(false),
|
||||
m_process(NULL),
|
||||
m_threadID(0),
|
||||
m_watch(NULL)
|
||||
|
@ -119,6 +131,14 @@ void
|
|||
CMSWindowsScreenSaver::enable()
|
||||
{
|
||||
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, m_wasEnabled, 0, 0);
|
||||
|
||||
// restore password protection
|
||||
if (m_wasSecure) {
|
||||
setSecure(true, m_wasSecureAnInt);
|
||||
}
|
||||
|
||||
// restore display power down
|
||||
CArchMiscWindows::removeBusyState(CArchMiscWindows::kDISPLAY);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -126,6 +146,15 @@ CMSWindowsScreenSaver::disable()
|
|||
{
|
||||
SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &m_wasEnabled, 0);
|
||||
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, 0, 0);
|
||||
|
||||
// disable password protected screensaver
|
||||
m_wasSecure = isSecure(&m_wasSecureAnInt);
|
||||
if (m_wasSecure) {
|
||||
setSecure(false, m_wasSecureAnInt);
|
||||
}
|
||||
|
||||
// disable display power down
|
||||
CArchMiscWindows::addBusyState(CArchMiscWindows::kDISPLAY);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -141,6 +170,9 @@ CMSWindowsScreenSaver::activate()
|
|||
// no foreground window. pretend we got the event instead.
|
||||
DefWindowProc(NULL, WM_SYSCOMMAND, SC_SCREENSAVE, 0);
|
||||
}
|
||||
|
||||
// restore power save when screen saver activates
|
||||
CArchMiscWindows::removeBusyState(CArchMiscWindows::kDISPLAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,6 +211,9 @@ CMSWindowsScreenSaver::deactivate()
|
|||
!m_wasEnabled, 0, SPIF_SENDWININICHANGE);
|
||||
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,
|
||||
m_wasEnabled, 0, SPIF_SENDWININICHANGE);
|
||||
|
||||
// disable display power down
|
||||
CArchMiscWindows::removeBusyState(CArchMiscWindows::kDISPLAY);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -252,8 +287,11 @@ BOOL CALLBACK
|
|||
CMSWindowsScreenSaver::killScreenSaverFunc(HWND hwnd, LPARAM arg)
|
||||
{
|
||||
if (IsWindowVisible(hwnd)) {
|
||||
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
||||
*reinterpret_cast<bool*>(arg) = true;
|
||||
HINSTANCE instance = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);
|
||||
if (instance != CMSWindowsScreen::getInstance()) {
|
||||
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
||||
*reinterpret_cast<bool*>(arg) = true;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -375,3 +413,60 @@ CMSWindowsScreenSaver::watchProcessThread(void*)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsScreenSaver::setSecure(bool secure, bool saveSecureAsInt)
|
||||
{
|
||||
HKEY hkey =
|
||||
CArchMiscWindows::openKey(HKEY_CURRENT_USER, g_pathScreenSaverIsSecure);
|
||||
if (hkey == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
const TCHAR* isSecure = m_is95Family ? g_isSecure9x : g_isSecureNT;
|
||||
if (saveSecureAsInt) {
|
||||
CArchMiscWindows::setValue(hkey, isSecure, secure ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
CArchMiscWindows::setValue(hkey, isSecure, secure ? "1" : "0");
|
||||
}
|
||||
|
||||
CArchMiscWindows::closeKey(hkey);
|
||||
}
|
||||
|
||||
bool
|
||||
CMSWindowsScreenSaver::isSecure(bool* wasSecureFlagAnInt) const
|
||||
{
|
||||
// get the password protection setting key
|
||||
HKEY hkey =
|
||||
CArchMiscWindows::openKey(HKEY_CURRENT_USER, g_pathScreenSaverIsSecure);
|
||||
if (hkey == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the value. the value may be an int or a string, depending
|
||||
// on the version of windows.
|
||||
bool result;
|
||||
const TCHAR* isSecure = m_is95Family ? g_isSecure9x : g_isSecureNT;
|
||||
switch (CArchMiscWindows::typeOfValue(hkey, isSecure)) {
|
||||
default:
|
||||
result = false;
|
||||
|
||||
case CArchMiscWindows::kUINT: {
|
||||
DWORD value =
|
||||
CArchMiscWindows::readValueInt(hkey, isSecure);
|
||||
*wasSecureFlagAnInt = true;
|
||||
result = (value != 0);
|
||||
}
|
||||
|
||||
case CArchMiscWindows::kSTRING: {
|
||||
std::string value =
|
||||
CArchMiscWindows::readValueString(hkey, isSecure);
|
||||
*wasSecureFlagAnInt = false;
|
||||
result = (value != "0");
|
||||
}
|
||||
}
|
||||
|
||||
CArchMiscWindows::closeKey(hkey);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#define CMSWINDOWSSCREENSAVER_H
|
||||
|
||||
#include "IScreenSaver.h"
|
||||
#include "CString.h"
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
|
@ -65,11 +66,16 @@ private:
|
|||
void watchDesktopThread(void*);
|
||||
void watchProcessThread(void*);
|
||||
|
||||
void setSecure(bool secure, bool saveSecureAsInt);
|
||||
bool isSecure(bool* wasSecureAnInt) const;
|
||||
|
||||
private:
|
||||
bool m_is95Family;
|
||||
bool m_is95;
|
||||
bool m_isNT;
|
||||
BOOL m_wasEnabled;
|
||||
bool m_wasSecure;
|
||||
bool m_wasSecureAnInt;
|
||||
|
||||
HANDLE m_process;
|
||||
CThread* m_watch;
|
||||
|
|
Loading…
Reference in New Issue