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