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:
crs 2004-03-10 22:03:01 +00:00
parent 6c7039490d
commit a1c807ba67
3 changed files with 140 additions and 7 deletions

View File

@ -57,8 +57,8 @@ AC_PATH_XTRA
save_CPPFLAGS="$CPPFLAGS" save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$X_CFLAGS $CPPFLAGS" CPPFLAGS="$X_CFLAGS $CPPFLAGS"
AC_CHECK_HEADERS([X11/extensions/XTest.h]) 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(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" CPPFLAGS="$save_CPPFLAGS"
dnl checks for types dnl checks for types

View File

@ -25,6 +25,11 @@
#else #else
# error The XTest extension is required to build synergy # error The XTest extension is required to build synergy
#endif #endif
#if defined(HAVE_X11_EXTENSIONS_DPMS_H)
extern "C" {
# include <X11/extensions/dpms.h>
}
#endif
// //
// CXWindowsScreenSaver // CXWindowsScreenSaver
@ -37,6 +42,7 @@ CXWindowsScreenSaver::CXWindowsScreenSaver(
m_eventTarget(eventTarget), m_eventTarget(eventTarget),
m_xscreensaver(None), m_xscreensaver(None),
m_xscreensaverActive(false), m_xscreensaverActive(false),
m_dpms(false),
m_disabled(false), m_disabled(false),
m_suppressDisable(false), m_suppressDisable(false),
m_disableTimer(NULL) m_disableTimer(NULL)
@ -51,6 +57,18 @@ CXWindowsScreenSaver::CXWindowsScreenSaver(
m_atomScreenSaverDeactivate = XInternAtom(m_display, m_atomScreenSaverDeactivate = XInternAtom(m_display,
"DEACTIVATE", False); "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 // watch top-level windows for changes
{ {
bool error = false; 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 // get the xscreensaver window, if any
if (!findXScreenSaver()) { if (!findXScreenSaver()) {
setXScreenSaver(None); setXScreenSaver(None);
} }
// get the built-in settings
XGetScreenSaver(m_display, &m_timeout, &m_interval,
&m_preferBlanking, &m_allowExposures);
// install disable timer event handler // install disable timer event handler
EVENTQUEUE->adoptHandler(CEvent::kTimer, this, EVENTQUEUE->adoptHandler(CEvent::kTimer, this,
new TMethodEventJob<CXWindowsScreenSaver>(this, new TMethodEventJob<CXWindowsScreenSaver>(this,
@ -90,6 +111,7 @@ CXWindowsScreenSaver::~CXWindowsScreenSaver()
EVENTQUEUE->removeHandler(CEvent::kTimer, this); EVENTQUEUE->removeHandler(CEvent::kTimer, this);
if (m_display != NULL) { if (m_display != NULL) {
enableDPMS(m_dpmsEnabled);
XSetScreenSaver(m_display, m_timeout, m_interval, XSetScreenSaver(m_display, m_timeout, m_interval,
m_preferBlanking, m_allowExposures); m_preferBlanking, m_allowExposures);
clearWatchForXScreenSaver(); clearWatchForXScreenSaver();
@ -176,6 +198,9 @@ CXWindowsScreenSaver::enable()
// for built-in X screen saver // for built-in X screen saver
XSetScreenSaver(m_display, m_timeout, m_interval, XSetScreenSaver(m_display, m_timeout, m_interval,
m_preferBlanking, m_allowExposures); m_preferBlanking, m_allowExposures);
// for DPMS
enableDPMS(m_dpmsEnabled);
} }
void void
@ -190,6 +215,11 @@ CXWindowsScreenSaver::disable()
&m_preferBlanking, &m_allowExposures); &m_preferBlanking, &m_allowExposures);
XSetScreenSaver(m_display, 0, m_interval, XSetScreenSaver(m_display, 0, m_interval,
m_preferBlanking, m_allowExposures); m_preferBlanking, m_allowExposures);
// for DPMS
m_dpmsEnabled = isDPMSEnabled();
enableDPMS(false);
// FIXME -- now deactivate? // FIXME -- now deactivate?
} }
@ -200,6 +230,9 @@ CXWindowsScreenSaver::activate()
m_suppressDisable = true; m_suppressDisable = true;
updateDisableTimer(); updateDisableTimer();
// enable DPMS if it was enabled
enableDPMS(m_dpmsEnabled);
// try xscreensaver // try xscreensaver
findXScreenSaver(); findXScreenSaver();
if (m_xscreensaver != None) { if (m_xscreensaver != None) {
@ -207,10 +240,15 @@ CXWindowsScreenSaver::activate()
return; return;
} }
// use built-in X screen saver // try built-in X screen saver
if (m_timeout != 0) {
XForceScreenSaver(m_display, ScreenSaverActive); XForceScreenSaver(m_display, ScreenSaverActive);
} }
// try DPMS
activateDPMS(true);
}
void void
CXWindowsScreenSaver::deactivate() CXWindowsScreenSaver::deactivate()
{ {
@ -218,6 +256,14 @@ CXWindowsScreenSaver::deactivate()
m_suppressDisable = false; m_suppressDisable = false;
updateDisableTimer(); updateDisableTimer();
// try DPMS
activateDPMS(false);
// disable DPMS if screen saver is disabled
if (m_disabled) {
enableDPMS(false);
}
// try xscreensaver // try xscreensaver
findXScreenSaver(); findXScreenSaver();
if (m_xscreensaver != None) { if (m_xscreensaver != None) {
@ -237,6 +283,11 @@ CXWindowsScreenSaver::isActive() const
return m_xscreensaverActive; return m_xscreensaverActive;
} }
// check DPMS
if (isDPMSActivated()) {
return true;
}
// can't check built-in X screen saver activity // can't check built-in X screen saver activity
return false; return false;
} }
@ -282,6 +333,9 @@ CXWindowsScreenSaver::setXScreenSaver(Window window)
XWindowAttributes attr; XWindowAttributes attr;
XGetWindowAttributes(m_display, m_xscreensaver, &attr); XGetWindowAttributes(m_display, m_xscreensaver, &attr);
setXScreenSaverActive(!error && attr.map_state != IsUnmapped); setXScreenSaverActive(!error && attr.map_state != IsUnmapped);
// save current DPMS state; xscreensaver may have changed it.
m_dpmsEnabled = isDPMSEnabled();
} }
else { else {
// screen saver can't be active if it doesn't exist // 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); 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
}

View File

@ -92,6 +92,18 @@ private:
// called periodically to prevent the screen saver from starting // called periodically to prevent the screen saver from starting
void handleDisableTimer(const CEvent&, void*); 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: private:
typedef std::map<Window, long> CWatchList; typedef std::map<Window, long> CWatchList;
@ -128,6 +140,10 @@ private:
int m_preferBlanking; int m_preferBlanking;
int m_allowExposures; int m_allowExposures;
// DPMS screen saver settings
bool m_dpms;
bool m_dpmsEnabled;
// true iff the client wants the screen saver suppressed // true iff the client wants the screen saver suppressed
bool m_disabled; bool m_disabled;