File indexing completed on 2022-04-22 12:14:03

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