MythTV  master
screensaver-x11.cpp
Go to the documentation of this file.
1 // Own header
2 #include "screensaver-x11.h"
3 
4 // QT headers
5 #include <QDateTime>
6 #include <QTimer>
7 
8 // Mythdb headers
9 #include "mythlogging.h"
10 #include "mythdate.h"
11 #include "mythdb.h"
12 
13 // Mythui headers
14 #include "mythsystemlegacy.h"
15 #include "mythxdisplay.h"
16 
17 // X11 headers
18 #include <X11/Xlib.h>
19 
20 extern "C" {
21 #include <X11/extensions/dpms.h>
22 }
23 
24 #define LOC QString("ScreenSaverX11Private: ")
25 
27 {
28  friend class ScreenSaverX11;
29 
30  public:
32  {
36  myth_system("xscreensaver-command -version >&- 2>&-",
37  flags) == 0;
38 
40  {
41  m_resetTimer = new QTimer(outer);
42  m_resetTimer->setSingleShot(false);
43  QObject::connect(m_resetTimer, SIGNAL(timeout()),
44  outer, SLOT(resetSlot()));
46  LOG(VB_GENERAL, LOG_INFO, LOC + "XScreenSaver support enabled");
47  }
48 
50  if (m_display)
51  {
52  int dummy0 = 0;
53  int dummy1 = 0;
54  m_dpmsaware = (DPMSQueryExtension(m_display->GetDisplay(),
55  &dummy0, &dummy1) != 0);
56  }
57  else
58  {
59  LOG(VB_GENERAL, LOG_ERR, LOC +
60  "Failed to open connection to X11 server");
61  }
62 
63  if (m_dpmsaware && m_display)
64  {
65  CARD16 power_level = 0;
66 
67  /* If someone runs into X server weirdness that goes away when
68  * they externally disable DPMS, then the 'dpmsenabled' test should
69  * be short circuited by a call to 'DPMSCapable()'. Be sure to
70  * manually initialize dpmsenabled to false.
71  */
72 
73  DPMSInfo(m_display->GetDisplay(), &power_level, &m_dpmsenabled);
74 
75  if (static_cast<bool>(m_dpmsenabled))
76  LOG(VB_GENERAL, LOG_INFO, LOC + "DPMS is active.");
77  else
78  LOG(VB_GENERAL, LOG_INFO, LOC + "DPMS is disabled.");
79  }
80  else
81  {
82  LOG(VB_GENERAL, LOG_INFO, LOC + "DPMS is not supported.");
83  }
84  }
85 
87  {
88  // m_resetTimer deleted by ScreenSaverX11 QObject dtor
89  delete m_display;
90  }
91 
92  bool IsScreenSaverRunning(void) const
93  {
94  return m_xscreensaverRunning;
95  }
96 
97  bool IsDPMSEnabled(void) const { return static_cast<bool>(m_dpmsenabled); }
98 
99  void StopTimer(void)
100  {
101  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + "StopTimer");
102  if (m_resetTimer)
103  m_resetTimer->stop();
104  }
105 
106  void StartTimer(void)
107  {
108  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + "StartTimer");
109  if (m_resetTimer)
111  }
112 
113  void ResetTimer(void)
114  {
115  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + "ResetTimer -- begin");
116 
117  StopTimer();
118 
119  if (m_timeoutInterval == -1)
120  {
122  "xscreensaverInterval", GetMythDB()->GetHostName(), 50) * 1000;
123  }
124 
125  if (m_timeoutInterval > 0)
126  StartTimer();
127 
128  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + "ResetTimer -- end");
129  }
130 
131  // DPMS
132  bool DeactivatedDPMS(void) const
133  {
134  return m_dpmsdeactivated;
135  }
136 
137  void DisableDPMS(void)
138  {
139  if (IsDPMSEnabled() && m_display)
140  {
141  m_dpmsdeactivated = true;
142  Status status = DPMSDisable(m_display->GetDisplay());
143  m_display->Sync();
144  LOG(VB_GENERAL, LOG_INFO, LOC +
145  QString("DPMS Deactivated %1").arg(status));
146  }
147  }
148 
149  void RestoreDPMS(void)
150  {
152  {
153  m_dpmsdeactivated = false;
154  Status status = DPMSEnable(m_display->GetDisplay());
155  m_display->Sync();
156  LOG(VB_GENERAL, LOG_INFO, LOC +
157  QString("DPMS Reactivated %1").arg(status));
158  }
159  }
160 
161  void SaveScreenSaver(void)
162  {
163  if (!m_state.m_saved && m_display)
164  {
165  XGetScreenSaver(m_display->GetDisplay(), &m_state.m_timeout,
168  m_state.m_saved = true;
169  }
170  }
171 
173  {
174  if (m_state.m_saved && m_display)
175  {
176  XSetScreenSaver(m_display->GetDisplay(), m_state.m_timeout,
179  m_display->Sync();
180  m_state.m_saved = false;
181  }
182  }
183 
184  void ResetScreenSaver(void)
185  {
186  if (!IsScreenSaverRunning())
187  return;
188 
189  QDateTime current_time = MythDate::current();
190  if ((!m_lastDeactivated.isValid()) ||
191  (m_lastDeactivated.secsTo(current_time) > 30))
192  {
194  {
195  LOG(VB_PLAYBACK, LOG_INFO, LOC +
196  "Calling xscreensaver-command -deactivate");
197  myth_system("xscreensaver-command -deactivate >&- 2>&- &",
201  }
202  m_lastDeactivated = current_time;
203  }
204  }
205 
206  private:
208  {
209  public:
210  ScreenSaverState() = default;
211  bool m_saved {false};
212  int m_timeout {-1};
213  int m_interval {-1};
214  int m_preferblank {-1};
215  int m_allowexposure {-1};
216  };
217 
218  private:
219  bool m_dpmsaware {false};
220  bool m_dpmsdeactivated {false};
221  bool m_xscreensaverRunning {false};
222  BOOL m_dpmsenabled {static_cast<BOOL>(false)};
223 
225  QTimer *m_resetTimer {nullptr};
226 
227  QDateTime m_lastDeactivated;
228 
231 };
232 
234  d(new ScreenSaverX11Private(this))
235 {
236 }
237 
239 {
240  /* Ensure DPMS gets left as it was found. */
241  if (d->DeactivatedDPMS())
243 
244  delete d;
245 }
246 
248 {
249  d->SaveScreenSaver();
250 
251  if (d->m_display)
252  {
253  XResetScreenSaver(d->m_display->GetDisplay());
254  XSetScreenSaver(d->m_display->GetDisplay(), 0, 0, 0, 0);
255  d->m_display->Sync();
256  }
257 
258  d->DisableDPMS();
259 
260  if (d->IsScreenSaverRunning())
261  d->ResetTimer();
262 }
263 
265 {
267  d->RestoreDPMS();
268 
269  // One must reset after the restore
270  if (d->m_display)
271  {
272  XResetScreenSaver(d->m_display->GetDisplay());
273  d->m_display->Sync();
274  }
275 
276  if (d->IsScreenSaverRunning())
277  d->StopTimer();
278 }
279 
281 {
282  bool need_xsync = false;
283  Display *dsp = nullptr;
284  if (d->m_display)
285  dsp = d->m_display->GetDisplay();
286 
287  if (dsp)
288  {
289  XResetScreenSaver(dsp);
290  need_xsync = true;
291  }
292 
293  if (d->IsScreenSaverRunning())
294  resetSlot();
295 
296  if (Asleep() && dsp)
297  {
298  DPMSForceLevel(dsp, DPMSModeOn);
299  need_xsync = true;
300  }
301 
302  if (need_xsync && d->m_display)
303  d->m_display->Sync();
304 }
305 
307 {
308  if (!d->IsDPMSEnabled())
309  return false;
310 
311  if (d->DeactivatedDPMS())
312  return false;
313 
314  BOOL on = static_cast<BOOL>(false);
315  CARD16 power_level = DPMSModeOn;
316 
317  if (d->m_display)
318  DPMSInfo(d->m_display->GetDisplay(), &power_level, &on);
319 
320  return (power_level != DPMSModeOn);
321 }
322 
324 {
325  d->ResetScreenSaver();
326 }
ScreenSaverX11Private::ScreenSaverState::m_interval
int m_interval
Definition: screensaver-x11.cpp:213
LOC
#define LOC
Definition: screensaver-x11.cpp:24
ScreenSaverX11Private::m_xscreensaverRunning
bool m_xscreensaverRunning
Definition: screensaver-x11.cpp:221
myth_system
uint myth_system(const QString &command, uint flags, uint timeout)
Definition: mythsystemlegacy.cpp:501
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
ScreenSaverX11::resetSlot
void resetSlot()
Definition: screensaver-x11.cpp:323
ScreenSaverX11Private::SaveScreenSaver
void SaveScreenSaver(void)
Definition: screensaver-x11.cpp:161
kMSDontBlockInputDevs
@ kMSDontBlockInputDevs
avoid blocking LIRC & Joystick Menu
Definition: mythsystem.h:34
mythdb.h
ScreenSaverX11Private::~ScreenSaverX11Private
~ScreenSaverX11Private()
Definition: screensaver-x11.cpp:86
ScreenSaverX11Private::m_dpmsaware
bool m_dpmsaware
Definition: screensaver-x11.cpp:219
ScreenSaverX11Private::RestoreDPMS
void RestoreDPMS(void)
Definition: screensaver-x11.cpp:149
ScreenSaverX11Private::StartTimer
void StartTimer(void)
Definition: screensaver-x11.cpp:106
arg
arg(title).arg(filename).arg(doDelete))
ScreenSaverX11Private::m_dpmsenabled
BOOL m_dpmsenabled
Definition: screensaver-x11.cpp:222
ScreenSaverX11::Asleep
bool Asleep(void) override
Definition: screensaver-x11.cpp:306
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:46
screensaver-x11.h
ScreenSaverX11Private::StopTimer
void StopTimer(void)
Definition: screensaver-x11.cpp:99
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
MythXDisplay::OpenMythXDisplay
static MythXDisplay * OpenMythXDisplay(bool Warn=true)
Definition: mythxdisplay.cpp:44
ScreenSaverX11::ScreenSaverX11
ScreenSaverX11()
Definition: screensaver-x11.cpp:233
ScreenSaverX11Private::RestoreScreenSaver
void RestoreScreenSaver(void)
Definition: screensaver-x11.cpp:172
mythsystemlegacy.h
ScreenSaverX11::Restore
void Restore(void) override
Definition: screensaver-x11.cpp:264
ScreenSaverX11Private::ScreenSaverState::m_preferblank
int m_preferblank
Definition: screensaver-x11.cpp:214
mythdate.h
ScreenSaverX11Private::m_lastDeactivated
QDateTime m_lastDeactivated
Definition: screensaver-x11.cpp:227
mythlogging.h
ScreenSaverX11Private::ScreenSaverState::m_timeout
int m_timeout
Definition: screensaver-x11.cpp:212
ScreenSaverX11Private::DeactivatedDPMS
bool DeactivatedDPMS(void) const
Definition: screensaver-x11.cpp:132
ScreenSaverX11
Definition: screensaver-x11.h:9
MythDB::GetNumSettingOnHost
int GetNumSettingOnHost(const QString &key, const QString &host, int defaultval)
Definition: mythdb.cpp:685
ScreenSaverX11Private::m_dpmsdeactivated
bool m_dpmsdeactivated
true if we disabled DPMS
Definition: screensaver-x11.cpp:220
ScreenSaverX11Private::ScreenSaverState::m_allowexposure
int m_allowexposure
Definition: screensaver-x11.cpp:215
ScreenSaverX11::d
class ScreenSaverX11Private * d
Definition: screensaver-x11.h:26
ScreenSaverX11::Reset
void Reset(void) override
Definition: screensaver-x11.cpp:280
uint
unsigned int uint
Definition: compat.h:140
ScreenSaverX11::~ScreenSaverX11
~ScreenSaverX11() override
Definition: screensaver-x11.cpp:238
MythXDisplay::GetDisplay
Display * GetDisplay(void)
Definition: mythxdisplay.h:31
kMSRunBackground
@ kMSRunBackground
run child in the background
Definition: mythsystem.h:36
mythxdisplay.h
ScreenSaverX11Private::ScreenSaverState::ScreenSaverState
ScreenSaverState()=default
MythXDisplay::Sync
void Sync(bool Flush=false)
Definition: mythxdisplay.cpp:147
ScreenSaverX11Private::DisableDPMS
void DisableDPMS(void)
Definition: screensaver-x11.cpp:137
kMSProcessEvents
@ kMSProcessEvents
process events while waiting
Definition: mythsystem.h:37
MythXDisplay
Definition: mythxdisplay.h:22
ScreenSaverX11Private::ScreenSaverState::m_saved
bool m_saved
Definition: screensaver-x11.cpp:211
ScreenSaverX11Private
Definition: screensaver-x11.cpp:27
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
ScreenSaverX11Private::m_resetTimer
QTimer * m_resetTimer
Definition: screensaver-x11.cpp:225
ScreenSaverX11Private::IsScreenSaverRunning
bool IsScreenSaverRunning(void) const
Definition: screensaver-x11.cpp:92
kMSDontDisableDrawing
@ kMSDontDisableDrawing
avoid disabling UI drawing
Definition: mythsystem.h:35
ScreenSaverX11Private::ResetScreenSaver
void ResetScreenSaver(void)
Definition: screensaver-x11.cpp:184
ScreenSaverX11Private::ResetTimer
void ResetTimer(void)
Definition: screensaver-x11.cpp:113
ScreenSaverX11Private::ScreenSaverX11Private
ScreenSaverX11Private(ScreenSaverX11 *outer)
Definition: screensaver-x11.cpp:31
ScreenSaverX11Private::m_state
ScreenSaverState m_state
Definition: screensaver-x11.cpp:229
ScreenSaverX11Private::ScreenSaverState
Definition: screensaver-x11.cpp:208
ScreenSaverX11Private::IsDPMSEnabled
bool IsDPMSEnabled(void) const
Definition: screensaver-x11.cpp:97
ScreenSaverX11Private::m_display
MythXDisplay * m_display
Definition: screensaver-x11.cpp:230
ScreenSaverX11Private::m_timeoutInterval
int m_timeoutInterval
Definition: screensaver-x11.cpp:224
ScreenSaverX11::Disable
void Disable(void) override
Definition: screensaver-x11.cpp:247