[mythtv] screensaver patch
Cliff Draper
Cliff.Draper at Sun.COM
Mon Dec 22 17:09:04 EST 2003
I'm attaching the patch for automatic disabling of screensavers
(standard X blanking, DPMS, and xscreensaver). It adds the following
functions to util.cpp:
void ScreenSaverOff();
void ScreenSaverRestore();
void ResetScreenSaver();
which are called at the right locations when the video player makes a
state transition, when pause is engaged or disengaged, and when
myth_system is called.
Since xscreensaver requires a constant deactivate message, I decided
to write that using a small perl script, rather than add another
thread to mythfrontend.
Here's what I have in my .xsession (which uses xscreensaver and not
the others):
xset s off
xset -dpms
xscreensaver -nosplash &
xscreensaver-keeper &
regards,
Cliff Draper Sun Microsystems, Forte Tools
My opinions may or may not reflect those of my employer.
---------------------------- food for thought ---------------------------
"The one thing that unites all human beings, regardless of age,
gender, religion, economic status, or ethnic background, is that, deep
down inside, we ALL believe that we are above-average drivers." -Dave Barry
-------------- next part --------------
Index: settings.pro
===================================================================
RCS file: /var/lib/mythcvs/mythtv/settings.pro,v
retrieving revision 1.40
diff -u -r1.40 settings.pro
--- settings.pro 23 Oct 2003 19:57:17 -0000 1.40
+++ settings.pro 22 Dec 2003 21:51:49 -0000
@@ -43,3 +43,6 @@
# VIA cle266 support
#CONFIG += using_viahwslice
#EXTRA_LIBS += -lddmpeg
+
+DEFINES += STANDARD_X_SCREENSAVER
+DEFINES += XSCREENSAVER_KEEPER
Index: libs/libmyth/util.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/util.cpp,v
retrieving revision 1.31
diff -u -r1.31 util.cpp
--- libs/libmyth/util.cpp 14 Dec 2003 19:46:51 -0000 1.31
+++ libs/libmyth/util.cpp 22 Dec 2003 21:51:52 -0000
@@ -3,6 +3,7 @@
#include <unistd.h>
#include <iostream>
+#include <fstream>
using namespace std;
#include "util.h"
@@ -12,6 +13,26 @@
extern "C" {
#include <X11/Xlib.h>
#include <X11/extensions/Xinerama.h>
+
+#ifdef STANDARD_X_SCREENSAVER
+ /* It would have been better to #include <X11/extensions/dpms.h>, but that didn't work for me; so including them manually. */
+ typedef unsigned short CARD16;
+ extern int XActivateScreenSaver(Display* display);
+ extern int XGetScreenSaver(Display* display, int* timeout_return,
+ int* interval_return, int* prefer_blanking_return,
+ int* allow_exposures_return);
+ extern int XSetScreenSaver(Display* display, int timeout,
+ int interval, int prefer_blanking,
+ int allow_exposures);
+ extern int XResetScreenSaver(Display* display);
+ extern int DPMSGetTimeouts(Display* display, CARD16* standby,
+ CARD16* suspend, CARD16* off);
+ extern int DPMSSetTimeouts(Display* display, CARD16 standby,
+ CARD16 suspend, CARD16 off);
+ extern int DPMSInfo(Display *, CARD16 *, unsigned char *);
+ extern int DPMSEnable(Display *);
+ extern int DPMSDisable(Display *);
+#endif
}
#endif
@@ -555,7 +576,10 @@
(void)flags;
#endif
- return system(command);
+ ScreenSaverOff();
+ int result = system(command);
+ ScreenSaverRestore();
+ return result;
}
QString cutDownString(QString text, QFont *testFont, int maxwidth)
@@ -584,3 +608,76 @@
return text;
}
+
+#ifdef XSCREENSAVER_KEEPER
+#define XSCREENSAVER_KEEPER_FILE "/tmp/keep-xscreensaver"
+#define XSCREENSAVER_RESET_FILE "/tmp/reset-xscreensaver"
+#endif
+#ifdef STANDARD_X_SCREENSAVER
+static int screenSaverTimeout, screenSaverInterval, screenSaverPreferBlank, screenSaverAllowExposure;
+static bool reenableDPMSOnRestore;
+#endif
+
+void ResetScreenSaver()
+{
+ //cout << "ResetScreenSaver" << endl;
+#ifdef STANDARD_X_SCREENSAVER
+ XResetScreenSaver(qt_xdisplay());
+#endif
+#ifdef XSCREENSAVER_KEEPER
+ ofstream fout;
+ fout.open(XSCREENSAVER_RESET_FILE);
+ fout.close();
+#endif
+}
+
+void ScreenSaverOff()
+{
+ //cout << "ScreenSaverOff" << endl;
+#ifdef XSCREENSAVER_KEEPER
+ // Need to create the file to turn off xscreensaver
+ ofstream fout;
+ fout.open(XSCREENSAVER_KEEPER_FILE);
+ fout.close();
+#endif
+
+#ifdef STANDARD_X_SCREENSAVER
+ XGetScreenSaver(qt_xdisplay(), &screenSaverTimeout, &screenSaverInterval,
+ &screenSaverPreferBlank, &screenSaverAllowExposure);
+ //cout << "timeout=" << screenSaverTimeout << " interval=" << screenSaverInterval << endl;
+ //cout << "PreferBlank=" << screenSaverPreferBlank << " allow_exposure=" << screenSaverAllowExposure << endl;
+ XSetScreenSaver(qt_xdisplay(), 0, 0, 0, 0);
+
+ CARD16 power_level;
+ unsigned char state;
+ int result = DPMSInfo(qt_xdisplay(), &power_level, &state);
+ //cout << "DPMSInfo result=" << result << endl;
+ //cout << "power_level " << power_level << " state " << (int) state << endl;
+ if (state != 0) {
+ reenableDPMSOnRestore = true;
+ result = DPMSDisable(qt_xdisplay());
+ //cout << "DPMSDisable result=" << result << endl;
+ } else {
+ reenableDPMSOnRestore = false;
+ }
+#endif
+}
+
+void ScreenSaverRestore()
+{
+ //cout << "ScreenSaverRestore" << endl;
+ // Reset the timer on the screen saver, so that when we restore it, it
+ // doesn't suddenly come on.
+ ResetScreenSaver();
+#ifdef STANDARD_X_SCREENSAVER
+ if (reenableDPMSOnRestore) {
+ int result = DPMSEnable(qt_xdisplay());
+ //cout << "DPMSEnable result=" << result << endl;
+ }
+ XSetScreenSaver(qt_xdisplay(), screenSaverTimeout, screenSaverInterval,
+ screenSaverPreferBlank, screenSaverAllowExposure);
+#endif
+#ifdef XSCREENSAVER_KEEPER
+ unlink(XSCREENSAVER_KEEPER_FILE);
+#endif
+}
Index: libs/libmyth/util.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/util.h,v
retrieving revision 1.13
diff -u -r1.13 util.h
--- libs/libmyth/util.h 11 Dec 2003 22:48:33 -0000 1.13
+++ libs/libmyth/util.h 22 Dec 2003 21:51:52 -0000
@@ -31,6 +31,10 @@
long long decodeLongLong(QStringList &list, int offset);
long long decodeLongLong(QStringList &list, QStringList::iterator &it);
+void ScreenSaverOff();
+void ScreenSaverRestore();
+void ResetScreenSaver();
+
#ifndef QWS
void GetMythTVGeometry(Display *dpy, int screen_num, int *x, int *y,
int *w, int *h);
Index: libs/libmythtv/tv_play.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/tv_play.cpp,v
retrieving revision 1.135
diff -u -r1.135 tv_play.cpp
--- libs/libmythtv/tv_play.cpp 22 Dec 2003 19:51:20 -0000 1.135
+++ libs/libmythtv/tv_play.cpp 22 Dec 2003 21:51:55 -0000
@@ -500,6 +500,7 @@
recorder->SpawnLiveTV();
+ ScreenSaverOff();
StartPlayerAndRecorder(true, true);
}
else if (internalState == kState_WatchingLiveTV &&
@@ -509,6 +510,7 @@
changed = true;
StopPlayerAndRecorder(true, true);
+ ScreenSaverRestore();
}
else if (internalState == kState_WatchingRecording &&
nextState == kState_WatchingPreRecorded)
@@ -521,6 +523,7 @@
(internalState == kState_None &&
nextState == kState_WatchingRecording))
{
+ ScreenSaverOff();
prbuffer = new RingBuffer(inputFilename, false);
if (nextState == kState_WatchingRecording)
@@ -559,6 +562,7 @@
changed = true;
StopPlayerAndRecorder(true, false);
+ ScreenSaverRestore();
}
else if (internalState == kState_None &&
nextState == kState_None)
@@ -1507,10 +1511,13 @@
if (activenvp != nvp)
return;
- if (paused)
+ if (paused) {
UpdatePosOSD(time, tr("Paused"));
- else
+ ScreenSaverRestore();
+ } else {
osd->EndPause();
+ ScreenSaverOff();
+ }
}
void TV::DoInfo(void)
Index: programs/mythfrontend/main.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/programs/mythfrontend/main.cpp,v
retrieving revision 1.126
diff -u -r1.126 main.cpp
--- programs/mythfrontend/main.cpp 16 Dec 2003 23:17:28 -0000 1.126
+++ programs/mythfrontend/main.cpp 22 Dec 2003 21:51:57 -0000
@@ -520,6 +520,20 @@
TV::InitKeys();
}
+#ifdef STANDARD_X_SCREENSAVER
+class MainEventFilter : public QObject {
+public:
+ MainEventFilter() {}
+
+ bool eventFilter(QObject *o, QEvent *event) {
+ if (event->type() == QEvent::KeyPress) {
+ ResetScreenSaver();
+ }
+ return false;
+ }
+};
+#endif
+
int main(int argc, char **argv)
{
QString lcd_host;
@@ -736,6 +750,11 @@
mainWindow->Init();
gContext->SetMainWindow(mainWindow);
+#ifdef STANDARD_X_SCREENSAVER
+ MainEventFilter *mainEventFilter = new MainEventFilter();
+ a.installEventFilter(mainEventFilter);
+#endif
+
InitJumpPoints();
MythPluginManager::init();
-------------- next part --------------
#!/usr/bin/perl -w
$keepFile = "/tmp/keep-xscreensaver";
$resetFile = "/tmp/reset-xscreensaver";
$dotXscreensaver = "$ENV{HOME}/.xscreensaver";
$SIG{'HUP'} = 'readDotXscreensaver';
$sleepTime=60;
$sleepTimeWhileSavedScreen = 2;
&readDotXscreensaver;
#$sleepTime=2; # For testing
printf("Sleep time is $sleepTime\n");
while (1) {
$deactivate = 0;
if (-f $resetFile) {
$deactivate = 1;
unlink $resetFile;
#printf("Found $resetFile\n");
} else {
if (-f $keepFile) {
$deactivate = 1;
# Someone else unlinks the keepFile
#printf("Found $keepFile\n");
} else {
#printf("Did not find it\n");
}
}
if ($deactivate) {
system "xscreensaver-command -deactivate";
# Now sleep just enough time to come back again and disable it.
sleep $sleepTime;
} else {
# The screen is currently saved (or will be in a second).
# Wait only a short amount of time, so that our response time to
# disabling it is quick.
sleep $sleepTimeWhileSavedScreen;
}
}
sub readDotXscreensaver {
if (open(RC, $dotXscreensaver)) {
while (defined($line = <RC>)) {
if ($line =~ /^timeout:\s*(.*)/) {
$time=$1;
#printf("Found $time\n");
($hours, $minutes, $seconds) = split(":", $time);
$sleepTime = $seconds + 60*$minutes + 3600*$hours - 1; # subtract 1 so that we can beat the screensaver
}
}
close(RC);
}
}
More information about the mythtv-dev
mailing list