From: Tomas Mendes rtdiasmendes@gmail.com
--- dlls/kernel32/powermgnt.c | 4 +- dlls/ntdll/unix/system.c | 90 +++++++++++++++++++++++++++------------ 2 files changed, 64 insertions(+), 30 deletions(-)
diff --git a/dlls/kernel32/powermgnt.c b/dlls/kernel32/powermgnt.c index c4bd97553fe..23c55b1cd83 100644 --- a/dlls/kernel32/powermgnt.c +++ b/dlls/kernel32/powermgnt.c @@ -65,11 +65,11 @@ BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS ps) { ps->BatteryLifePercent = bs.MaxCapacity ? 100 * bs.RemainingCapacity / bs.MaxCapacity : 100; ps->BatteryLifeTime = bs.EstimatedTime; - if (!bs.Charging && (LONG)bs.Rate < 0) + if ((LONG)bs.Rate < 0) ps->BatteryFullLifeTime = 3600 * bs.MaxCapacity / -(LONG)bs.Rate;
ps->BatteryFlag = 0; - if (bs.Charging) + if (bs.Rate > 0) ps->BatteryFlag |= BATTERY_FLAG_CHARGING; if (ps->BatteryLifePercent > 66) ps->BatteryFlag |= BATTERY_FLAG_HIGH; diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index 551ef10980e..1a0090a83b4 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -4071,12 +4071,13 @@ static NTSTATUS fill_battery_state( SYSTEM_BATTERY_STATE *bs ) DIR *d = opendir("/sys/class/power_supply"); struct dirent *de; char s[16], path[64]; - BOOL found_ac = FALSE; - LONG64 voltage; /* microvolts */ + struct linux_battery bat;
- bs->AcOnLine = TRUE; if (!d) return STATUS_SUCCESS;
+ bs->BatteryPresent = FALSE; + bs->AcOnLine = FALSE; + while ((de = readdir(d))) { if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; @@ -4084,44 +4085,77 @@ static NTSTATUS fill_battery_state( SYSTEM_BATTERY_STATE *bs ) if (get_sys_str(path, "scope", s) && strcmp(s, "Device\n") == 0) continue; if (!get_sys_str(path, "type", s)) continue;
- if (strcmp(s, "Mains\n") == 0) + if (!strcmp(s, "Mains\n") && + !bs->AcOnLine && + get_sys_int(path, "online")) + { + bs->AcOnLine = TRUE; + } + else if (!strcmp(s, "Battery\n")) { - if (!get_sys_str(path, "online", s)) continue; - if (found_ac) + get_sys_bat(path, &bat); + + if (!bat.present) continue; + + if (!bs->BatteryPresent) { - FIXME("Multiple mains found, only reporting on the first\n"); + bs->BatteryPresent = TRUE; + bs->Charging = FALSE; + bs->Discharging = FALSE; + bs->MaxCapacity = 0u; + bs->RemainingCapacity = 0u; + bs->Rate = 0u; + bs->EstimatedTime = ~0u; + bs->DefaultAlert1 = 0u; + bs->DefaultAlert2 = 0u; } - else + + if (bat.status == BATTERY_CHARGING && !bs->Charging) bs->Charging = TRUE; + if (bat.status == BATTERY_DISCHARGING && !bs->Discharging) bs->Discharging = TRUE; + + switch (bat.power_unit) + { + case 0: + continue; + case 1: + bs->MaxCapacity += (ULONG)(bat.full_charge_capacity / 1e3); + bs->RemainingCapacity += (ULONG)(bat.capacity_now / 1e3); + if (bat.status == BATTERY_CHARGING) bs->Rate += (ULONG)(bat.rate_now / 1e3); + if (bat.status == BATTERY_DISCHARGING) bs->Rate -= (ULONG)(bat.rate_now / 1e3); + break; + case 2: + bs->MaxCapacity += (ULONG)(bat.full_charge_capacity * bat.voltage_now / 1e9); + bs->RemainingCapacity += (ULONG)(bat.capacity_now * bat.voltage_now / 1e9); + if (bat.status == BATTERY_UNKNOWN || !bat.rate_now) continue; + if (bat.status == BATTERY_DISCHARGING && bat.rate_now > 0) + bs->Rate -= (ULONG)(bat.rate_now * bat.voltage_now / 1e9); + else + bs->Rate += (ULONG)(bat.rate_now * bat.voltage_now / 1e9); + break; + } + + if(bat.alarm) { - bs->AcOnLine = atoi(s); - found_ac = TRUE; + bs->DefaultAlert1 = bs->MaxCapacity / 20; + bs->DefaultAlert2 = (ULONG)(bat.alarm); } - } - else if (strcmp(s, "Battery\n") == 0) - { - if (!get_sys_str(path, "status", s)) continue; - if (bs->BatteryPresent) + else if(bat.capacity_alert_min && bat.capacity_alert_max) { - FIXME("Multiple batteries found, only reporting on the first\n"); + bs->DefaultAlert1 = bs->MaxCapacity * bat.capacity_alert_min / 100; + bs->DefaultAlert2 = bs->MaxCapacity * bat.capacity_alert_max / 100; } else { - bs->Charging = (strcmp(s, "Charging\n") == 0); - bs->Discharging = (strcmp(s, "Discharging\n") == 0); - bs->BatteryPresent = TRUE; - voltage = get_sys_int(path, "voltage_now"); - bs->MaxCapacity = get_sys_int(path, "charge_full") * voltage / 1e9; - bs->RemainingCapacity = get_sys_int(path, "charge_now") * voltage / 1e9; - bs->Rate = -get_sys_int(path, "current_now") * voltage / 1e9; - if (!bs->Charging && (LONG)bs->Rate < 0) - bs->EstimatedTime = 3600 * bs->RemainingCapacity / -(LONG)bs->Rate; - else - bs->EstimatedTime = ~0u; + bs->DefaultAlert1 = bs->MaxCapacity / 20; + bs->DefaultAlert2 = bs->MaxCapacity / 3; } } } - closedir(d); + + if (bs->BatteryPresent && (LONG)bs->Rate < 0) + bs->EstimatedTime = 3600 * bs->RemainingCapacity / -bs->Rate; + return STATUS_SUCCESS; }