File indexing completed on 2024-04-28 13:21:10
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 = ki18n( 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 = ki18n( 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%2\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 }