Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1994 - (hide annotations) (download)
Wed Dec 19 09:48:16 2012 UTC (11 years, 6 months ago) by niro
File size: 20802 byte(s)
-added serveral patches
1 niro 1994 --- 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     }