From: Rafael Sadowski Subject: Control battery charging support in x11/kde-plasma/powerdevil To: ports Date: Fri, 7 Jun 2024 11:20:29 +0200 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 + ++#if defined(__OpenBSD__) ++ #include ++ #include ++#endif ++ + #include + + #include +@@ -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) +