Added support for DPMS in X11 screen saver. DPMS is the extension
that allows you to power down the display. Previously, synergy would not power on the display if DPMS was enabled and activated and xscreensaver was not running. It also wouldn't disable DPMS so the display would power down normally on a synergy client if there was no input activity.
This commit is contained in:
parent
6c7039490d
commit
a1c807ba67
|
@ -57,8 +57,8 @@ AC_PATH_XTRA
|
|||
save_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$X_CFLAGS $CPPFLAGS"
|
||||
AC_CHECK_HEADERS([X11/extensions/XTest.h])
|
||||
|
||||
AC_CHECK_LIB(Xinerama, XineramaQueryExtension, AC_CHECK_HEADERS([X11/extensions/Xinerama.h]) [X_LIBS="$X_LIBS -lXinerama"], , [$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
|
||||
AC_CHECK_LIB(Xext, DPMSQueryExtension, AC_CHECK_HEADERS([X11/extensions/dpms.h]) [X_LIBS="$X_LIBS -lXext"], , [$X_LIBS -lX11 $X_EXTRA_LIBS])
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
|
||||
dnl checks for types
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
#else
|
||||
# error The XTest extension is required to build synergy
|
||||
#endif
|
||||
#if defined(HAVE_X11_EXTENSIONS_DPMS_H)
|
||||
extern "C" {
|
||||
# include <X11/extensions/dpms.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// CXWindowsScreenSaver
|
||||
|
@ -37,6 +42,7 @@ CXWindowsScreenSaver::CXWindowsScreenSaver(
|
|||
m_eventTarget(eventTarget),
|
||||
m_xscreensaver(None),
|
||||
m_xscreensaverActive(false),
|
||||
m_dpms(false),
|
||||
m_disabled(false),
|
||||
m_suppressDisable(false),
|
||||
m_disableTimer(NULL)
|
||||
|
@ -51,6 +57,18 @@ CXWindowsScreenSaver::CXWindowsScreenSaver(
|
|||
m_atomScreenSaverDeactivate = XInternAtom(m_display,
|
||||
"DEACTIVATE", False);
|
||||
|
||||
// check for DPMS extension. this is an alternative screen saver
|
||||
// that powers down the display.
|
||||
#if defined(HAVE_X11_EXTENSIONS_DPMS_H)
|
||||
int eventBase, errorBase;
|
||||
if (DPMSQueryExtension(m_display, &eventBase, &errorBase)) {
|
||||
if (DPMSCapable(m_display)) {
|
||||
// we have DPMS
|
||||
m_dpms = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// watch top-level windows for changes
|
||||
{
|
||||
bool error = false;
|
||||
|
@ -66,15 +84,18 @@ CXWindowsScreenSaver::CXWindowsScreenSaver(
|
|||
}
|
||||
}
|
||||
|
||||
// get the built-in settings
|
||||
XGetScreenSaver(m_display, &m_timeout, &m_interval,
|
||||
&m_preferBlanking, &m_allowExposures);
|
||||
|
||||
// get the DPMS settings
|
||||
m_dpmsEnabled = isDPMSEnabled();
|
||||
|
||||
// get the xscreensaver window, if any
|
||||
if (!findXScreenSaver()) {
|
||||
setXScreenSaver(None);
|
||||
}
|
||||
|
||||
// get the built-in settings
|
||||
XGetScreenSaver(m_display, &m_timeout, &m_interval,
|
||||
&m_preferBlanking, &m_allowExposures);
|
||||
|
||||
// install disable timer event handler
|
||||
EVENTQUEUE->adoptHandler(CEvent::kTimer, this,
|
||||
new TMethodEventJob<CXWindowsScreenSaver>(this,
|
||||
|
@ -90,6 +111,7 @@ CXWindowsScreenSaver::~CXWindowsScreenSaver()
|
|||
EVENTQUEUE->removeHandler(CEvent::kTimer, this);
|
||||
|
||||
if (m_display != NULL) {
|
||||
enableDPMS(m_dpmsEnabled);
|
||||
XSetScreenSaver(m_display, m_timeout, m_interval,
|
||||
m_preferBlanking, m_allowExposures);
|
||||
clearWatchForXScreenSaver();
|
||||
|
@ -176,6 +198,9 @@ CXWindowsScreenSaver::enable()
|
|||
// for built-in X screen saver
|
||||
XSetScreenSaver(m_display, m_timeout, m_interval,
|
||||
m_preferBlanking, m_allowExposures);
|
||||
|
||||
// for DPMS
|
||||
enableDPMS(m_dpmsEnabled);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -190,6 +215,11 @@ CXWindowsScreenSaver::disable()
|
|||
&m_preferBlanking, &m_allowExposures);
|
||||
XSetScreenSaver(m_display, 0, m_interval,
|
||||
m_preferBlanking, m_allowExposures);
|
||||
|
||||
// for DPMS
|
||||
m_dpmsEnabled = isDPMSEnabled();
|
||||
enableDPMS(false);
|
||||
|
||||
// FIXME -- now deactivate?
|
||||
}
|
||||
|
||||
|
@ -200,6 +230,9 @@ CXWindowsScreenSaver::activate()
|
|||
m_suppressDisable = true;
|
||||
updateDisableTimer();
|
||||
|
||||
// enable DPMS if it was enabled
|
||||
enableDPMS(m_dpmsEnabled);
|
||||
|
||||
// try xscreensaver
|
||||
findXScreenSaver();
|
||||
if (m_xscreensaver != None) {
|
||||
|
@ -207,8 +240,13 @@ CXWindowsScreenSaver::activate()
|
|||
return;
|
||||
}
|
||||
|
||||
// use built-in X screen saver
|
||||
// try built-in X screen saver
|
||||
if (m_timeout != 0) {
|
||||
XForceScreenSaver(m_display, ScreenSaverActive);
|
||||
}
|
||||
|
||||
// try DPMS
|
||||
activateDPMS(true);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -218,6 +256,14 @@ CXWindowsScreenSaver::deactivate()
|
|||
m_suppressDisable = false;
|
||||
updateDisableTimer();
|
||||
|
||||
// try DPMS
|
||||
activateDPMS(false);
|
||||
|
||||
// disable DPMS if screen saver is disabled
|
||||
if (m_disabled) {
|
||||
enableDPMS(false);
|
||||
}
|
||||
|
||||
// try xscreensaver
|
||||
findXScreenSaver();
|
||||
if (m_xscreensaver != None) {
|
||||
|
@ -237,6 +283,11 @@ CXWindowsScreenSaver::isActive() const
|
|||
return m_xscreensaverActive;
|
||||
}
|
||||
|
||||
// check DPMS
|
||||
if (isDPMSActivated()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// can't check built-in X screen saver activity
|
||||
return false;
|
||||
}
|
||||
|
@ -282,6 +333,9 @@ CXWindowsScreenSaver::setXScreenSaver(Window window)
|
|||
XWindowAttributes attr;
|
||||
XGetWindowAttributes(m_display, m_xscreensaver, &attr);
|
||||
setXScreenSaverActive(!error && attr.map_state != IsUnmapped);
|
||||
|
||||
// save current DPMS state; xscreensaver may have changed it.
|
||||
m_dpmsEnabled = isDPMSEnabled();
|
||||
}
|
||||
else {
|
||||
// screen saver can't be active if it doesn't exist
|
||||
|
@ -450,3 +504,66 @@ CXWindowsScreenSaver::handleDisableTimer(const CEvent&, void*)
|
|||
XSendEvent(m_display, m_xscreensaver, False, 0, &event);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreenSaver::activateDPMS(bool activate)
|
||||
{
|
||||
#if defined(HAVE_X11_EXTENSIONS_DPMS_H)
|
||||
if (m_dpms) {
|
||||
// DPMSForceLevel will generate a BadMatch if DPMS is disabled
|
||||
CXWindowsUtil::CErrorLock lock(m_display);
|
||||
DPMSForceLevel(m_display, activate ? DPMSModeStandby : DPMSModeOn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreenSaver::enableDPMS(bool enable)
|
||||
{
|
||||
#if defined(HAVE_X11_EXTENSIONS_DPMS_H)
|
||||
if (m_dpms) {
|
||||
if (enable) {
|
||||
DPMSEnable(m_display);
|
||||
}
|
||||
else {
|
||||
DPMSDisable(m_display);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
CXWindowsScreenSaver::isDPMSEnabled() const
|
||||
{
|
||||
#if defined(HAVE_X11_EXTENSIONS_DPMS_H)
|
||||
if (m_dpms) {
|
||||
CARD16 level;
|
||||
BOOL state;
|
||||
DPMSInfo(m_display, &level, &state);
|
||||
return (state != False);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
CXWindowsScreenSaver::isDPMSActivated() const
|
||||
{
|
||||
#if defined(HAVE_X11_EXTENSIONS_DPMS_H)
|
||||
if (m_dpms) {
|
||||
CARD16 level;
|
||||
BOOL state;
|
||||
DPMSInfo(m_display, &level, &state);
|
||||
return (level != DPMSModeOn);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -92,6 +92,18 @@ private:
|
|||
// called periodically to prevent the screen saver from starting
|
||||
void handleDisableTimer(const CEvent&, void*);
|
||||
|
||||
// force DPMS to activate or deactivate
|
||||
void activateDPMS(bool activate);
|
||||
|
||||
// enable/disable DPMS screen saver
|
||||
void enableDPMS(bool);
|
||||
|
||||
// check if DPMS is enabled
|
||||
bool isDPMSEnabled() const;
|
||||
|
||||
// check if DPMS is activate
|
||||
bool isDPMSActivated() const;
|
||||
|
||||
private:
|
||||
typedef std::map<Window, long> CWatchList;
|
||||
|
||||
|
@ -128,6 +140,10 @@ private:
|
|||
int m_preferBlanking;
|
||||
int m_allowExposures;
|
||||
|
||||
// DPMS screen saver settings
|
||||
bool m_dpms;
|
||||
bool m_dpmsEnabled;
|
||||
|
||||
// true iff the client wants the screen saver suppressed
|
||||
bool m_disabled;
|
||||
|
||||
|
|
Loading…
Reference in New Issue