1- #include "fastfetch.h"
21#include "battery.h"
32#include "common/io/io.h"
3+ #include "util/FFstrbuf.h"
4+ #include "util/stringUtils.h"
45
6+ #include <prop/prop_array.h>
7+ #include <prop/prop_bool.h>
8+ #include <prop/prop_dictionary.h>
9+ #include <prop/prop_object.h>
510#include <sys/envsys.h>
611#include <prop/proplib.h>
712#include <paths.h>
813#include <time.h>
914#include <unistd.h>
1015#include <fcntl.h>
1116
12- const char * ffDetectBattery (FFBatteryOptions * options , FFlist * results )
17+ const char * ffDetectBattery (FF_MAYBE_UNUSED FFBatteryOptions * options , FFlist * results )
1318{
1419 FF_AUTO_CLOSE_FD int fd = open (_PATH_SYSMON , O_RDONLY );
1520 if (fd < 0 ) return "open(_PATH_SYSMON, O_RDONLY) failed" ;
@@ -18,25 +23,85 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
1823 if (prop_dictionary_recv_ioctl (fd , ENVSYS_GETDICTIONARY , & root ) < 0 )
1924 return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed" ;
2025
21- prop_array_t array = prop_dictionary_get (root , "acpiacad0" );
22- if (!array )
23- return "No key `acpibat0` in root dictionary" ;
26+ bool acConnected = false;
27+ {
28+ prop_array_t acad = prop_dictionary_get (root , "acpiacad0" );
29+ if (acad )
30+ {
31+ prop_dictionary_t dict = prop_array_get (acad , 0 );
32+ prop_dictionary_get_uint8 (dict , "cur-value" , (uint8_t * ) & acConnected );
33+ }
34+ }
2435
25- if (prop_array_count (array ) != 2 )
26- return "Unexpect `acpibat0` data" ;
36+ prop_object_iterator_t itKey = prop_dictionary_iterator (root );
37+ for (prop_dictionary_keysym_t key ; (key = prop_object_iterator_next (itKey )) != NULL ; )
38+ {
39+ if (!ffStrStartsWith (prop_dictionary_keysym_value (key ), "acpibat" )) continue ;
2740
28- prop_dictionary_t dict = prop_array_get (array , 0 );
29- if (prop_object_type (dict ) != PROP_TYPE_DICTIONARY )
30- return "Unexpect `acpibat0[0]`" ;
41+ prop_array_t bat = prop_dictionary_get_keysym (root , key );
42+ uint32_t max = 0 , curr = 0 , dischargeRate = 0 ;
43+ bool charging = false, critical = false;
44+ prop_object_iterator_t iter = prop_array_iterator (bat );
45+ for (prop_dictionary_t dict ; (dict = prop_object_iterator_next (iter )) != NULL ;)
46+ {
47+ if (prop_object_type (dict ) != PROP_TYPE_DICTIONARY )
48+ continue ;
49+
50+ const char * desc = NULL ;
51+ if (!prop_dictionary_get_string (dict , "description" , & desc ))
52+ continue ;
3153
32- //prop_array_t keys = prop_dictionary_all_keys(dict);
33- //for (uint32_t i = 0; i < prop_array_count(keys); ++i)
34- // puts(prop_dictionary_keysym_value(prop_array_get(keys, i)));
54+ if (ffStrEquals (desc , "present" ))
55+ {
56+ int value = 0 ;
57+ if (prop_dictionary_get_int (dict , "cur-value" , & value ) && value == 0 )
58+ continue ;
59+ }
60+ else if (ffStrEquals (desc , "charging" ))
61+ {
62+ prop_dictionary_get_uint8 (dict , "cur-value" , (uint8_t * ) & charging );
63+ }
64+ else if (ffStrEquals (desc , "charge" ))
65+ {
66+ prop_dictionary_get_uint32 (dict , "max-value" , & max );
67+ prop_dictionary_get_uint32 (dict , "cur-value" , & curr );
68+ const char * state = NULL ;
69+ if (prop_dictionary_get_string (dict , "state" , & state ) && ffStrEquals (state , "critical" ))
70+ critical = true;
71+ }
72+ else if (ffStrEquals (desc , "discharge rate" ))
73+ {
74+ prop_dictionary_get_uint (dict , "cur-value" , & dischargeRate );
75+ }
76+ }
3577
36- int acConnected = false;
37- prop_dictionary_get_int (dict , "cur-value" , & acConnected );
78+ if (max > 0 )
79+ {
80+ FFBatteryResult * battery = ffListAdd (results );
81+ battery -> temperature = FF_BATTERY_TEMP_UNSET ;
82+ battery -> cycleCount = 0 ;
83+ ffStrbufInit (& battery -> manufacturer );
84+ ffStrbufInit (& battery -> modelName );
85+ ffStrbufInit (& battery -> status );
86+ ffStrbufInit (& battery -> technology );
87+ ffStrbufInit (& battery -> serial );
88+ ffStrbufInit (& battery -> manufactureDate );
89+ battery -> timeRemaining = -1 ;
3890
39- // TODO: actually use acpibat0
40-
41- return acConnected ? "AC Connected" : "Discharging" ;
91+ battery -> capacity = (double ) curr / max ;
92+ if (charging )
93+ ffStrbufAppendS (& battery -> status , "Charging, " );
94+ else if (dischargeRate )
95+ ffStrbufAppendS (& battery -> status , "Discharging, " );
96+ if (critical )
97+ ffStrbufAppendS (& battery -> status , "Critical, " );
98+ if (acConnected )
99+ ffStrbufAppendS (& battery -> status , "AC Connected" );
100+ ffStrbufTrimRight (& battery -> status , ' ' );
101+ ffStrbufTrimRight (& battery -> status , ',' );
102+ }
103+ }
104+ prop_object_iterator_release (itKey );
105+
106+ return NULL ;
42107}
0 commit comments