mirror of
https://github.com/aristocratos/btop.git
synced 2024-09-28 22:21:35 +02:00
battery state via CoreFoundation
This commit is contained in:
parent
bbba17cd35
commit
c66b46f850
3
Makefile
3
Makefile
@ -93,6 +93,9 @@ ifdef DEBUG
|
|||||||
override OPTFLAGS := -O0 -g
|
override OPTFLAGS := -O0 -g
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(PLATFORM), OSX)
|
||||||
|
override LDCXXFLAGS += -framework IOKit -framework CoreFoundation
|
||||||
|
endif
|
||||||
ifneq ($(ARCH),arm64)
|
ifneq ($(ARCH),arm64)
|
||||||
ifneq ($(PLATFORM),OSX)
|
ifneq ($(PLATFORM),OSX)
|
||||||
override LDCXXFLAGS += -fstack-protector -fstack-clash-protection
|
override LDCXXFLAGS += -fstack-protector -fstack-clash-protection
|
||||||
|
@ -16,6 +16,13 @@ indent = tab
|
|||||||
tab-size = 4
|
tab-size = 4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#include <IOKit/IOCFSerialize.h>
|
||||||
|
#include <IOKit/IOMessage.h>
|
||||||
|
#include <IOKit/ps/IOPSKeys.h>
|
||||||
|
#include <IOKit/ps/IOPowerSources.h>
|
||||||
|
#include <IOKit/pwr_mgt/IOPM.h>
|
||||||
|
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#include <libproc.h>
|
#include <libproc.h>
|
||||||
@ -323,32 +330,39 @@ namespace Cpu {
|
|||||||
auto get_battery() -> tuple<int, long, string> {
|
auto get_battery() -> tuple<int, long, string> {
|
||||||
if (not has_battery) return {0, 0, ""};
|
if (not has_battery) return {0, 0, ""};
|
||||||
|
|
||||||
int percent = -1;
|
uint32_t percent = -1;
|
||||||
long seconds = -1;
|
long seconds = -1;
|
||||||
string status = "discharging";
|
string status = "discharging";
|
||||||
|
CFTypeRef ps_info = IOPSCopyPowerSourcesInfo();
|
||||||
FILE *bat = popen("pmset -g batt", "r");
|
if (ps_info) {
|
||||||
if (bat) {
|
CFArrayRef one_ps_descriptor = IOPSCopyPowerSourcesList(ps_info);
|
||||||
char buf[2048];
|
if (one_ps_descriptor) {
|
||||||
while (fgets(buf, sizeof(buf), bat) != NULL) {
|
CFDictionaryRef one_ps = IOPSGetPowerSourceDescription(ps_info, CFArrayGetValueAtIndex(one_ps_descriptor, 0));
|
||||||
char *perc = strstr(buf, "%");
|
has_battery = true;
|
||||||
if (perc) {
|
auto state = CFDictionaryGetValue(one_ps, CFSTR(kIOPSPowerSourceStateKey));
|
||||||
has_battery = true;
|
CFNumberRef remaining = (CFNumberRef)CFDictionaryGetValue(one_ps, CFSTR(kIOPSTimeToEmptyKey));
|
||||||
perc -= 3;
|
int32_t estimatedMinutesRemaining;
|
||||||
string p(perc);
|
if (remaining) {
|
||||||
p.resize(3);
|
CFNumberGetValue(remaining, kCFNumberSInt32Type, &estimatedMinutesRemaining);
|
||||||
percent = atoi(p.c_str());
|
seconds = estimatedMinutesRemaining * 60;
|
||||||
if (!strstr(buf, "discharging")) {
|
}
|
||||||
if (percent < 100) {
|
CFNumberRef charge = (CFNumberRef)CFDictionaryGetValue(one_ps, CFSTR(kIOPSCurrentCapacityKey));
|
||||||
status = "charging";
|
if (charge) {
|
||||||
} else {
|
CFNumberGetValue(charge, kCFNumberSInt32Type, &percent);
|
||||||
|
}
|
||||||
|
CFBooleanRef charging = (CFBooleanRef)CFDictionaryGetValue(one_ps, CFSTR(kIOPSIsChargingKey));
|
||||||
|
if (charging) {
|
||||||
|
bool isCharging = CFBooleanGetValue(charging);
|
||||||
|
if (isCharging) {
|
||||||
|
status = "charging";
|
||||||
|
if (percent == 100) {
|
||||||
status = "full";
|
status = "full";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
has_battery = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CFRelease(ps_info);
|
||||||
|
CFRelease(one_ps_descriptor);
|
||||||
}
|
}
|
||||||
return {percent, seconds, status};
|
return {percent, seconds, status};
|
||||||
}
|
}
|
||||||
@ -926,7 +940,7 @@ namespace Proc {
|
|||||||
if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0 || size == 0) {
|
if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0 || size == 0) {
|
||||||
Logger::error("Unable to get size of kproc_infos");
|
Logger::error("Unable to get size of kproc_infos");
|
||||||
}
|
}
|
||||||
|
uint64_t cpu_t = 0;
|
||||||
processes = (struct kinfo_proc *)malloc(size);
|
processes = (struct kinfo_proc *)malloc(size);
|
||||||
if (sysctl(mib, 4, processes, &size, NULL, 0) == 0) {
|
if (sysctl(mib, 4, processes, &size, NULL, 0) == 0) {
|
||||||
size_t count = size / sizeof(struct kinfo_proc);
|
size_t count = size / sizeof(struct kinfo_proc);
|
||||||
@ -944,10 +958,10 @@ namespace Proc {
|
|||||||
struct proc_taskinfo pti;
|
struct proc_taskinfo pti;
|
||||||
if (sizeof(pti) == proc_pidinfo(p.pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti))) {
|
if (sizeof(pti) == proc_pidinfo(p.pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti))) {
|
||||||
p.threads = pti.pti_threadnum;
|
p.threads = pti.pti_threadnum;
|
||||||
p.cpu_t = pti.pti_total_user + pti.pti_total_system;
|
cpu_t = pti.pti_total_user + pti.pti_total_system;
|
||||||
p.cpu_c = (double)p.cpu_t / max(1.0, (uptime * Shared::clkTck) - p.cpu_s);
|
|
||||||
p.cpu_p = 0;
|
|
||||||
p.cpu_s = pti.pti_total_system;
|
p.cpu_s = pti.pti_total_system;
|
||||||
|
p.cpu_c = (double)p.cpu_t / max(1.0, (uptime * Shared::clkTck) - p.cpu_s);
|
||||||
|
p.mem = pti.pti_resident_size;
|
||||||
}
|
}
|
||||||
struct passwd *pwd = getpwuid(kproc.kp_eproc.e_ucred.cr_uid);
|
struct passwd *pwd = getpwuid(kproc.kp_eproc.e_ucred.cr_uid);
|
||||||
p.user = pwd->pw_name;
|
p.user = pwd->pw_name;
|
||||||
@ -960,6 +974,14 @@ namespace Proc {
|
|||||||
find_old = current_procs.end() - 1;
|
find_old = current_procs.end() - 1;
|
||||||
no_cache = true;
|
no_cache = true;
|
||||||
}
|
}
|
||||||
|
//? Process cpu usage since last update
|
||||||
|
p.cpu_p = clamp(round(cmult * 1000 * (cpu_t - p.cpu_t) / max((uint64_t)1, cputimes - old_cputimes)) / 10.0, 0.0, 100.0 * Shared::coreCount);
|
||||||
|
|
||||||
|
//? Process cumulative cpu usage since process start
|
||||||
|
p.cpu_c = (double)cpu_t / max(1.0, (uptime * Shared::clkTck) - p.cpu_s);
|
||||||
|
|
||||||
|
//? Update cached value with latest cpu times
|
||||||
|
p.cpu_t = cpu_t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user