File indexing completed on 2024-04-14 05:21:19

0001 /*
0002 SPDX-FileCopyrightText: 1999 Martin R. Jones <mjones@kde.org>
0003 SPDX-FileCopyrightText: 2002 Luboš Luňák <l.lunak@kde.org>
0004 SPDX-FileCopyrightText: 2003 Oswald Buddenhagen <ossi@kde.org>
0005 SPDX-FileCopyrightText: 2008 Chani Armitage <chanika@gmail.com>
0006 SPDX-FileCopyrightText: 2011 Martin Gräßlin <mgraesslin@kde.org>
0007 SPDX-FileCopyrightText: 2015 Bhushan Shah <bhush94@gmail.com>
0008 
0009 SPDX-License-Identifier: GPL-2.0-or-later
0010 */
0011 
0012 #include "abstractlocker.h"
0013 
0014 #include <QApplication>
0015 #include <QPainter>
0016 #include <QScreen>
0017 #include <QtDBus>
0018 
0019 #include <KLocalizedString>
0020 
0021 namespace ScreenLocker
0022 {
0023 BackgroundWindow::BackgroundWindow(AbstractLocker *lock)
0024     : QRasterWindow()
0025     , m_lock(lock)
0026 {
0027     setFlags(Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint);
0028     setProperty("org_kde_ksld_emergency", true);
0029 }
0030 
0031 BackgroundWindow::~BackgroundWindow() = default;
0032 
0033 void BackgroundWindow::paintEvent(QPaintEvent *)
0034 {
0035     QPainter p(this);
0036     p.fillRect(0, 0, width(), height(), Qt::black);
0037     if (m_greeterFailure) {
0038         auto text = ki18n(
0039             "The screen locker is broken and unlocking is not possible anymore.\n"
0040             "In order to unlock it either ConsoleKit or LoginD is needed, neither\n"
0041             "of which could be found on your system.");
0042         auto text_ck = ki18nc("%1 = other terminal",
0043             "The screen locker is broken and unlocking is not possible anymore.\n"
0044             "In order to unlock it, switch to a virtual terminal (e.g. Ctrl+Alt+F%1),\n"
0045             "log in as root and execute the command:\n\n"
0046             "# ck-unlock-session <session-name>\n\n");
0047         auto text_ld = ki18nc("%1 = other terminal, %2 = session ID, %3 = this terminal",
0048             "The screen locker is broken and unlocking is not possible anymore.\n"
0049             "In order to unlock it, switch to a virtual terminal (e.g. Ctrl+Alt+F%1),\n"
0050             "log in to your account and execute the command:\n\n"
0051             "loginctl unlock-session %2\n\n"
0052             "Then log out of the virtual session by pressing Ctrl+D, and switch\n"
0053             "back to the running session (Ctrl+Alt+F%3).\n"
0054             "Should you have forgotten the instructions, you can get back to this\n"
0055             "screen by pressing Ctrl+Alt+F%3\n\n");
0056 
0057         auto haveService = [](QString service) {
0058             return QDBusConnection::systemBus().interface()->isServiceRegistered(service);
0059         };
0060         if (haveService(QStringLiteral("org.freedesktop.ConsoleKit"))) {
0061             auto virtualTerminalId = qgetenv("XDG_VTNR").toInt();
0062             text = text_ck.subs(virtualTerminalId == 2 ? 1 : 2);
0063         } else if (haveService(QStringLiteral("org.freedesktop.login1"))) {
0064             text = text_ld;
0065             auto virtualTerminalId = qgetenv("XDG_VTNR").toInt();
0066             text = text.subs(virtualTerminalId == 2 ? 1 : 2);
0067             text = text.subs(QString::fromLocal8Bit(qgetenv("XDG_SESSION_ID")));
0068             text = text.subs(virtualTerminalId);
0069         }
0070 
0071         p.setPen(Qt::white);
0072         QFont f = p.font();
0073         f.setBold(true);
0074         f.setPointSize(24);
0075         // for testing emergency mode, we need to disable antialias, as otherwise
0076         // screen wouldn't be completely black and white.
0077         if (qEnvironmentVariableIsSet("KSLD_TESTMODE")) {
0078             f.setStyleStrategy(QFont::NoAntialias);
0079         }
0080         p.setFont(f);
0081         const auto screens = QGuiApplication::screens();
0082         for (auto s : screens) {
0083             p.drawText(s->geometry(), Qt::AlignVCenter | Qt::AlignHCenter, text.toString());
0084         }
0085     }
0086     m_lock->stayOnTop();
0087 }
0088 
0089 void BackgroundWindow::emergencyShow()
0090 {
0091     m_greeterFailure = true;
0092     update();
0093     show();
0094 }
0095 
0096 AbstractLocker::AbstractLocker(QObject *parent)
0097     : QObject(parent)
0098 {
0099     if (qobject_cast<QGuiApplication *>(QCoreApplication::instance())) {
0100         m_background.reset(new BackgroundWindow(this));
0101     }
0102 }
0103 
0104 AbstractLocker::~AbstractLocker()
0105 {
0106 }
0107 
0108 void AbstractLocker::emergencyShow()
0109 {
0110     if (m_background.isNull()) {
0111         return;
0112     }
0113     m_background->emergencyShow();
0114 }
0115 
0116 void AbstractLocker::addAllowedWindow(quint32 windows)
0117 {
0118     Q_UNUSED(windows);
0119 }
0120 
0121 }
0122 
0123 #include "moc_abstractlocker.cpp"