Index | Thread | Search

From:
Rafael Sadowski <rafael@sizeofvoid.org>
Subject:
Control battery charging support in x11/kde-plasma/powerdevil
To:
ports <ports@openbsd.org>
Date:
Fri, 7 Jun 2024 11:20:29 +0200

Download raw body.

Thread
Please find below a simple patch to add control battery charging support
in powerdevil aka KDE Plamsa - systemsettings via sysctl(2).

I would be happy if someone would take a look at the code.

Rafael

Index: Makefile
===================================================================
RCS file: /cvs/ports/x11/kde-plasma/powerdevil/Makefile,v
diff -u -p -r1.4 Makefile
--- Makefile	20 May 2024 06:39:26 -0000	1.4
+++ Makefile	7 Jun 2024 09:16:00 -0000
@@ -1,5 +1,6 @@
 COMMENT =	power management daemon
 DISTNAME =	powerdevil-${VERSION}
+REVISION =	0
 
 WANTLIB += ${COMPILER_LIBCXX} GL KF6AuthCore KF6ColorScheme KF6Completion
 WANTLIB += KF6ConfigCore KF6ConfigGui KF6ConfigWidgets KF6CoreAddons
Index: patches/patch-daemon_chargethresholdhelper_cpp
===================================================================
RCS file: patches/patch-daemon_chargethresholdhelper_cpp
diff -N patches/patch-daemon_chargethresholdhelper_cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-daemon_chargethresholdhelper_cpp	7 Jun 2024 09:16:00 -0000
@@ -0,0 +1,113 @@
+Index: daemon/chargethresholdhelper.cpp
+--- daemon/chargethresholdhelper.cpp.orig
++++ daemon/chargethresholdhelper.cpp
+@@ -8,6 +8,11 @@
+ 
+ #include <powerdevil_debug.h>
+ 
++#if defined(__OpenBSD__)
++  #include <sys/types.h>
++  #include <sys/sysctl.h>
++#endif
++
+ #include <KAuth/HelperSupport>
+ 
+ #include <algorithm>
+@@ -107,10 +112,89 @@ static bool setThresholds(const QString &which, int th
+     return true;
+ }
+ 
++#if defined(__OpenBSD__)
++static bool isThresholdSupported()
++{
++    int mode;
++    size_t len = sizeof(mode);
++    int mib[] = {CTL_HW, HW_BATTERY, HW_BATTERY_CHARGEMODE};
++    return (sysctl(mib, 3, &mode, &len, NULL, 0) != -1);
++}
++
++static int getBatteryCharge(const int type)
++{
++    int percentage = -1;
++    size_t len = sizeof(percentage);
++    int mib[] = {CTL_HW, HW_BATTERY, type};
++    sysctl(mib, 3, &percentage, &len, NULL, 0);
++    return percentage;
++}
++
++static bool setBatteryCharge(const int type, int percentage)
++{
++    size_t len = sizeof(percentage);
++    int mib[] = {CTL_HW, HW_BATTERY, type};
++    return (sysctl(mib, 3, NULL, 0, &percentage, len) != -1);
++}
++
+ ActionReply ChargeThresholdHelper::getthreshold(const QVariantMap &args)
+ {
+     Q_UNUSED(args);
+ 
++    if (!isThresholdSupported()) {
++        auto reply = ActionReply::HelperErrorReply();
++        reply.setErrorDescription(QStringLiteral("Control battery charging is not supported by the kernel for this hardware"));
++        return reply;
++    }
++
++    const int startThreshold = getBatteryCharge(HW_BATTERY_CHARGESTART);
++    const int stopThreshold = getBatteryCharge(HW_BATTERY_CHARGESTOP);
++
++    ActionReply reply;
++    reply.setData({
++        {QStringLiteral("chargeStartThreshold"), startThreshold},
++        {QStringLiteral("chargeStopThreshold"), stopThreshold},
++    });
++    return reply;
++}
++
++ActionReply ChargeThresholdHelper::setthreshold(const QVariantMap &args)
++{
++    bool hasStartThreshold;
++    const int startThreshold = args.value(QStringLiteral("chargeStartThreshold"), -1).toInt(&hasStartThreshold);
++    hasStartThreshold &= startThreshold != -1;
++
++    bool hasStopThreshold;
++    const int stopThreshold = args.value(QStringLiteral("chargeStopThreshold"), -1).toInt(&hasStopThreshold);
++    hasStopThreshold &= stopThreshold != -1;
++
++    if ((hasStartThreshold && (startThreshold < 0 || startThreshold > 100)) || (hasStopThreshold && (stopThreshold < 0 || stopThreshold > 100))
++        || (hasStartThreshold && hasStopThreshold && startThreshold > stopThreshold) || (!hasStartThreshold && !hasStopThreshold)) {
++        auto reply = ActionReply::HelperErrorReply(); // is there an "invalid arguments" error?
++        reply.setErrorDescription(QStringLiteral("Invalid thresholds provided"));
++        return reply;
++    }
++    if (hasStartThreshold && !(setBatteryCharge(HW_BATTERY_CHARGESTART, startThreshold)
++        || setBatteryCharge(HW_BATTERY_CHARGESTART, startThreshold))) {
++        auto reply = ActionReply::HelperErrorReply();
++        reply.setErrorDescription(QStringLiteral("Failed to write start charge threshold"));
++        return reply;
++    }
++
++    if (hasStopThreshold && !(setBatteryCharge(HW_BATTERY_CHARGESTOP, stopThreshold)
++        || setBatteryCharge(HW_BATTERY_CHARGESTOP, stopThreshold))) {
++        auto reply = ActionReply::HelperErrorReply();
++        reply.setErrorDescription(QStringLiteral("Failed to write stop charge threshold"));
++        return reply;
++    }
++
++    return ActionReply();
++}
++#else // Linux and friends
++ActionReply ChargeThresholdHelper::getthreshold(const QVariantMap &args)
++{
++    Q_UNUSED(args);
++
+     auto startThresholds = getThresholds(s_chargeStartThreshold);
+     auto stopThresholds = getThresholds(s_chargeEndThreshold);
+ 
+@@ -174,6 +258,7 @@ ActionReply ChargeThresholdHelper::setthreshold(const 
+ 
+     return ActionReply();
+ }
++#endif
+ 
+ KAUTH_HELPER_MAIN("org.kde.powerdevil.chargethresholdhelper", ChargeThresholdHelper)
+