[PATCH] ntdll: Implement SystemBatteryState for Mac OS.

Chip Davis cdavis at codeweavers.com
Sun Nov 24 20:09:31 CST 2019


Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---
 dlls/ntdll/nt.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index ceda544a4df..3aa17b4f422 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -38,6 +38,9 @@
 #endif
 #ifdef HAVE_IOKIT_IOKITLIB_H
 # include <IOKit/IOKitLib.h>
+# include <IOKit/pwr_mgt/IOPM.h>
+# include <IOKit/pwr_mgt/IOPMLib.h>
+# include <IOKit/ps/IOPowerSources.h>
 #endif
 
 #include <ctype.h>
@@ -3338,6 +3341,73 @@ static NTSTATUS fill_battery_state(SYSTEM_BATTERY_STATE *bs)
 	return STATUS_SUCCESS;
 }
 
+#elif defined(HAVE_IOKIT_IOKITLIB_H)
+
+static NTSTATUS fill_battery_state(SYSTEM_BATTERY_STATE *bs)
+{
+	CFArrayRef batteries;
+	CFDictionaryRef battery;
+	CFNumberRef prop;
+	uint32_t value, voltage;
+	CFTimeInterval remain;
+
+	if (IOPMCopyBatteryInfo( kIOMasterPortDefault, &batteries ) != kIOReturnSuccess)
+		return STATUS_ACCESS_DENIED;
+
+	if (CFArrayGetCount( batteries ) == 0)
+	{
+		/* Just assume we're on AC with no battery. */
+		bs->AcOnLine = TRUE;
+		return STATUS_SUCCESS;
+	}
+	/* Just use the first battery. */
+	battery = CFArrayGetValueAtIndex( batteries, 0 );
+
+	prop = CFDictionaryGetValue( battery, CFSTR(kIOBatteryFlagsKey) );
+	CFNumberGetValue( prop, kCFNumberSInt32Type, &value );
+
+	if (value & kIOBatteryInstalled)
+		bs->BatteryPresent = TRUE;
+	else
+		/* Since we are executing code, we must have AC power. */
+		bs->AcOnLine = TRUE;
+	if (value & kIOBatteryChargerConnect)
+	{
+		bs->AcOnLine = TRUE;
+		if (value & kIOBatteryCharge)
+			bs->Charging = TRUE;
+	}
+	else
+		bs->Discharging = TRUE;
+
+	/* We'll need the voltage to be able to interpret the other values. */
+	prop = CFDictionaryGetValue( battery, CFSTR(kIOBatteryVoltageKey) );
+	CFNumberGetValue( prop, kCFNumberSInt32Type, &voltage );
+
+	prop = CFDictionaryGetValue( battery, CFSTR(kIOBatteryCapacityKey) );
+	CFNumberGetValue( prop, kCFNumberSInt32Type, &value );
+	bs->MaxCapacity = value * voltage;
+	/* Apple uses "estimated time < 10:00" and "22%" for these, but we'll follow
+	 * Windows for now (5% and 33%). */
+	bs->DefaultAlert1 = bs->MaxCapacity / 20;
+	bs->DefaultAlert2 = bs->MaxCapacity / 3;
+
+	prop = CFDictionaryGetValue( battery, CFSTR(kIOBatteryCurrentChargeKey) );
+	CFNumberGetValue( prop, kCFNumberSInt32Type, &value );
+	bs->RemainingCapacity = value * voltage;
+
+	prop = CFDictionaryGetValue( battery, CFSTR(kIOBatteryAmperageKey) );
+	CFNumberGetValue( prop, kCFNumberSInt32Type, &value );
+	bs->Rate = value * voltage;
+
+	remain = IOPSGetTimeRemainingEstimate();
+	if (remain != kIOPSTimeRemainingUnknown && remain != kIOPSTimeRemainingUnlimited)
+		bs->EstimatedTime = (ULONG)remain;
+
+	CFRelease( batteries );
+	return STATUS_SUCCESS;
+}
+
 #else
 
 static NTSTATUS fill_battery_state(SYSTEM_BATTERY_STATE *bs)
-- 
2.21.0




More information about the wine-devel mailing list