Alex Henrie : ntdll: Implement NtPowerInformation(SystemBatteryState) on Linux.
Alexandre Julliard
julliard at winehq.org
Thu Oct 31 17:39:29 CDT 2019
Module: wine
Branch: master
Commit: 63ddf0343b352d5709a587b9a1efc52bf111ab6a
URL: https://source.winehq.org/git/wine.git/?a=commit;h=63ddf0343b352d5709a587b9a1efc52bf111ab6a
Author: Alex Henrie <alexhenrie24 at gmail.com>
Date: Tue Oct 29 20:22:23 2019 -0600
ntdll: Implement NtPowerInformation(SystemBatteryState) on Linux.
Signed-off-by: Alex Henrie <alexhenrie24 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/nt.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 5afdf77986..81bac70b0f 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -3137,6 +3137,73 @@ static ULONG mhz_from_cpuinfo(void)
}
#endif
+#ifdef linux
+
+static const char * get_sys_str(const char *path)
+{
+ static char s[16];
+ FILE *f = fopen(path, "r");
+ const char *ret = NULL;
+ if (f)
+ {
+ if (fgets(s, sizeof(s), f))
+ ret = s;
+ fclose(f);
+ }
+ return ret;
+}
+
+static int get_sys_int(const char *path, int def)
+{
+ const char *s = get_sys_str(path);
+ return s ? atoi(s) : def;
+}
+
+static NTSTATUS fill_battery_state(SYSTEM_BATTERY_STATE *bs)
+{
+ char path[64];
+ const char *s;
+ unsigned int i = 0;
+ LONG64 voltage; /* microvolts */
+
+ bs->AcOnLine = get_sys_int("/sys/class/power_supply/AC/online", 1);
+
+ for (;;)
+ {
+ sprintf(path, "/sys/class/power_supply/BAT%u/status", i);
+ s = get_sys_str(path);
+ if (!s) break;
+ bs->Charging |= (strcmp(s, "Charging\n") == 0);
+ bs->Discharging |= (strcmp(s, "Discharging\n") == 0);
+ bs->BatteryPresent = TRUE;
+ i++;
+ }
+
+ if (bs->BatteryPresent)
+ {
+ voltage = get_sys_int("/sys/class/power_supply/BAT0/voltage_now", 0);
+ bs->MaxCapacity = get_sys_int("/sys/class/power_supply/BAT0/charge_full", 0) * voltage / 1e9;
+ bs->RemainingCapacity = get_sys_int("/sys/class/power_supply/BAT0/charge_now", 0) * voltage / 1e9;
+ bs->Rate = -get_sys_int("/sys/class/power_supply/BAT0/current_now", 0) * voltage / 1e9;
+ if (!bs->Charging && (LONG)bs->Rate < 0)
+ bs->EstimatedTime = 3600 * bs->RemainingCapacity / -(LONG)bs->Rate;
+ else
+ bs->EstimatedTime = ~0u;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+#else
+
+static NTSTATUS fill_battery_state(SYSTEM_BATTERY_STATE *)
+{
+ FIXME("SystemBatteryState not implemented on this platform\n");
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+#endif
+
/******************************************************************************
* NtPowerInformation [NTDLL.@]
*
@@ -3190,6 +3257,12 @@ NTSTATUS WINAPI NtPowerInformation(
PowerCaps->DefaultLowLatencyWake = PowerSystemUnspecified;
return STATUS_SUCCESS;
}
+ case SystemBatteryState: {
+ if (nOutputBufferSize < sizeof(SYSTEM_BATTERY_STATE))
+ return STATUS_BUFFER_TOO_SMALL;
+ memset(lpOutputBuffer, 0, sizeof(SYSTEM_BATTERY_STATE));
+ return fill_battery_state(lpOutputBuffer);
+ }
case SystemExecutionState: {
PULONG ExecutionState = lpOutputBuffer;
WARN("semi-stub: SystemExecutionState\n"); /* Needed for .NET Framework, but using a FIXME is really noisy. */
More information about the wine-cvs
mailing list