~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to libs/kworkspace/kdisplaymanager.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (C) 2004 Oswald Buddenhagen <ossi@kde.org>
 
3
 
 
4
   This program is free software; you can redistribute it and/or
 
5
   modify it under the terms of the Lesser GNU General Public
 
6
   License as published by the Free Software Foundation; either
 
7
   version 2 of the License, or (at your option) any later version.
 
8
 
 
9
   This program is distributed in the hope that it will be useful,
 
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
    General Public License for more details.
 
13
 
 
14
   You should have received a copy of the Lesser GNU General Public License
 
15
   along with this program; see the file COPYING.  If not, write to
 
16
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
17
   Boston, MA 02110-1301, USA.
 
18
*/
 
19
 
 
20
#include "kdisplaymanager.h"
 
21
 
 
22
#ifdef Q_WS_X11
 
23
 
 
24
#include <kapplication.h>
 
25
#include <klocale.h>
 
26
#include <kuser.h>
 
27
 
 
28
#include <QtDBus/QtDBus>
 
29
#include <QRegExp>
 
30
 
 
31
#include <X11/Xauth.h>
 
32
#include <X11/Xlib.h>
 
33
 
 
34
#include <sys/types.h>
 
35
#include <sys/socket.h>
 
36
#include <sys/un.h>
 
37
#include <unistd.h>
 
38
#include <stdlib.h>
 
39
#include <fcntl.h>
 
40
#include <errno.h>
 
41
#include <stdio.h>
 
42
 
 
43
class CKManager : public QDBusInterface
 
44
{
 
45
public:
 
46
    CKManager() :
 
47
        QDBusInterface(
 
48
                QLatin1String("org.freedesktop.ConsoleKit"),
 
49
                QLatin1String("/org/freedesktop/ConsoleKit/Manager"),
 
50
                QLatin1String("org.freedesktop.ConsoleKit.Manager"),
 
51
                QDBusConnection::systemBus()) {}
 
52
};
 
53
 
 
54
class CKSeat : public QDBusInterface
 
55
{
 
56
public:
 
57
    CKSeat(const QDBusObjectPath &path) :
 
58
        QDBusInterface(
 
59
                QLatin1String("org.freedesktop.ConsoleKit"),
 
60
                path.path(),
 
61
                QLatin1String("org.freedesktop.ConsoleKit.Seat"),
 
62
                QDBusConnection::systemBus()) {}
 
63
};
 
64
 
 
65
class CKSession : public QDBusInterface
 
66
{
 
67
public:
 
68
    CKSession(const QDBusObjectPath &path) :
 
69
        QDBusInterface(
 
70
                QLatin1String("org.freedesktop.ConsoleKit"),
 
71
            path.path(),
 
72
                QLatin1String("org.freedesktop.ConsoleKit.Session"),
 
73
                QDBusConnection::systemBus()) {}
 
74
};
 
75
 
 
76
class GDMFactory : public QDBusInterface
 
77
{
 
78
public:
 
79
    GDMFactory() :
 
80
        QDBusInterface(
 
81
                QLatin1String("org.gnome.DisplayManager"),
 
82
                QLatin1String("/org/gnome/DisplayManager/LocalDisplayFactory"),
 
83
                QLatin1String("org.gnome.DisplayManager.LocalDisplayFactory"),
 
84
                QDBusConnection::systemBus()) {}
 
85
};
 
86
 
 
87
class LightDMDBus : public QDBusInterface
 
88
{
 
89
public:
 
90
    LightDMDBus() :
 
91
        QDBusInterface(
 
92
                QLatin1String("org.lightdm.LightDisplayManager"),
 
93
                "/org/lightdm/LightDisplayManager",
 
94
                QLatin1String("org.lightdm.LightDisplayManager"),
 
95
                QDBusConnection::systemBus()) {}
 
96
};
 
97
 
 
98
static enum { Dunno, NoDM, NewKDM, OldKDM, NewGDM, OldGDM, LightDM } DMType = Dunno;
 
