Skip to content

Commit 413d126

Browse files
committed
Battery: add dirty support for macOS
1 parent 9eeb216 commit 413d126

File tree

4 files changed

+124
-3
lines changed

4 files changed

+124
-3
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ if(APPLE)
243243
src/detection/battery/battery_apple.c
244244
src/detection/memory/memory_apple.c
245245
src/detection/displayserver/displayserver_apple.c
246+
src/util/apple/cfdict_helpers.c
246247
)
247248
elseif(ANDROID)
248249
list(APPEND LIBFASTFETCH_SRC
Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,68 @@
11
#include "fastfetch.h"
22
#include "battery.h"
3+
#include "util/apple/cfdict_helpers.h"
34

4-
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) {
5-
FF_UNUSED(instance, results);
6-
return "Unimplemented";
5+
#include <IOKit/IOKitLib.h>
6+
7+
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
8+
{
9+
FF_UNUSED(instance);
10+
11+
CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery");
12+
if (matchDict == NULL)
13+
return "IOServiceMatching(\"AppleSmartBattery\") failed";
14+
15+
io_iterator_t iterator;
16+
if(IOServiceGetMatchingServices(0, matchDict, &iterator) != kIOReturnSuccess)
17+
return "IOServiceGetMatchingServices() failed";
18+
19+
io_registry_entry_t registryEntry;
20+
while((registryEntry = IOIteratorNext(iterator)) != 0)
21+
{
22+
CFMutableDictionaryRef properties;
23+
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
24+
{
25+
IOObjectRelease(registryEntry);
26+
continue;
27+
}
28+
29+
int intValue;
30+
bool boolValue;
31+
32+
BatteryResult* battery = ffListAdd(results);
33+
ffStrbufInit(&battery->capacity);
34+
if(ffCfDictGetInt(properties, "CurrentCapacity", &intValue))
35+
ffStrbufAppendF(&battery->capacity, "%d", intValue);
36+
37+
ffStrbufInit(&battery->manufacturer);
38+
ffStrbufInit(&battery->modelName);
39+
ffStrbufInit(&battery->technology);
40+
if (ffCfDictGetBool(properties, "built-in", &boolValue) && boolValue)
41+
{
42+
ffStrbufAppendS(&battery->manufacturer, "Apple Inc.");
43+
ffStrbufAppendS(&battery->modelName, "Builtin");
44+
ffStrbufAppendS(&battery->technology, "Lithium");
45+
}
46+
else
47+
{
48+
ffStrbufAppendS(&battery->manufacturer, "Unknown");
49+
ffStrbufAppendS(&battery->modelName, "Unknown");
50+
ffStrbufAppendS(&battery->technology, "Unknown");
51+
}
52+
53+
ffStrbufInit(&battery->status);
54+
if (ffCfDictGetBool(properties, "FullyCharged", &boolValue) && boolValue)
55+
ffStrbufAppendS(&battery->status, "Fully charged");
56+
else if (ffCfDictGetBool(properties, "IsCharging", &boolValue) && boolValue)
57+
ffStrbufAppendS(&battery->status, "Charging");
58+
else
59+
ffStrbufAppendS(&battery->status, "");
60+
61+
CFRelease(properties);
62+
IOObjectRelease(registryEntry);
63+
}
64+
65+
IOObjectRelease(iterator);
66+
67+
return NULL;
768
}

src/util/apple/cfdict_helpers.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "cfdict_helpers.h"
2+
3+
const void* ffCfDictGetValue(CFMutableDictionaryRef dict, const char* key)
4+
{
5+
CFStringRef cfKey = CFStringCreateWithCStringNoCopy(NULL, key, kCFStringEncodingASCII, kCFAllocatorNull);
6+
return CFDictionaryGetValue(dict, cfKey);
7+
}
8+
9+
bool ffCfDictGetString(CFMutableDictionaryRef dict, const char* key, FFstrbuf* result)
10+
{
11+
CFStringRef cf = (CFStringRef)ffCfDictGetValue(dict, key);
12+
if(cf == NULL || CFGetTypeID(cf) != CFStringGetTypeID())
13+
return false;
14+
15+
uint32_t length = (uint32_t)CFStringGetLength(cf);
16+
ffStrbufEnsureFree(result, length + 1);
17+
if(CFStringGetCString(cf, result->chars, length + 1, kCFStringEncodingASCII))
18+
{
19+
result->length = length;
20+
// CFStringGetCString ensures the buffer is NUL terminated
21+
// https://developer.apple.com/documentation/corefoundation/1542721-cfstringgetcstring
22+
}
23+
return true;
24+
}
25+
26+
bool ffCfDictGetBool(CFMutableDictionaryRef dict, const char* key, bool* result)
27+
{
28+
CFBooleanRef cf = (CFBooleanRef)ffCfDictGetValue(dict, key);
29+
if(cf == NULL || CFGetTypeID(cf) != CFNumberGetTypeID())
30+
return false;
31+
32+
*result = CFBooleanGetValue(cf);
33+
return true;
34+
}
35+
36+
bool ffCfDictGetInt(CFMutableDictionaryRef dict, const char* key, int* result)
37+
{
38+
CFNumberRef cf = (CFNumberRef)ffCfDictGetValue(dict, key);
39+
if (cf == NULL || CFGetTypeID(cf) != CFStringGetTypeID())
40+
return false;
41+
42+
if(!CFNumberGetValue(cf, kCFNumberSInt32Type, result))
43+
return false;
44+
return true;
45+
}

src/util/apple/cfdict_helpers.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
#ifndef FASTFETCH_INCLUDED_cfdict_helpers
4+
#define FASTFETCH_INCLUDED_cfdict_helpers
5+
6+
#include "fastfetch.h"
7+
#include <CoreFoundation/CoreFoundation.h>
8+
9+
const void* ffCfDictGetValue(CFMutableDictionaryRef dict, const char* str);
10+
bool ffCfDictGetString(CFMutableDictionaryRef dict, const char* key, FFstrbuf* result);
11+
bool ffCfDictGetBool(CFMutableDictionaryRef dict, const char* key, bool* result);
12+
bool ffCfDictGetInt(CFMutableDictionaryRef dict, const char* key, int* result);
13+
14+
#endif

0 commit comments

Comments
 (0)