// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: 2026 A-La-Karte Contributors #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KAuth; static const QString kPowerProfilesService = QStringLiteral("net.hadess.PowerProfiles"); static const QString kPowerProfilesPath = QStringLiteral("/net/hadess/PowerProfiles"); static const QString kPowerProfilesInterface = QStringLiteral("net.hadess.PowerProfiles"); static const QString kLogin1Service = QStringLiteral("org.freedesktop.login1"); static const QString kLogin1ManagerPath = QStringLiteral("/org/freedesktop/login1"); static const QString kLogin1ManagerIface = QStringLiteral("org.freedesktop.login1.Manager"); static const QString kLogin1SeatPath = QStringLiteral("/org/freedesktop/login1/seat/seat0"); static const QString kLogin1SeatIface = QStringLiteral("org.freedesktop.login1.Seat"); class GameCenterHelper : public QObject { Q_OBJECT public Q_SLOTS: ActionReply setpowerprofile(const QVariantMap &args); ActionReply activate_session(const QVariantMap &args); ActionReply switch_to_vt(const QVariantMap &args); ActionReply terminate_session(const QVariantMap &args); }; static QVariant unwrapDbusVariant(QVariant v) { if (v.canConvert()) { v = v.value().variant(); } return v; } static QString unwrapStringArg(const QVariantMap &args, const QString &key) { QVariant v = args.value(key); if (v.canConvert()) { v = v.value().variant(); } return v.toString(); } ActionReply GameCenterHelper::setpowerprofile(const QVariantMap &args) { const QString profile = unwrapStringArg(args, QStringLiteral("profile")); if (profile.isEmpty()) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("missing profile")); return reply; } QDBusConnection bus = QDBusConnection::systemBus(); if (!bus.isConnected()) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("system bus not connected")); return reply; } if (bus.interface() && !bus.interface()->isServiceRegistered(kPowerProfilesService)) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("power-profiles-daemon service not available")); return reply; } QDBusInterface props(kPowerProfilesService, kPowerProfilesPath, QStringLiteral("org.freedesktop.DBus.Properties"), bus); if (!props.isValid()) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("power-profiles-daemon D-Bus interface not available")); return reply; } { const QDBusReply profilesReply = props.call(QStringLiteral("Get"), kPowerProfilesInterface, QStringLiteral("Profiles")); if (profilesReply.isValid()) { QVariant v = unwrapDbusVariant(profilesReply.value()); QVariantList list; if (v.canConvert()) { list = qdbus_cast(v.value()); } else if (v.canConvert()) { list = v.toList(); } if (!list.isEmpty()) { QStringList available; available.reserve(list.size()); for (const QVariant &item : list) { QVariant mV = unwrapDbusVariant(item); QVariantMap m; if (mV.canConvert()) { m = qdbus_cast(mV.value()); } else if (mV.canConvert()) { m = mV.toMap(); } const QString name = m.value(QStringLiteral("Profile")).toString(); if (!name.isEmpty()) { available.push_back(name); } } if (!available.isEmpty() && !available.contains(profile)) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("unsupported profile '%1'").arg(profile)); reply.addData(QStringLiteral("available"), available); return reply; } } } } QDBusMessage msg = QDBusMessage::createMethodCall(kPowerProfilesService, kPowerProfilesPath, QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("Set")); msg.setArguments({kPowerProfilesInterface, QStringLiteral("ActiveProfile"), QVariant::fromValue(QDBusVariant(profile))}); const QDBusMessage replyMsg = bus.call(msg, QDBus::Block, 5000); if (replyMsg.type() == QDBusMessage::ErrorMessage) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(replyMsg.errorName() + QStringLiteral(": ") + replyMsg.errorMessage()); return reply; } return ActionReply::SuccessReply(); } ActionReply GameCenterHelper::activate_session(const QVariantMap &args) { const QString sessionId = unwrapStringArg(args, QStringLiteral("sessionId")); if (sessionId.isEmpty()) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("missing sessionId")); return reply; } QDBusConnection bus = QDBusConnection::systemBus(); if (!bus.isConnected()) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("system bus not connected")); return reply; } QDBusInterface mgr(kLogin1Service, kLogin1ManagerPath, kLogin1ManagerIface, bus); if (!mgr.isValid()) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("login1 manager interface not available")); return reply; } const QDBusMessage replyMsg = mgr.call(QStringLiteral("ActivateSession"), sessionId); if (replyMsg.type() == QDBusMessage::ErrorMessage) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(replyMsg.errorName() + QStringLiteral(": ") + replyMsg.errorMessage()); return reply; } return ActionReply::SuccessReply(); } ActionReply GameCenterHelper::switch_to_vt(const QVariantMap &args) { QVariant vtArg = args.value(QStringLiteral("vtnr")); if (vtArg.canConvert()) { vtArg = vtArg.value().variant(); } bool ok = false; const uint vtnr = vtArg.toUInt(&ok); if (!ok || vtnr == 0) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("missing or invalid vtnr")); return reply; } QDBusConnection bus = QDBusConnection::systemBus(); if (!bus.isConnected()) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("system bus not connected")); return reply; } QDBusInterface seat(kLogin1Service, kLogin1SeatPath, kLogin1SeatIface, bus); if (!seat.isValid()) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("login1 seat interface not available")); return reply; } const QDBusMessage replyMsg = seat.call(QStringLiteral("SwitchTo"), vtnr); if (replyMsg.type() == QDBusMessage::ErrorMessage) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(replyMsg.errorName() + QStringLiteral(": ") + replyMsg.errorMessage()); return reply; } return ActionReply::SuccessReply(); } ActionReply GameCenterHelper::terminate_session(const QVariantMap &args) { const QString sessionId = unwrapStringArg(args, QStringLiteral("sessionId")); if (sessionId.isEmpty()) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("missing sessionId")); return reply; } QDBusConnection bus = QDBusConnection::systemBus(); if (!bus.isConnected()) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("system bus not connected")); return reply; } QDBusInterface mgr(kLogin1Service, kLogin1ManagerPath, kLogin1ManagerIface, bus); if (!mgr.isValid()) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(QStringLiteral("login1 manager interface not available")); return reply; } const QDBusMessage replyMsg = mgr.call(QStringLiteral("TerminateSession"), sessionId); if (replyMsg.type() == QDBusMessage::ErrorMessage) { ActionReply reply = ActionReply::HelperErrorReply(); reply.setErrorDescription(replyMsg.errorName() + QStringLiteral(": ") + replyMsg.errorMessage()); return reply; } return ActionReply::SuccessReply(); } KAUTH_HELPER_MAIN("org.kde.alakarte.gamecenter.helper", GameCenterHelper) #include "gamecenterkauthhelper.moc"