99
static const char *ctl, *dpy;
 
100
 
 
101
class KDisplayManager::Private
 
102
{
 
103
public:
 
104
    Private() : fd(-1) {}
 
105
    ~Private() {
 
106
        if (fd >= 0)
 
107
            close(fd);
 
108
    }
 
109
 
 
110
    int fd;
 
111
};
 
112
 
 
113
KDisplayManager::KDisplayManager() : d(new Private)
 
114
{
 
115
    const char *ptr;
 
116
    struct sockaddr_un sa;
 
117
 
 
118
    if (DMType == Dunno) {
 
119
        if (!(dpy = ::getenv("DISPLAY")))
 
120
            DMType = NoDM;
 
121
        else if ((ctl = ::getenv("DM_CONTROL")))
 
122
            DMType = NewKDM;
 
123
        else if ((ctl = ::getenv("XDM_MANAGED")) && ctl[0] == '/')
 
124
            DMType = OldKDM;
 
125
        else if (::getenv("GDMSESSION")) {
 
126
            //lightDM identifies itself as GDM at the moment.
 
127
            QDBusReply<bool> reply = QDBusConnection::systemBus().interface()->isServiceRegistered("org.lightdm.LightDisplayManager");
 
128
            if (reply.isValid()) {
 
129
                DMType = LightDM;
 
130
            } else {
 
131
                DMType = GDMFactory().isValid() ? NewGDM : OldGDM;
 
132
            }
 
133
        }
 
134
        else
 
135
            DMType = NoDM;
 
136
    }
 
137
    switch (DMType) {
 
138
    default:
 
139
        return;
 
140
    case NewKDM:
 
141
    case OldGDM:
 
142
        if ((d->fd = ::socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
 
143
            return;
 
144
        sa.sun_family = AF_UNIX;
 
145
        if (DMType == OldGDM) {
 
146
            strcpy(sa.sun_path, "/var/run/gdm_socket");
 
147
            if (::connect(d->fd, (struct sockaddr *)&sa, sizeof(sa))) {
 
148
                strcpy(sa.sun_path, "/tmp/.gdm_socket");
 
149
                if (::connect(d->fd, (struct sockaddr *)&sa, sizeof(sa))) {
 
150
                    ::close(d->fd);
 
151
                    d->fd = -1;
 
152
                    break;
 
153
                }
 
154
            }
 
155
            GDMAuthenticate();
 
156
        } else {
 
157
            if ((ptr = strchr(dpy, ':')))
 
158
                ptr = strchr(ptr, '.');
 
159
            snprintf(sa.sun_path, sizeof(sa.sun_path),
 
160
                     "%s/dmctl-%.*s/socket",
 
161
                     ctl, ptr ? int(ptr - dpy) : 512, dpy);
 
162
            if (::connect(d->fd, (struct sockaddr *)&sa, sizeof(sa))) {
 
163
                ::close(d->fd);
 
164
                d->fd = -1;
 
165
            }
 
166
        }
 
167
        break;
 
168
    case OldKDM:
 
169
        {
 
170
            QString tf(ctl);
 
171
            tf.truncate(tf.indexOf(','));
 
172
            d->fd = ::open(tf.toLatin1(), O_WRONLY);
 
173
        }
 
174
        break;
 
175
    }
 
176
}
 
177
 
 
178
KDisplayManager::~KDisplayManager()
 
179
{
 
180
    delete d;
 
181
}
 
182
 
 
183
bool
 
184
KDisplayManager::exec(const char *cmd)
 
185
{
 
186
    QByteArray buf;
 
187
 
 
188
    return exec(cmd, buf);
 
189
}
 
190
 
 
191
/**
 
192
 * Execute a KDM/GDM remote control command.
 
193
 * @param cmd the command to execute. FIXME: undocumented yet.
 
194
 * @param buf the result buffer.
 
195
 * @return result:
 
196
 *  @li If true, the command was successfully executed.
 
197
 *   @p ret might contain addional results.
 
198
 *  @li If false and @p ret is empty, a communication error occurred
 
199
 *   (most probably KDM is not running).
 
200
 *  @li If false and @p ret is non-empty, it contains the error message
 
201
 *   from KDM.
 
202
 */
 
203
bool
 
204
KDisplayManager::exec(const char *cmd, QByteArray &buf)
 
205
{
 
206
    bool ret = false;
 
207
    int tl;
 
208
    int len = 0;
 
209
 
 
210
    if (d->fd < 0)
 
211
        goto busted;
 
212
 
 
213
    tl = strlen(cmd);
 
214
    if (::write(d->fd, cmd, tl) != tl) {
 
215
      bust:
 
216
        ::close(d->fd);
 
217
        d->fd = -1;
 
218
      busted:
 
219
        buf.resize(0);
 
220
        return false;
 
221
    }
 
222
    if (DMType == OldKDM) {
 
223
        buf.resize(0);
 
224
        return true;
 
225
    }
 
226
    for (;;) {
 
227
        if (buf.size() < 128)
 
228
            buf.resize(128);
 
229
        else if (buf.size() < len * 2)
 
230
            buf.resize(len * 2);
 
231
        if ((tl = ::read(d->fd, buf.data() + len, buf.size() - len)) <= 0) {
 
232
            if (tl < 0 && errno == EINTR)
 
233
                continue;
 
234
            goto bust;
 
235
        }
 
236
        len += tl;
 
237
        if (buf[len - 1] == '\n') {
 
238
            buf[len - 1] = 0;
 
239
            if (len > 2 && (buf[0] == 'o' || buf[0] == 'O') &&
 
240
                (buf[1] == 'k' || buf[1] == 'K') && buf[2] <= ' ')
 
241
                ret = true;
 
242
            break;
 
243
        }
 
244
    }
 
245
    return ret;
 
246
}
 
247
 
 
248
static bool getCurrentSeat(QDBusObjectPath *currentSession, QDBusObjectPath *currentSeat)
 
249
{
 
250
    CKManager man;
 
251
    QDBusReply<QDBusObjectPath> r = man.call(QLatin1String("GetCurrentSession"));
 
252
    if (r.isValid()) {
 
253
        CKSession sess(r.value());
 
254
        if (sess.isValid()) {
 
255
            QDBusReply<QDBusObjectPath> r2 = sess.call(QLatin1String("GetSeatId"));
 
256
            if (r2.isValid()) {
 
257
                if (currentSession)
 
258
                    *currentSession = r.value();
 
259
                *currentSeat = r2.value();
 
260
                return true;
 
261
            }
 
262
        }
 
263
    }
 
264
    return false;
 
265
}
 
266
 
 
267
static QList<QDBusObjectPath> getSessionsForSeat(const QDBusObjectPath &path)
 
268
{
 
269
    CKSeat seat(path);
 
270
    if (seat.isValid()) {
 
271
        QDBusReply<QList<QDBusObjectPath> > r = seat.call(QLatin1String("GetSessions"));
 
272
        if (r.isValid()) {
 
273
            // This will contain only local sessions:
 
274
            // - this is only ever called when isSwitchable() is true => local seat
 
275
            // - remote logins into the machine are assigned to other seats
 
276
            return r.value();
 
277
        }
 
278
    }
 
279
    return QList<QDBusObjectPath>();
 
280
}
 
281
 
 
282
static void getSessionLocation(CKSession &lsess, SessEnt &se)
 
283
{
 
284
    QString tty;
 
285
    QDBusReply<QString> r = lsess.call(QLatin1String("GetX11Display"));
 
286
    if (r.isValid() && !r.value().isEmpty()) {
 
287
        QDBusReply<QString> r2 = lsess.call(QLatin1String("GetX11DisplayDevice"));
 
288
        tty = r2.value();
 
289
        se.display = r.value();
 
290
        se.tty = false;
 
291
    } else {
 
292
        QDBusReply<QString> r2 = lsess.call(QLatin1String("GetDisplayDevice"));
 
293
        tty = r2.value();
 
294
        se.display = tty;
 
295
        se.tty = true;
 
296
    }
 
297
    se.vt = tty.mid(strlen("/dev/tty")).toInt();
 
298
}
 
299
 
 
300
#ifndef KDM_NO_SHUTDOWN
 
301
bool
 
302
KDisplayManager::canShutdown()
 
303
{
 
304
    if (DMType == NewGDM || DMType == NoDM || DMType == LightDM) {
 
305
        QDBusReply<bool> canStop = CKManager().call(QLatin1String("CanStop"));
 
306
        return (canStop.isValid() && canStop.value());
 
307
    }
 
308
 
 
309
    if (DMType == OldKDM)
 
310
        return strstr(ctl, ",maysd") != 0;
 
311
 
 
312
    QByteArray re;
 
313
 
 
314
    if (DMType == OldGDM)
 
315
        return exec("QUERY_LOGOUT_ACTION\n", re) && re.indexOf("HALT") >= 0;
 
316
 
 
317
    return exec("caps\n", re) && re.indexOf("\tshutdown") >= 0;
 
318
}
 
319
 
 
320
void
 
321
KDisplayManager::shutdown(KWorkSpace::ShutdownType shutdownType,
 
322
                          KWorkSpace::ShutdownMode shutdownMode, /* NOT Default */
 
323
                          const QString &bootOption)
 
324
{
 
325
    if (shutdownType == KWorkSpace::ShutdownTypeNone || shutdownType == KWorkSpace::ShutdownTypeLogout)
 
326
        return;
 
327
 
 
328
    bool cap_ask;
 
329
    if (DMType == NewKDM) {
 
330
        QByteArray re;
 
331
        cap_ask = exec("caps\n", re) && re.indexOf("\tshutdown ask") >= 0;
 
332
    } else {
 
333
        if (!bootOption.isEmpty())
 
334
            return;
 
335
 
 
336
        if (DMType == NewGDM || DMType == NoDM || DMType == LightDM) {
 
337
            // FIXME: entirely ignoring shutdownMode
 
338
            CKManager().call(QLatin1String(
 
339
                    shutdownType == KWorkSpace::ShutdownTypeReboot ? "Restart" : "Stop"));
 
340
            return;
 
341
        }
 
342
 
 
343
        cap_ask = false;
 
344
    }
 
345
    if (!cap_ask && shutdownMode == KWorkSpace::ShutdownModeInteractive)
 
346
        shutdownMode = KWorkSpace::ShutdownModeForceNow;
 
347
 
 
348
    QByteArray cmd;
 
349
    if (DMType == OldGDM) {
 
350
        cmd.append(shutdownMode == KWorkSpace::ShutdownModeForceNow ?
 
351
                   "SET_LOGOUT_ACTION " : "SET_SAFE_LOGOUT_ACTION ");
 
352
        cmd.append(shutdownType == KWorkSpace::ShutdownTypeReboot ?
 
353
                   "REBOOT\n" : "HALT\n");
 
354
    } else {
 
355
        cmd.append("shutdown\t");
 
356
        cmd.append(shutdownType == KWorkSpace::ShutdownTypeReboot ?
 
357
                   "reboot\t" : "halt\t");
 
358
        if (!bootOption.isEmpty())
 
359
            cmd.append("=").append(bootOption.toLocal8Bit()).append("\t");
 
360
        cmd.append(shutdownMode == KWorkSpace::ShutdownModeInteractive ?
 
361
                   "ask\n" :
 
362
                   shutdownMode == KWorkSpace::ShutdownModeForceNow ?
 
363
                   "forcenow\n" :
 
364
                   shutdownMode == KWorkSpace::ShutdownModeTryNow ?
 
365
                   "trynow\n" : "schedule\n");
 
366
    }
 
367
    exec(cmd.data());
 
368
}
 
369
 
 
370
bool
 
371
KDisplayManager::bootOptions(QStringList &opts, int &defopt, int &current)
 
372
{
 
373
    if (DMType != NewKDM)
 
374
        return false;
 
375
 
 
376
    QByteArray re;
 
377
    if (!exec("listbootoptions\n", re))
 
378
        return false;
 
379
 
 
380
    opts = QString::fromLocal8Bit(re.data()).split('\t', QString::SkipEmptyParts);
 
381
    if (opts.size() < 4)
 
382
        return false;
 
383
 
 
384
    bool ok;
 
385
    defopt = opts[2].toInt(&ok);
 
386
    if (!ok)
 
387
        return false;
 
388
    current = opts[3].toInt(&ok);
 
389
    if (!ok)
 
390
        return false;
 
391
 
 
392
    opts = opts[1].split(' ', QString::SkipEmptyParts);
 
393
    for (QStringList::Iterator it = opts.begin(); it != opts.end(); ++it)
 
394
        (*it).replace("\\s", " ");
 
395
 
 
396
    return true;
 
397
}
 
398
#endif // KDM_NO_SHUTDOWN
 
399
 
 
400
// This only tells KDM to not auto-re-login upon session crash
 
401
void
 
402
KDisplayManager::setLock(bool on)
 
403
{
 
404
    if (DMType == NewKDM || DMType == OldKDM)
 
405
        exec(on ? "lock\n" : "unlock\n");
 
406
}
 
407
 
 
408
bool
 
409
KDisplayManager::isSwitchable()
 
410
{
 
411
    if (DMType == NewGDM || DMType == LightDM) {
 
412
        QDBusObjectPath currentSeat;
 
413
        if (getCurrentSeat(0, &currentSeat)) {
 
414
            CKSeat seat(currentSeat);
 
415
            if (seat.isValid()) {
 
416
                QDBusReply<bool> r = seat.call(QLatin1String("CanActivateSessions"));
 
417
                if (r.isValid())
 
418
                    return r.value();
 
419
            }
 
420
        }
 
421
        return false;
 
422
    }
 
423
 
 
424
    if (DMType == OldKDM)
 
425
        return dpy[0] == ':';
 
426
 
 
427
    if (DMType == OldGDM)
 
428
        return exec("QUERY_VT\n");
 
429
 
 
430
    QByteArray re;
 
431
 
 
432
    return exec("caps\n", re) && re.indexOf("\tlocal") >= 0;
 
433
}
 
434
 
 
435
int
 
436
KDisplayManager::numReserve()
 
437
{
 
438
    if (DMType == NewGDM || DMType == OldGDM || DMType == LightDM)
 
439
        return 1; /* Bleh */
 
440
 
 
441
    if (DMType == OldKDM)
 
442
        return strstr(ctl, ",rsvd") ? 1 : -1;
 
443
 
 
444
    QByteArray re;
 
445
    int p;
 
446
 
 
447
    if (!(exec("caps\n", re) && (p = re.indexOf("\treserve ")) >= 0))
 
448
        return -1;
 
449
    return atoi(re.data() + p + 9);
 
450
}
 
451
 
 
452
void
 
453
KDisplayManager::startReserve()
 
454
{
 
455
    if (DMType == NewGDM)
 
456
        GDMFactory().call(QLatin1String("CreateTransientDisplay"));
 
457
    else if (DMType == OldGDM)
 
458
        exec("FLEXI_XSERVER\n");
 
459
    else if (DMType == LightDM) {
 
460
        LightDMDBus lightDM;
 
461
        lightDM.call("SwitchToUser", QVariant::fromValue<QString>(""));
 
462
    }
 
463
    else
 
464
        exec("reserve\n");
 
465
}
 
466
 
 
467
bool
 
468
KDisplayManager::localSessions(SessList &list)
 
469
{
 
470
    if (DMType == OldKDM)
 
471
        return false;
 
472
 
 
473
    if (DMType == NewGDM || DMType == LightDM) {
 
474
        QDBusObjectPath currentSession, currentSeat;
 
475
        if (getCurrentSeat(&currentSession, &currentSeat)) {
 
476
            foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) {
 
477
                CKSession lsess(sp);
 
478
                if (lsess.isValid()) {
 
479
                    SessEnt se;
 
480
                    getSessionLocation(lsess, se);
 
481
                    // "Warning: we haven't yet defined the allowed values for this property.
 
482
                    // It is probably best to avoid this until we do."
 
483
                    QDBusReply<QString> r = lsess.call(QLatin1String("GetSessionType"));
 
484
                    if (r.value() != QLatin1String("LoginWindow")) {
 
485
                        QDBusReply<unsigned> r2 = lsess.call(QLatin1String("GetUnixUser"));
 
486
                        se.user = KUser(K_UID(r2.value())).loginName();
 
487
                        se.session = "<unknown>";
 
488
                    }
 
489
                    se.self = (sp == currentSession);
 
490
                    list.append(se);
 
491
                }
 
492
            }
 
493
            return true;
 
494
        }
 
495
        return false;
 
496
    }
 
497
 
 
498
    QByteArray re;
 
499
 
 
500
    if (DMType == OldGDM) {
 
501
        if (!exec("CONSOLE_SERVERS\n", re))
 
502
            return false;
 
503
        const QStringList sess = QString(re.data() +3).split(QChar(';'), QString::SkipEmptyParts);
 
504
        for (QStringList::ConstIterator it = sess.constBegin(); it != sess.constEnd(); ++it) {
 
505
            QStringList ts = (*it).split(QChar(','));
 
506
            SessEnt se;
 
507
            se.display = ts[0];
 
508
            se.user = ts[1];
 
509
            se.vt = ts[2].toInt();
 
510
            se.session = "<unknown>";
 
511
            se.self = ts[0] == ::getenv("DISPLAY"); /* Bleh */
 
512
            se.tty = false;
 
513
            list.append(se);
 
514
        }
 
515
    } else {
 
516
        if (!exec("list\talllocal\n", re))
 
517
            return false;
 
518
        const QStringList sess = QString(re.data() + 3).split(QChar('\t'), QString::SkipEmptyParts);
 
519
        for (QStringList::ConstIterator it = sess.constBegin(); it != sess.constEnd(); ++it) {
 
520
            QStringList ts = (*it).split(QChar(','));
 
521
            SessEnt se;
 
522
            se.display = ts[0];
 
523
            se.vt = ts[1].mid(2).toInt();
 
524
            se.user = ts[2];
 
525
            se.session = ts[3];
 
526
            se.self = (ts[4].indexOf('*') >= 0);
 
527
            se.tty = (ts[4].indexOf('t') >= 0);
 
528
            list.append(se);
 
529
        }
 
530
    }
 
531
    return true;
 
532
}
 
533
 
 
534
void
 
535
KDisplayManager::sess2Str2(const SessEnt &se, QString &user, QString &loc)
 
536
{
 
537
    if (se.tty) {
 
538
        user = i18nc("user: ...", "%1: TTY login", se.user);
 
539
        loc = se.vt ? QString("vt%1").arg(se.vt) : se.display ;
 
540
    } else {
 
541
        user =
 
542
            se.user.isEmpty() ?
 
543
                se.session.isEmpty() ?
 
544
                    i18nc("... location (TTY or X display)", "Unused") :
 
545
                    se.session == "<remote>" ?
 
546
                        i18n("X login on remote host") :
 
547
                        i18nc("... host", "X login on %1", se.session) :
 
548
                se.session == "<unknown>" ?
 
549
                    se.user :
 
550
                    i18nc("user: session type", "%1: %2",
 
551
                          se.user, se.session);
 
552
        loc =
 
553
            se.vt ?
 
554
                QString("%1, vt%2").arg(se.display).arg(se.vt) :
 
555
                se.display;
 
556
    }
 
557
}
 
558
 
 
559
QString
 
560
KDisplayManager::sess2Str(const SessEnt &se)
 
561
{
 
562
    QString user, loc;
 
563
 
 
564
    sess2Str2(se, user, loc);
 
565
    return i18nc("session (location)", "%1 (%2)", user, loc);
 
566
}
 
567
 
 
568
bool
 
569
KDisplayManager::switchVT(int vt)
 
570
{
 
571
    if (DMType == NewGDM || DMType == LightDM) {
 
572
        QDBusObjectPath currentSeat;
 
573
        if (getCurrentSeat(0, &currentSeat)) {
 
574
            foreach (const QDBusObjectPath &sp, getSessionsForSeat(currentSeat)) {
 
575
                CKSession lsess(sp);
 
576
                if (lsess.isValid()) {
 
577
                    SessEnt se;
 
578
                    getSessionLocation(lsess, se);
 
579
                    if (se.vt == vt) {
 
580
                        if (se.tty) // ConsoleKit simply ignores these
 
581
                            return false;
 
582
                        lsess.call(QLatin1String("Activate"));
 
583
                        return true;
 
584
                    }
 
585
                }
 
586
            }
 
587
        }
 
588
        return false;
 
589
    }
 
590
 
 
591
    if (DMType == OldGDM)
 
592
        return exec(QString("SET_VT %1\n").arg(vt).toLatin1());
 
593
 
 
594
    return exec(QString("activate\tvt%1\n").arg(vt).toLatin1());
 
595
}
 
596
 
 
597
void
 
598
KDisplayManager::lockSwitchVT(int vt)
 
599
{
 
600
    if (switchVT(vt)) {
 
601
        QDBusInterface screensaver("org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver");
 
602
        screensaver.call("Lock");
 
603
    }
 
604
}
 
605
 
 
606
void
 
607
KDisplayManager::GDMAuthenticate()
 
608
{
 
609
    FILE *fp;
 
610
    const char *dpy, *dnum, *dne;
 
611
    int dnl;
 
612
    Xauth *xau;
 
613
 
 
614
    dpy = DisplayString(QX11Info::display());
 
615
    if (!dpy) {
 
616
        dpy = ::getenv("DISPLAY");
 
617
        if (!dpy)
 
618
            return;
 
619
    }
 
620
    dnum = strchr(dpy, ':') + 1;
 
621
    dne = strchr(dpy, '.');
 
622
    dnl = dne ? dne - dnum : strlen(dnum);
 
623
 
 
624
    /* XXX should do locking */
 
625
    if (!(fp = fopen(XauFileName(), "r")))
 
626
        return;
 
627
 
 
628
    while ((xau = XauReadAuth(fp))) {
 
629
        if (xau->family == FamilyLocal &&
 
630
            xau->number_length == dnl && !memcmp(xau->number, dnum, dnl) &&
 
631
            xau->data_length == 16 &&
 
632
            xau->name_length == 18 && !memcmp(xau->name, "MIT-MAGIC-COOKIE-1", 18))
 
633
        {
 
634
            QString cmd("AUTH_LOCAL ");
 
635
            for (int i = 0; i < 16; i++)
 
636
                cmd += QString::number((uchar)xau->data[i], 16).rightJustified(2, '0');
 
637
            cmd += '\n';
 
638
            if (exec(cmd.toLatin1())) {
 
639
                XauDisposeAuth(xau);
 
640
                break;
 
641
            }
 
642
        }
 
643
        XauDisposeAuth(xau);
 
644
    }
 
645
 
 
646
    fclose (fp);
 
647
}
 
648
 
 
649
#endif // Q_WS_X11