1 #include <QCoreApplication>
2 #include <QDBusPendingReply>
3 #include <QDBusPendingCall>
4 #include <QDBusPendingCallWatcher>
5 #include <QDBusReply>
6 #include "screensaver_unix.h"
7
ScreenSaverUnix(QObject * parent)8 ScreenSaverUnix::ScreenSaverUnix(QObject *parent)
9 : ScreenSaver(parent),
10 dbusScreensaver("org.freedesktop.ScreenSaver",
11 "/ScreenSaver",
12 "org.freedesktop.ScreenSaver"),
13 dbusLogin("org.freedesktop.login1",
14 "/org/freedesktop/login1",
15 "org.freedesktop.login1.Manager",
16 QDBusConnection::systemBus()),
17 dbusLoginSelf("org.freedesktop.login1",
18 "/org/freedesktop/login1/user/self",
19 "org.freedesktop.login1.User",
20 QDBusConnection::systemBus())
21 {
22 }
23
abilities()24 QSet<ScreenSaverUnix::Ability> ScreenSaverUnix::abilities()
25 {
26 QSet<Ability> abilities;
27
28 if (dbusScreensaver.isValid())
29 abilities << Inhibit << Uninhibit << LaunchSaver << LockScreen;
30
31 if (dbusLogin.isValid()) {
32 auto check = [&](QString method, ScreenSaverUnix::Ability ability) {
33 QDBusReply<QString> reply = dbusLogin.call(method);
34 if (reply.isValid() && reply.value() == "yes")
35 abilities << ability;
36 };
37 check("CanHibernate", Hibernate);
38 check("CanSuspend", Suspend);
39 check("CanPowerOff", Shutdown);
40 }
41 if (dbusLoginSelf.isValid()
42 && dbusLoginSelf.metaObject()->indexOfMethod("Terminate()") != -1) {
43 abilities << LogOff;
44 }
45 return abilities;
46 }
47
inhibitSaver(const QString & reason)48 void ScreenSaverUnix::inhibitSaver(const QString &reason)
49 {
50 if (isInhibiting || inhibitCalled)
51 return;
52
53 inhibitCalled = true;
54
55 QDBusPendingCall async = dbusScreensaver.asyncCall("Inhibit",
56 QCoreApplication::applicationName(), reason);
57 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
58
59 connect(watcher, &QDBusPendingCallWatcher::finished,
60 this, &ScreenSaverUnix::dbusScreensaver_inhibit);
61 }
62
uninhibitSaver()63 void ScreenSaverUnix::uninhibitSaver()
64 {
65 if (!isInhibiting)
66 return;
67
68 QDBusPendingCall async = dbusScreensaver.asyncCall("UnInhibit", inhibitToken);
69 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
70
71 connect(watcher, &QDBusPendingCallWatcher::finished,
72 this, &ScreenSaverUnix::dbusScreensaver_uninhibit);
73
74 }
75
launchSaver()76 void ScreenSaverUnix::launchSaver()
77 {
78 QDBusPendingCall async = dbusScreensaver.asyncCall("SetActive", true);
79 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
80
81 connect(watcher, &QDBusPendingCallWatcher::finished,
82 this, &ScreenSaverUnix::dbusScreensaver_launch);
83
84 }
85
lockScreen()86 void ScreenSaverUnix::lockScreen()
87 {
88 QDBusPendingCall async = dbusScreensaver.asyncCall("Lock");
89 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
90
91 connect(watcher, &QDBusPendingCallWatcher::finished,
92 this, &ScreenSaverUnix::dbusScreensaver_lock);
93
94 }
95
hibernateSystem()96 void ScreenSaverUnix::hibernateSystem()
97 {
98 if (!isInhibiting)
99 return;
100
101 QDBusPendingCall async = dbusLogin.asyncCall("Hibernate");
102 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
103
104 connect(watcher, &QDBusPendingCallWatcher::finished,
105 this, &ScreenSaverUnix::dbusLogin_hibernate);
106 }
107
suspendSystem()108 void ScreenSaverUnix::suspendSystem()
109 {
110 if (!isInhibiting)
111 return;
112
113 QDBusPendingCall async = dbusLogin.asyncCall("Suspend");
114 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
115
116 connect(watcher, &QDBusPendingCallWatcher::finished,
117 this, &ScreenSaverUnix::dbusLogin_suspend);
118 }
119
shutdownSystem()120 void ScreenSaverUnix::shutdownSystem()
121 {
122 if (!isInhibiting)
123 return;
124
125 QDBusPendingCall async = dbusLogin.asyncCall("PowerOff");
126 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
127
128 connect(watcher, &QDBusPendingCallWatcher::finished,
129 this, &ScreenSaverUnix::dbusLogin_shutdown);
130 }
131
132
logOff()133 void ScreenSaverUnix::logOff()
134 {
135 QDBusPendingCall async = dbusLoginSelf.asyncCall("Terminate");
136 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
137
138 connect(watcher, &QDBusPendingCallWatcher::finished,
139 this, &ScreenSaverUnix::dbusLoginSelf_logoff);
140
141 emit failed(LogOff);
142 }
143
dbusScreensaver_inhibit(QDBusPendingCallWatcher * call)144 void ScreenSaverUnix::dbusScreensaver_inhibit(QDBusPendingCallWatcher *call)
145 {
146 QDBusPendingReply<uint32_t> reply = *call;
147 if (reply.isError()) {
148 emit failed(Inhibit);
149 } else {
150 inhibitToken = reply.argumentAt<0>();
151 isInhibiting = true;
152 emit inhibitedSaver();
153 }
154 inhibitCalled = false;
155 call->deleteLater();
156 }
157
dbusScreensaver_uninhibit(QDBusPendingCallWatcher * call)158 void ScreenSaverUnix::dbusScreensaver_uninhibit(QDBusPendingCallWatcher *call)
159 {
160 QDBusPendingReply<> reply = *call;
161 if (reply.isError()) {
162 emit failed(Uninhibit);
163 } else {
164 isInhibiting = false;
165 emit uninhibitedSaver();
166 }
167 call->deleteLater();
168 }
169
dbusScreensaver_launch(QDBusPendingCallWatcher * call)170 void ScreenSaverUnix::dbusScreensaver_launch(QDBusPendingCallWatcher *call)
171 {
172 QDBusPendingReply<> reply = *call;
173 if (reply.isError())
174 emit failed(LaunchSaver);
175 else
176 emit launchedSaver();
177 call->deleteLater();
178 }
179
dbusScreensaver_lock(QDBusPendingCallWatcher * call)180 void ScreenSaverUnix::dbusScreensaver_lock(QDBusPendingCallWatcher *call)
181 {
182 QDBusPendingReply<> reply = *call;
183 if (reply.isError())
184 emit failed(LockScreen);
185 else
186 emit screenLocked();
187 call->deleteLater();
188 }
189
dbusLogin_hibernate(QDBusPendingCallWatcher * call)190 void ScreenSaverUnix::dbusLogin_hibernate(QDBusPendingCallWatcher *call)
191 {
192 QDBusPendingReply<> reply = *call;
193 if (reply.isError())
194 emit failed(Hibernate);
195 else
196 emit systemHibernated();
197 call->deleteLater();
198 }
199
dbusLogin_suspend(QDBusPendingCallWatcher * call)200 void ScreenSaverUnix::dbusLogin_suspend(QDBusPendingCallWatcher *call)
201 {
202 QDBusPendingReply<> reply = *call;
203 if (reply.isError())
204 emit failed(Suspend);
205 else
206 emit systemSuspended();
207 call->deleteLater();
208 }
209
dbusLogin_shutdown(QDBusPendingCallWatcher * call)210 void ScreenSaverUnix::dbusLogin_shutdown(QDBusPendingCallWatcher *call)
211 {
212 QDBusPendingReply<> reply = *call;
213 if (reply.isError())
214 emit failed(Shutdown);
215 else
216 emit systemShutdown();
217 call->deleteLater();
218 }
219
dbusLoginSelf_logoff(QDBusPendingCallWatcher * call)220 void ScreenSaverUnix::dbusLoginSelf_logoff(QDBusPendingCallWatcher *call)
221 {
222 QDBusPendingReply<> reply = *call;
223 if (reply.isError())
224 emit failed(LogOff);
225 else
226 emit loggedOff();
227 call->deleteLater();
228 }
229
230
231