Magellan Linux

Contents of /trunk/kdebase-workspace/patches/kdebase-workspace-4.9.4-systemd-displaymanager.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1994 - (show annotations) (download)
Wed Dec 19 09:48:16 2012 UTC (11 years, 4 months ago) by niro
File size: 20802 byte(s)
-added serveral patches
1 --- libs/kworkspace/kdisplaymanager.cpp.systemd-displaymanager 2012-08-13 10:53:46.000000000 +0200
2 +++ libs/kworkspace/kdisplaymanager.cpp 2012-12-05 12:58:32.193798795 +0100
3 @@ -40,6 +40,166 @@
4 #include <errno.h>
5 #include <stdio.h>
6
7 +#define _DBUS_PROPERTIES_IFACE "org.freedesktop.DBus.Properties"
8 +#define _DBUS_PROPERTIES_GET "Get"
9 +
10 +#define DBUS_PROPERTIES_IFACE QLatin1String(_DBUS_PROPERTIES_IFACE)
11 +#define DBUS_PROPERTIES_GET QLatin1String(_DBUS_PROPERTIES_GET)
12 +
13 +#define _SYSTEMD_SERVICE "org.freedesktop.login1"
14 +#define _SYSTEMD_BASE_PATH "/org/freedesktop/login1"
15 +#define _SYSTEMD_MANAGER_IFACE _SYSTEMD_SERVICE ".Manager"
16 +#define _SYSTEMD_SESSION_BASE_PATH _SYSTEMD_BASE_PATH "/Session"
17 +#define _SYSTEMD_SEAT_IFACE _SYSTEMD_SERVICE ".Seat"
18 +#define _SYSTEMD_SEAT_BASE_PATH _SYSTEMD_BASE_PATH "/Seat"
19 +#define _SYSTEMD_SESSION_IFACE _SYSTEMD_SERVICE ".Session"
20 +#define _SYSTEMD_USER_PROPERTY "User"
21 +#define _SYSTEMD_SEAT_PROPERTY "Seat"
22 +#define _SYSTEMD_SESSIONS_PROPERTY "Sessions"
23 +#define _SYSTEMD_SWITCH_CALL "Activate"
24 +
25 +#define SYSTEMD_SERVICE QLatin1String(_SYSTEMD_SERVICE)
26 +#define SYSTEMD_BASE_PATH QLatin1String(_SYSTEMD_BASE_PATH)
27 +#define SYSTEMD_MANAGER_IFACE QLatin1String(_SYSTEMD_MANAGER_IFACE)
28 +#define SYSTEMD_SESSION_BASE_PATH QLatin1String(_SYSTEMD_SESSION_BASE_PATH)
29 +#define SYSTEMD_SEAT_IFACE QLatin1String(_SYSTEMD_SEAT_IFACE)
30 +#define SYSTEMD_SEAT_BASE_PATH QLatin1String(_SYSTEMD_SEAT_BASE_PATH)
31 +#define SYSTEMD_SESSION_IFACE QLatin1String(_SYSTEMD_SESSION_IFACE)
32 +#define SYSTEMD_USER_PROPERTY QLatin1String(_SYSTEMD_USER_PROPERTY)
33 +#define SYSTEMD_SEAT_PROPERTY QLatin1String(_SYSTEMD_SEAT_PROPERTY)
34 +#define SYSTEMD_SESSIONS_PROPERTY QLatin1String(_SYSTEMD_SESSIONS_PROPERTY)
35 +#define SYSTEMD_SWITCH_CALL QLatin1String(_SYSTEMD_SWITCH_CALL)
36 +
37 +struct NamedDBusObjectPath
38 +{
39 + QString name;
40 + QDBusObjectPath path;
41 +};
42 +Q_DECLARE_METATYPE(NamedDBusObjectPath)
43 +Q_DECLARE_METATYPE(QList<NamedDBusObjectPath>)
44 +
45 +// Marshall the NamedDBusObjectPath data into a D-Bus argument
46 +QDBusArgument &operator<<(QDBusArgument &argument, const NamedDBusObjectPath &namedPath)
47 +{
48 + argument.beginStructure();
49 + argument << namedPath.name << namedPath.path;
50 + argument.endStructure();
51 + return argument;
52 +}
53 +
54 +// Retrieve the NamedDBusObjectPath data from the D-Bus argument
55 +const QDBusArgument &operator>>(const QDBusArgument &argument, NamedDBusObjectPath &namedPath)
56 +{
57 + argument.beginStructure();
58 + argument >> namedPath.name >> namedPath.path;
59 + argument.endStructure();
60 + return argument;
61 +}
62 +
63 +struct NumberedDBusObjectPath
64 +{
65 + uint num;
66 + QDBusObjectPath path;
67 +};
68 +Q_DECLARE_METATYPE(NumberedDBusObjectPath)
69 +
70 +// Marshall the NumberedDBusObjectPath data into a D-Bus argument
71 +QDBusArgument &operator<<(QDBusArgument &argument, const NumberedDBusObjectPath &numberedPath)
72 +{
73 + argument.beginStructure();
74 + argument << numberedPath.num << numberedPath.path;
75 + argument.endStructure();
76 + return argument;
77 +}
78 +
79 +// Retrieve the NumberedDBusObjectPath data from the D-Bus argument
80 +const QDBusArgument &operator>>(const QDBusArgument &argument, NumberedDBusObjectPath &numberedPath)
81 +{
82 + argument.beginStructure();
83 + argument >> numberedPath.num >> numberedPath.path;
84 + argument.endStructure();
85 + return argument;
86 +}
87 +
88 +class SystemdManager : public QDBusInterface
89 +{
90 +public:
91 + SystemdManager() :
92 + QDBusInterface(
93 + SYSTEMD_SERVICE,
94 + SYSTEMD_BASE_PATH,
95 + SYSTEMD_MANAGER_IFACE,
96 + QDBusConnection::systemBus()) {}
97 +};
98 +
99 +class SystemdSeat : public QDBusInterface
100 +{
101 +public:
102 + SystemdSeat(const QDBusObjectPath &path) :
103 + QDBusInterface(
104 + SYSTEMD_SERVICE,
105 + path.path(),
106 + SYSTEMD_SEAT_IFACE,
107 + QDBusConnection::systemBus()) {}
108 + /* HACK to be able to extract a(so) type from QDBus, property doesn't do the trick */
109 + QList<NamedDBusObjectPath> getSessions() {
110 + QDBusMessage message = QDBusMessage::createMethodCall(service(), path(), DBUS_PROPERTIES_IFACE, DBUS_PROPERTIES_GET);
111 + message << interface() << SYSTEMD_SESSIONS_PROPERTY;
112 + QDBusMessage reply = QDBusConnection::systemBus().call(message);
113 +
114 + QVariantList args = reply.arguments();
115 + if (!args.isEmpty()) {
116 + QList<NamedDBusObjectPath> namedPathList = qdbus_cast< QList<NamedDBusObjectPath> >(args.at(0).value<QDBusVariant>().variant().value<QDBusArgument>());
117 + return namedPathList;
118 + }
119 + return QList<NamedDBusObjectPath>();
120 + }
121 +};
122 +
123 +class SystemdSession : public QDBusInterface
124 +{
125 +public:
126 + SystemdSession(const QDBusObjectPath &path) :
127 + QDBusInterface(
128 + SYSTEMD_SERVICE,
129 + path.path(),
130 + SYSTEMD_SESSION_IFACE,
131 + QDBusConnection::systemBus()) {}
132 + /* HACK to be able to extract (so) type from QDBus, property doesn't do the trick */
133 + NamedDBusObjectPath getSeat() {
134 + QDBusMessage message = QDBusMessage::createMethodCall(service(), path(), DBUS_PROPERTIES_IFACE, DBUS_PROPERTIES_GET);
135 + message << interface() << SYSTEMD_SEAT_PROPERTY;
136 + QDBusMessage reply = QDBusConnection::systemBus().call(message);
137 +
138 + QVariantList args = reply.arguments();
139 + if (!args.isEmpty()) {
140 + NamedDBusObjectPath namedPath;
141 + args.at(0).value<QDBusVariant>().variant().value<QDBusArgument>() >> namedPath;
142 + return namedPath;
143 + }
144 + return NamedDBusObjectPath();
145 + }
146 + NumberedDBusObjectPath getUser() {
147 + QDBusMessage message = QDBusMessage::createMethodCall(service(), path(), DBUS_PROPERTIES_IFACE, DBUS_PROPERTIES_GET);
148 + message << interface() << SYSTEMD_USER_PROPERTY;
149 + QDBusMessage reply = QDBusConnection::systemBus().call(message);
150 +
151 + QVariantList args = reply.arguments();
152 + if (!args.isEmpty()) {
153 + NumberedDBusObjectPath numberedPath;
154 + args.at(0).value<QDBusVariant>().variant().value<QDBusArgument>() >> numberedPath;
155 + return numberedPath;
156 + }
157 + return NumberedDBusObjectPath();
158 + }
159 + void getSessionLocation(SessEnt &se)
160 + {
161 + se.tty = (property("Type").toString() != QLatin1String("x11"));
162 + se.display = property(se.tty ? "TTY" : "Display").toString();
163 + se.vt = property("VTNr").toInt();
164 + }
165 +};
166 +
167 class CKManager : public QDBusInterface
168 {
169 public:
170 @@ -68,9 +228,26 @@
171 CKSession(const QDBusObjectPath &path) :
172 QDBusInterface(
173 QLatin1String("org.freedesktop.ConsoleKit"),
174 - path.path(),
175 + path.path(),
176 QLatin1String("org.freedesktop.ConsoleKit.Session"),
177 QDBusConnection::systemBus()) {}
178 + void getSessionLocation(SessEnt &se)
179 + {
180 + QString tty;
181 + QDBusReply<QString> r = call(QLatin1String("GetX11Display"));
182 + if (r.isValid() && !r.value().isEmpty()) {
183 + QDBusReply<QString> r2 = call(QLatin1String("GetX11DisplayDevice"));
184 + tty = r2.value();
185 + se.display = r.value();
186 + se.tty = false;
187 + } else {
188 + QDBusReply<QString> r2 = call(QLatin1String("GetDisplayDevice"));
189 + tty = r2.value();
190 + se.display = tty;
191 + se.tty = true;
192 + }
193 + se.vt = tty.mid(strlen("/dev/tty")).toInt();
194 + }
195 };
196
197 class GDMFactory : public QDBusInterface
198 @@ -131,6 +308,9 @@
199 }
200 switch (DMType) {
201 default:
202 + qDBusRegisterMetaType<NamedDBusObjectPath>();
203 + qDBusRegisterMetaType<QList<NamedDBusObjectPath> >();
204 + qDBusRegisterMetaType<NumberedDBusObjectPath>();
205 return;
206 case NewKDM:
207 case OldGDM:
208 @@ -242,17 +422,31 @@
209
210 static bool getCurrentSeat(QDBusObjectPath *currentSession, QDBusObjectPath *currentSeat)
211 {
212 - CKManager man;
213 - QDBusReply<QDBusObjectPath> r = man.call(QLatin1String("GetCurrentSession"));
214 + SystemdManager man;
215 + QDBusReply<QDBusObjectPath> r = man.call(QLatin1String("GetSessionByPID"), (uint) QCoreApplication::applicationPid());
216 if (r.isValid()) {
217 - CKSession sess(r.value());
218 + SystemdSession sess(r.value());
219 if (sess.isValid()) {
220 - QDBusReply<QDBusObjectPath> r2 = sess.call(QLatin1String("GetSeatId"));
221 - if (r2.isValid()) {
222 - if (currentSession)
223 - *currentSession = r.value();
224 - *currentSeat = r2.value();
225 - return true;
226 + NamedDBusObjectPath namedPath = sess.getSeat();
227 + if (currentSession)
228 + *currentSession = r.value();
229 + *currentSeat = namedPath.path;
230 + return true;
231 + }
232 + }
233 + else {
234 + CKManager man;
235 + QDBusReply<QDBusObjectPath> r = man.call(QLatin1String("GetCurrentSession"));
236 + if (r.isValid()) {
237 + CKSession sess(r.value());
238 + if (sess.isValid()) {
239 + QDBusReply<QDBusObjectPath> r2 = sess.call(QLatin1String("GetSeatId"));
240 + if (r2.isValid()) {
241 + if (currentSession)
242 + *currentSession = r.value();
243 + *currentSeat = r2.value();
244 + return true;
245 + }
246 }
247 }
248 }
249 @@ -261,44 +455,44 @@
250
251 static QList<QDBusObjectPath> getSessionsForSeat(const QDBusObjectPath &path)
252 {
253 - CKSeat seat(path);
254 - if (seat.isValid()) {
255 - QDBusReply<QList<QDBusObjectPath> > r = seat.call(QLatin1String("GetSessions"));
256 - if (r.isValid()) {
257 - // This will contain only local sessions:
258 - // - this is only ever called when isSwitchable() is true => local seat
259 - // - remote logins into the machine are assigned to other seats
260 - return r.value();
261 + if (path.path().startsWith(SYSTEMD_BASE_PATH)) { // systemd path incoming
262 + SystemdSeat seat(path);
263 + if (seat.isValid()) {
264 + QList<NamedDBusObjectPath> r = seat.getSessions();
265 + QList<QDBusObjectPath> result;
266 + foreach (const NamedDBusObjectPath &namedPath, r)
267 + result.append(namedPath.path);
268 + // This pretty much can't contain any other than local sessions as seats are assigned only locally in systemd
269 + return result;
270 + }
271 + }
272 + else if (path.path().startsWith("/org/freedesktop/ConsoleKit")) {
273 + CKSeat seat(path);
274 + if (seat.isValid()) {
275 + QDBusReply<QList<QDBusObjectPath> > r = seat.call(QLatin1String("GetSessions"));
276 + if (r.isValid()) {
277 + // This will contain only local sessions:
278 + // - this is only ever called when isSwitchable() is true => local seat
279 + // - remote logins into the machine are assigned to other seats
280 + return r.value();
281 + }
282 }
283 }
284 return QList<QDBusObjectPath>();
285 }
286
287 -static void getSessionLocation(CKSession &lsess, SessEnt &se)
288 -{
289 - QString tty;
290 - QDBusReply<QString> r = lsess.call(QLatin1String("GetX11Display"));
291 - if (r.isValid() && !r.value().isEmpty()) {
292 - QDBusReply<QString> r2 = lsess.call(QLatin1String("GetX11DisplayDevice"));
293 - tty = r2.value();
294 - se.display = r.value();
295 - se.tty = false;
296 - } else {
297 - QDBusReply<QString> r2 = lsess.call(QLatin1String("GetDisplayDevice"));
298 - tty = r2.value();
299 - se.display = tty;
300 - se.tty = true;
301 - }
302 - se.vt = tty.mid(strlen("/dev/tty")).toInt();
303 -}
304 -
305 #ifndef KDM_NO_SHUTDOWN
306 bool
307 KDisplayManager::canShutdown()
308 {
309 if (DMType == NewGDM || DMType == NoDM || DMType == LightDM) {
310 + QDBusReply<QString> canPowerOff = SystemdManager().call(QLatin1String("CanPowerOff"));
311 + if (canPowerOff.isValid())
312 + return canPowerOff.value() != QLatin1String("no");
313 QDBusReply<bool> canStop = CKManager().call(QLatin1String("CanStop"));
314 - return (canStop.isValid() && canStop.value());
315 + if (canStop.isValid())
316 + return canStop.value();
317 + return false;
318 }
319
320 if (DMType == OldKDM)
321 @@ -329,9 +523,21 @@
322 return;
323
324 if (DMType == NewGDM || DMType == NoDM || DMType == LightDM) {
325 - // FIXME: entirely ignoring shutdownMode
326 - CKManager().call(QLatin1String(
327 - shutdownType == KWorkSpace::ShutdownTypeReboot ? "Restart" : "Stop"));
328 + // systemd supports only 2 modes:
329 + // * interactive = true: brings up a PolicyKit prompt if other sessions are active
330 + // * interactive = false: rejects the shutdown if other sessions are active
331 + // There are no schedule or force modes.
332 + // We try to map our 4 shutdown modes in the sanest way.
333 + bool interactive = (shutdownMode == KWorkSpace::ShutdownModeInteractive
334 + || shutdownMode == KWorkSpace::ShutdownModeForceNow);
335 + QDBusReply<QString> check = SystemdManager().call(QLatin1String(
336 + shutdownType == KWorkSpace::ShutdownTypeReboot ? "Reboot" : "PowerOff"), interactive);
337 + if (!check.isValid()) {
338 + // FIXME: entirely ignoring shutdownMode
339 + CKManager().call(QLatin1String(
340 + shutdownType == KWorkSpace::ShutdownTypeReboot ? "Restart" : "Stop"));
341 + // if even CKManager call fails, there is nothing more to be done
342 + }
343 return;
344 }
345
346 @@ -406,9 +612,15 @@
347 if (DMType == NewGDM || DMType == LightDM) {
348 QDBusObjectPath currentSeat;
349 if (getCurrentSeat(0, &currentSeat)) {
350 - CKSeat seat(currentSeat);
351 - if (seat.isValid()) {
352 - QDBusReply<bool> r = seat.call(QLatin1String("CanActivateSessions"));
353 + SystemdSeat SDseat(currentSeat);
354 + if (SDseat.isValid()) {
355 + QVariant prop = SDseat.property("CanMultiSession");
356 + if (prop.isValid())
357 + return prop.toBool();
358 + }
359 + CKSeat CKseat(currentSeat);
360 + if (CKseat.isValid()) {
361 + QDBusReply<bool> r = CKseat.call(QLatin1String("CanActivateSessions"));
362 if (r.isValid())
363 return r.value();
364 }
365 @@ -468,23 +680,56 @@
366 if (DMType == NewGDM || DMType == LightDM) {
367 QDBusObjectPath currentSession, currentSeat;
368 if (getCurrentSeat(&currentSession, &currentSeat)) {
369 - foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) {
370 - CKSession lsess(sp);
371 - if (lsess.isValid()) {
372 - SessEnt se;
373 - getSessionLocation(lsess, se);
374 - // "Warning: we haven't yet defined the allowed values for this property.
375 - // It is probably best to avoid this until we do."
376 - QDBusReply<QString> r = lsess.call(QLatin1String("GetSessionType"));
377 - if (r.value() != QLatin1String("LoginWindow")) {
378 - QDBusReply<unsigned> r2 = lsess.call(QLatin1String("GetUnixUser"));
379 - se.user = KUser(K_UID(r2.value())).loginName();
380 - se.session = "<unknown>";
381 + // we'll divide the code in two branches to reduce the overhead of calls to non-existent services
382 + // systemd part // preferred
383 + if (QDBusConnection::systemBus().interface()->isServiceRegistered(SYSTEMD_SERVICE)) {
384 + foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) {
385 + SystemdSession lsess(sp);
386 + if (lsess.isValid()) {
387 + SessEnt se;
388 + lsess.getSessionLocation(se);
389 + if ((lsess.property("Class").toString() != QLatin1String("greeter")) &&
390 + (lsess.property("State").toString() != QLatin1String("closing"))) {
391 + NumberedDBusObjectPath numberedPath = lsess.getUser();
392 + se.display = lsess.property("Display").toString();
393 + se.vt = lsess.property("VTNr").toInt();
394 + se.user = KUser(K_UID(numberedPath.num)).loginName();
395 + /* TODO:
396 + * regarding the session name in this, it IS possible to find it out - logind tracks the session leader PID
397 + * the problem is finding out the name of the process, I could come only with reading /proc/PID/comm which
398 + * doesn't seem exactly... right to me --mbriza
399 + */
400 + se.session = "<unknown>";
401 + se.self = lsess.property("Display").toString() == ::getenv("DISPLAY"); /* Bleh once again */
402 + se.tty = !lsess.property("TTY").toString().isEmpty();
403 + }
404 + list.append(se);
405 + }
406 + }
407 + }
408 + // ConsoleKit part
409 + else if (QDBusConnection::systemBus().interface()->isServiceRegistered("org.freedesktop.ConsoleKit")) {
410 + foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) {
411 + CKSession lsess(sp);
412 + if (lsess.isValid()) {
413 + SessEnt se;
414 + lsess.getSessionLocation(se);
415 + // "Warning: we haven't yet defined the allowed values for this property.
416 + // It is probably best to avoid this until we do."
417 + QDBusReply<QString> r = lsess.call(QLatin1String("GetSessionType"));
418 + if (r.value() != QLatin1String("LoginWindow")) {
419 + QDBusReply<unsigned> r2 = lsess.call(QLatin1String("GetUnixUser"));
420 + se.user = KUser(K_UID(r2.value())).loginName();
421 + se.session = "<unknown>";
422 + }
423 + se.self = (sp == currentSession);
424 + list.append(se);
425 }
426 - se.self = (sp == currentSession);
427 - list.append(se);
428 }
429 }
430 + else {
431 + return false;
432 + }
433 return true;
434 }
435 return false;
436 @@ -566,16 +811,33 @@
437 if (DMType == NewGDM || DMType == LightDM) {
438 QDBusObjectPath currentSeat;
439 if (getCurrentSeat(0, &currentSeat)) {
440 - foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) {
441 - CKSession lsess(sp);
442 - if (lsess.isValid()) {
443 - SessEnt se;
444 - getSessionLocation(lsess, se);
445 - if (se.vt == vt) {
446 - if (se.tty) // ConsoleKit simply ignores these
447 - return false;
448 - lsess.call(QLatin1String("Activate"));
449 - return true;
450 + // systemd part // preferred
451 + if (QDBusConnection::systemBus().interface()->isServiceRegistered(SYSTEMD_SERVICE)) {
452 + foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) {
453 + SystemdSession lsess(sp);
454 + if (lsess.isValid()) {
455 + SessEnt se;
456 + lsess.getSessionLocation(se);
457 + if (se.vt == vt) {
458 + lsess.call(SYSTEMD_SWITCH_CALL);
459 + return true;
460 + }
461 + }
462 + }
463 + }
464 + // ConsoleKit part
465 + else if (QDBusConnection::systemBus().interface()->isServiceRegistered("org.freedesktop.ConsoleKit")) {
466 + foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) {
467 + CKSession lsess(sp);
468 + if (lsess.isValid()) {
469 + SessEnt se;
470 + lsess.getSessionLocation(se);
471 + if (se.vt == vt) {
472 + if (se.tty) // ConsoleKit simply ignores these
473 + return false;
474 + lsess.call(QLatin1String("Activate"));
475 + return true;
476 + }
477 }
478 }
479 }