mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-29 16:26:39 +01:00
Merge pull request #235 from CarterLi/master
macOS: add battery info support; fix GPU detection; various improvements
This commit is contained in:
@@ -240,8 +240,10 @@ if(APPLE)
|
||||
src/detection/os/os_apple.c
|
||||
src/detection/cpu/cpu_apple.c
|
||||
src/detection/gpu/gpu_apple.c
|
||||
src/detection/battery/battery_apple.c
|
||||
src/detection/memory/memory_apple.c
|
||||
src/detection/displayserver/displayserver_apple.c
|
||||
src/util/apple/cfdict_helpers.c
|
||||
)
|
||||
elseif(ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -249,6 +251,7 @@ elseif(ANDROID)
|
||||
src/detection/os/os_android.c
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/gpu/gpu_android.c
|
||||
src/detection/battery/battery_android.c
|
||||
src/detection/memory/memory_linux.c
|
||||
src/detection/displayserver/displayserver_android.c
|
||||
)
|
||||
@@ -259,6 +262,7 @@ else()
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/gpu/gpu_linux.c
|
||||
src/detection/memory/memory_linux.c
|
||||
src/detection/battery/battery_linux.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/wayland.c
|
||||
src/detection/displayserver/linux/xcb.c
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
--terminal-font-format Raw: {}; Name: {}; Size: {}; Styles: {}; Pretty: {}
|
||||
--cpu-format Name: {}, Vendor: {}, CoresPhysical: {}, CoresLogical: {}, CoresOnline: {}, FrequencyMin: {}, FrequencyMax: {}, Temperature: {}
|
||||
--cpu-usage-format Percentage: {}
|
||||
--gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}
|
||||
--gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}; CoreCount: {}
|
||||
--memory-format Used: {}; Total: {}; Percentage: {}
|
||||
--disk-format Used: {}; Total: {}; Files: {}; Percentage: {}
|
||||
--battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {}
|
||||
|
||||
+1
-1
@@ -19,6 +19,6 @@ bool ffFileExists(const char* fileName, mode_t mode);
|
||||
// Not thread safe!
|
||||
void ffSuppressIO(bool suppress);
|
||||
|
||||
void ffGetTerminalResponse(const char* request, const char* format, ...);
|
||||
FF_C_SCANF(2, 3) void ffGetTerminalResponse(const char* request, const char* format, ...);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat);
|
||||
void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments);
|
||||
void ffPrintFormat(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments);
|
||||
void ffPrintErrorString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, ...);
|
||||
void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...);
|
||||
FF_C_PRINTF(6, 7) void ffPrintErrorString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, ...);
|
||||
FF_C_PRINTF(5, 6) void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...);
|
||||
void ffPrintColor(const FFstrbuf* colorValue);
|
||||
void ffPrintCharTimes(char c, uint32_t times);
|
||||
void ffPrintUserString(const char* str);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_battery_battery
|
||||
#define FF_INCLUDED_detection_battery_battery
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct BatteryResult
|
||||
{
|
||||
FFstrbuf manufacturer;
|
||||
FFstrbuf modelName;
|
||||
FFstrbuf technology;
|
||||
FFstrbuf capacity;
|
||||
FFstrbuf status;
|
||||
} BatteryResult;
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/io.h"
|
||||
#include "battery.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) {
|
||||
FF_UNUSED(instance, results)
|
||||
return "Unimplemented";
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#include "fastfetch.h"
|
||||
#include "battery.h"
|
||||
#include "util/apple/cfdict_helpers.h"
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery");
|
||||
if (matchDict == NULL)
|
||||
return "IOServiceMatching(\"AppleSmartBattery\") failed";
|
||||
|
||||
io_iterator_t iterator;
|
||||
if(IOServiceGetMatchingServices(0, matchDict, &iterator) != kIOReturnSuccess)
|
||||
return "IOServiceGetMatchingServices() failed";
|
||||
|
||||
io_registry_entry_t registryEntry;
|
||||
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||
{
|
||||
CFMutableDictionaryRef properties;
|
||||
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
{
|
||||
IOObjectRelease(registryEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
int intValue;
|
||||
bool boolValue;
|
||||
|
||||
BatteryResult* battery = ffListAdd(results);
|
||||
ffStrbufInit(&battery->capacity);
|
||||
if(ffCfDictGetInt(properties, "CurrentCapacity", &intValue))
|
||||
ffStrbufAppendF(&battery->capacity, "%d", intValue);
|
||||
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffStrbufInit(&battery->technology);
|
||||
if (ffCfDictGetBool(properties, "built-in", &boolValue) && boolValue)
|
||||
{
|
||||
ffStrbufAppendS(&battery->manufacturer, "Apple Inc.");
|
||||
ffStrbufAppendS(&battery->modelName, "Builtin");
|
||||
ffStrbufAppendS(&battery->technology, "Lithium");
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&battery->manufacturer, "Unknown");
|
||||
ffStrbufAppendS(&battery->modelName, "Unknown");
|
||||
ffStrbufAppendS(&battery->technology, "Unknown");
|
||||
}
|
||||
|
||||
ffStrbufInit(&battery->status);
|
||||
if (ffCfDictGetBool(properties, "FullyCharged", &boolValue) && boolValue)
|
||||
ffStrbufAppendS(&battery->status, "Fully charged");
|
||||
else if (ffCfDictGetBool(properties, "IsCharging", &boolValue) && boolValue)
|
||||
ffStrbufAppendS(&battery->status, "Charging");
|
||||
else
|
||||
ffStrbufAppendS(&battery->status, "");
|
||||
|
||||
CFRelease(properties);
|
||||
IOObjectRelease(registryEntry);
|
||||
}
|
||||
|
||||
IOObjectRelease(iterator);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/io.h"
|
||||
#include "battery.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
static void parseBattery(FFstrbuf* dir, FFlist* results)
|
||||
{
|
||||
uint32_t dirLength = dir->length;
|
||||
|
||||
FFstrbuf testBatteryBuffer;
|
||||
ffStrbufInit(&testBatteryBuffer);
|
||||
|
||||
//type must exist and be "Battery"
|
||||
ffStrbufAppendS(dir, "/type");
|
||||
ffReadFileBuffer(dir->chars, &testBatteryBuffer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Battery") != 0)
|
||||
{
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
//scope may not exist or must not be "Device"
|
||||
ffStrbufAppendS(dir, "/scope");
|
||||
ffReadFileBuffer(dir->chars, &testBatteryBuffer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Device") == 0)
|
||||
{
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
BatteryResult* result = ffListAdd(results);
|
||||
|
||||
//capacity must exist and be not empty
|
||||
ffStrbufInit(&result->capacity);
|
||||
ffStrbufAppendS(dir, "/capacity");
|
||||
ffReadFileBuffer(dir->chars, &result->capacity);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(result->capacity.length == 0)
|
||||
{
|
||||
ffStrbufDestroy(&result->capacity);
|
||||
--results->length;
|
||||
return;
|
||||
}
|
||||
|
||||
//At this point, we have a battery. Try to get as much values as possible.
|
||||
|
||||
ffStrbufInit(&result->manufacturer);
|
||||
ffStrbufAppendS(dir, "/manufacturer");
|
||||
ffReadFileBuffer(dir->chars, &result->manufacturer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->modelName);
|
||||
ffStrbufAppendS(dir, "/model_name");
|
||||
ffReadFileBuffer(dir->chars, &result->modelName);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->technology);
|
||||
ffStrbufAppendS(dir, "/technology");
|
||||
ffReadFileBuffer(dir->chars, &result->technology);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->status);
|
||||
ffStrbufAppendS(dir, "/status");
|
||||
ffReadFileBuffer(dir->chars, &result->status);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
}
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) {
|
||||
FFstrbuf baseDir;
|
||||
ffStrbufInitA(&baseDir, 64);
|
||||
if(instance->config.batteryDir.length > 0)
|
||||
{
|
||||
ffStrbufAppend(&baseDir, &instance->config.batteryDir);
|
||||
if (!ffStrbufEndsWithC(&baseDir, '/'))
|
||||
{
|
||||
ffStrbufAppendC(&baseDir, '/');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&baseDir, "/sys/class/power_supply/");
|
||||
}
|
||||
|
||||
uint32_t baseDirLength = baseDir.length;
|
||||
|
||||
DIR* dirp = opendir(baseDir.chars);
|
||||
if(dirp == NULL)
|
||||
{
|
||||
ffStrbufDestroy(&baseDir);
|
||||
return "opendir(batteryDir) == NULL";
|
||||
}
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
ffStrbufAppendS(&baseDir, entry->d_name);
|
||||
parseBattery(&baseDir, results);
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
|
||||
if(results->length == 0) {
|
||||
ffStrbufDestroy(&baseDir);
|
||||
return "batteryDir doesn't contain any battery folder";
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&baseDir);
|
||||
return NULL;
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_GPU_TEMP_UNSET (0/0.0)
|
||||
#define FF_GPU_CORE_COUNT_UNSET -1
|
||||
|
||||
typedef struct FFGPUResult
|
||||
{
|
||||
@@ -13,6 +14,7 @@ typedef struct FFGPUResult
|
||||
FFstrbuf name;
|
||||
FFstrbuf driver;
|
||||
double temperature;
|
||||
int coreCount;
|
||||
} FFGPUResult;
|
||||
|
||||
const FFlist* ffDetectGPU(const FFinstance* instance);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "gpu.h"
|
||||
|
||||
void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(gpus, instance);
|
||||
return "Unimplemented";
|
||||
}
|
||||
|
||||
@@ -1,33 +1,18 @@
|
||||
#include "gpu.h"
|
||||
#include "common/library.h"
|
||||
#include "detection/cpu/cpu.h"
|
||||
#include "util/apple/cfdict_helpers.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
|
||||
void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
const FFCPUResult* cpu = ffDetectCPU();
|
||||
if(ffStrbufStartsWithIgnCaseS(&cpu->name, "Apple M"))
|
||||
{
|
||||
FFGPUResult* gpu = ffListAdd(gpus);
|
||||
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffStrbufAppendS(&gpu->vendor, "Apple");
|
||||
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufAppendS(&gpu->name, cpu->name.chars + 6); //Cut "Apple "
|
||||
|
||||
ffStrbufInitA(&gpu->driver, 0);
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
}
|
||||
|
||||
CFMutableDictionaryRef matchDict = IOServiceMatching("IOPCIDevice");
|
||||
CFMutableDictionaryRef matchDict = IOServiceMatching(kIOAcceleratorClassName);
|
||||
io_iterator_t iterator;
|
||||
if(IOServiceGetMatchingServices(0, matchDict, &iterator) != kIOReturnSuccess)
|
||||
return;
|
||||
return "IOServiceGetMatchingServices() failed";
|
||||
|
||||
io_registry_entry_t registryEntry;
|
||||
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||
@@ -39,25 +24,19 @@ void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
continue;
|
||||
}
|
||||
|
||||
CFStringRef key = CFStringCreateWithCStringNoCopy(NULL, "model", kCFStringEncodingASCII, kCFAllocatorNull);
|
||||
CFStringRef model = CFDictionaryGetValue(properties, key);
|
||||
if(model == NULL || CFGetTypeID(model) != CFDataGetTypeID())
|
||||
{
|
||||
CFRelease(properties);
|
||||
IOObjectRelease(registryEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
FFGPUResult* gpu = ffListAdd(gpus);
|
||||
|
||||
uint32_t modelLength = (uint32_t) CFStringGetLength(model);
|
||||
ffStrbufInitA(&gpu->name, modelLength + 1);
|
||||
CFStringGetCString(model, gpu->name.chars, modelLength + 1, kCFStringEncodingASCII);
|
||||
gpu->name.length = modelLength;
|
||||
gpu->name.chars[gpu->name.length] = '\0';
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffCfDictGetString(properties, "model", &gpu->name);
|
||||
|
||||
if (!ffCfDictGetInt(properties, "gpu-core-count", &gpu->coreCount))
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
|
||||
ffStrbufInitA(&gpu->vendor, 0);
|
||||
ffStrbufInitA(&gpu->driver, 0);
|
||||
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffCfDictGetString(properties, "CFBundleIdentifier", &gpu->driver);
|
||||
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
|
||||
CFRelease(properties);
|
||||
@@ -65,4 +44,5 @@ void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
}
|
||||
|
||||
IOObjectRelease(iterator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -168,24 +168,26 @@ static void pciHandleDevice(FFlist* results, PCIData* pci, struct pci_dev* devic
|
||||
ffStrbufInit(&gpu->driver);
|
||||
pciDetectDriverName(gpu, pci, device);
|
||||
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
pciDetectTemperatur(gpu, device);
|
||||
}
|
||||
|
||||
static void pciDetectGPUs(const FFinstance* instance, FFlist* gpus)
|
||||
static const char* pciDetectGPUs(const FFinstance* instance, FFlist* gpus)
|
||||
{
|
||||
PCIData pci;
|
||||
|
||||
FF_LIBRARY_LOAD(libpci, instance->config.libPCI, , "libpci.so", 4)
|
||||
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_alloc, )
|
||||
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_init, )
|
||||
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_scan_bus, )
|
||||
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_cleanup, )
|
||||
FF_LIBRARY_LOAD(libpci, instance->config.libPCI, "dlopen libpci.so failed", "libpci.so", 4)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_alloc)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_init)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_scan_bus)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_cleanup)
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libpci, pci, pci_read_byte, )
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libpci, pci, pci_read_word, )
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libpci, pci, pci_lookup_name, )
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libpci, pci, pci_get_param, )
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_read_byte)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_read_word)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_lookup_name)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_get_param)
|
||||
|
||||
pci.access = ffpci_alloc();
|
||||
ffpci_init(pci.access);
|
||||
@@ -200,13 +202,14 @@ static void pciDetectGPUs(const FFinstance* instance, FFlist* gpus)
|
||||
|
||||
ffpci_cleanup(pci.access);
|
||||
dlclose(libpci);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
{
|
||||
#ifdef FF_HAVE_LIBPCI
|
||||
pciDetectGPUs(instance, gpus);
|
||||
return pciDetectGPUs(instance, gpus);
|
||||
#endif
|
||||
}
|
||||
|
||||
+3
-2
@@ -274,11 +274,12 @@ static inline void printCommandHelp(const char* command)
|
||||
}
|
||||
else if(strcasecmp(command, "gpu-format") == 0)
|
||||
{
|
||||
constructAndPrintCommandHelpFormat("gpu", "{} {}", 4,
|
||||
constructAndPrintCommandHelpFormat("gpu", "{} {}", 5,
|
||||
"GPU vendor",
|
||||
"GPU name",
|
||||
"GPU driver",
|
||||
"GPU temperature"
|
||||
"GPU temperature",
|
||||
"GPU core count"
|
||||
);
|
||||
}
|
||||
else if(strcasecmp(command, "memory-format") == 0)
|
||||
|
||||
+21
-125
@@ -1,89 +1,10 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/io.h"
|
||||
#include "common/printing.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include "detection/battery/battery.h"
|
||||
|
||||
#define FF_BATTERY_MODULE_NAME "Battery"
|
||||
#define FF_BATTERY_NUM_FORMAT_ARGS 5
|
||||
|
||||
typedef struct BatteryResult
|
||||
{
|
||||
FFstrbuf manufacturer;
|
||||
FFstrbuf modelName;
|
||||
FFstrbuf technology;
|
||||
FFstrbuf capacity;
|
||||
FFstrbuf status;
|
||||
} BatteryResult;
|
||||
|
||||
static void parseBattery(FFstrbuf* dir, FFlist* results)
|
||||
{
|
||||
uint32_t dirLength = dir->length;
|
||||
|
||||
FFstrbuf testBatteryBuffer;
|
||||
ffStrbufInit(&testBatteryBuffer);
|
||||
|
||||
//type must exist and be "Battery"
|
||||
ffStrbufAppendS(dir, "/type");
|
||||
ffReadFileBuffer(dir->chars, &testBatteryBuffer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Battery") != 0)
|
||||
{
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
//scope may not exist or must not be "Device"
|
||||
ffStrbufAppendS(dir, "/scope");
|
||||
ffReadFileBuffer(dir->chars, &testBatteryBuffer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Device") == 0)
|
||||
{
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
BatteryResult* result = ffListAdd(results);
|
||||
|
||||
//capacity must exist and be not empty
|
||||
ffStrbufInit(&result->capacity);
|
||||
ffStrbufAppendS(dir, "/capacity");
|
||||
ffReadFileBuffer(dir->chars, &result->capacity);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(result->capacity.length == 0)
|
||||
{
|
||||
ffStrbufDestroy(&result->capacity);
|
||||
--results->length;
|
||||
return;
|
||||
}
|
||||
|
||||
//At this point, we have a battery. Try to get as much values as possible.
|
||||
|
||||
ffStrbufInit(&result->manufacturer);
|
||||
ffStrbufAppendS(dir, "/manufacturer");
|
||||
ffReadFileBuffer(dir->chars, &result->manufacturer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->modelName);
|
||||
ffStrbufAppendS(dir, "/model_name");
|
||||
ffReadFileBuffer(dir->chars, &result->modelName);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->technology);
|
||||
ffStrbufAppendS(dir, "/technology");
|
||||
ffReadFileBuffer(dir->chars, &result->technology);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->status);
|
||||
ffStrbufAppendS(dir, "/status");
|
||||
ffReadFileBuffer(dir->chars, &result->status);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
}
|
||||
|
||||
static void printBattery(FFinstance* instance, const BatteryResult* result, uint8_t index)
|
||||
{
|
||||
if(instance->config.battery.outputFormat.length == 0)
|
||||
@@ -127,56 +48,31 @@ static void printBattery(FFinstance* instance, const BatteryResult* result, uint
|
||||
|
||||
void ffPrintBattery(FFinstance* instance)
|
||||
{
|
||||
FFstrbuf baseDir;
|
||||
ffStrbufInitA(&baseDir, 64);
|
||||
if(instance->config.batteryDir.length > 0)
|
||||
FFlist results;
|
||||
ffListInitA(&results, sizeof(BatteryResult), 0);
|
||||
|
||||
const char* error = ffDetectBatteryImpl(instance, &results);
|
||||
|
||||
if (error)
|
||||
{
|
||||
ffStrbufAppend(&baseDir, &instance->config.batteryDir);
|
||||
ffStrbufEndsWithC(&baseDir, '/');
|
||||
ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &instance->config.battery, "%s", error);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&baseDir, "/sys/class/power_supply/");
|
||||
for(uint8_t i = 0; i < (uint8_t) results.length; i++)
|
||||
{
|
||||
BatteryResult* result = ffListGet(&results, i);
|
||||
printBattery(instance, result, i);
|
||||
|
||||
ffStrbufDestroy(&result->manufacturer);
|
||||
ffStrbufDestroy(&result->modelName);
|
||||
ffStrbufDestroy(&result->technology);
|
||||
ffStrbufDestroy(&result->capacity);
|
||||
ffStrbufDestroy(&result->status);
|
||||
}
|
||||
if(results.length == 0)
|
||||
ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &instance->config.battery, "No batteries found");
|
||||
}
|
||||
|
||||
uint32_t baseDirLength = baseDir.length;
|
||||
|
||||
DIR* dirp = opendir(baseDir.chars);
|
||||
if(dirp == NULL)
|
||||
{
|
||||
ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &instance->config.battery, "opendir(\"%s\") == NULL", baseDir.chars);
|
||||
ffStrbufDestroy(&baseDir);
|
||||
return;
|
||||
}
|
||||
|
||||
FFlist results;
|
||||
ffListInitA(&results, sizeof(BatteryResult), 4);
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
ffStrbufAppendS(&baseDir, entry->d_name);
|
||||
parseBattery(&baseDir, &results);
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
|
||||
for(uint8_t i = 0; i < (uint8_t) results.length; i++)
|
||||
{
|
||||
BatteryResult* result = ffListGet(&results, i);
|
||||
printBattery(instance, result, i);
|
||||
|
||||
ffStrbufDestroy(&result->manufacturer);
|
||||
ffStrbufDestroy(&result->modelName);
|
||||
ffStrbufDestroy(&result->technology);
|
||||
ffStrbufDestroy(&result->capacity);
|
||||
ffStrbufDestroy(&result->status);
|
||||
}
|
||||
|
||||
if(results.length == 0)
|
||||
ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &instance->config.battery, "%s doesn't contain any battery folder", baseDir.chars);
|
||||
|
||||
ffListDestroy(&results);
|
||||
ffStrbufDestroy(&baseDir);
|
||||
}
|
||||
|
||||
+6
-2
@@ -7,7 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FF_GPU_MODULE_NAME "GPU"
|
||||
#define FF_GPU_NUM_FORMAT_ARGS 4
|
||||
#define FF_GPU_NUM_FORMAT_ARGS 5
|
||||
|
||||
static void printGPUResult(FFinstance* instance, uint8_t index, FFcache* cache, FFGPUResult* gpu)
|
||||
{
|
||||
@@ -22,11 +22,15 @@ static void printGPUResult(FFinstance* instance, uint8_t index, FFcache* cache,
|
||||
|
||||
ffStrbufAppend(&output, &gpu->name);
|
||||
|
||||
if(gpu->coreCount != FF_GPU_CORE_COUNT_UNSET)
|
||||
ffStrbufAppendF(&output, " (%d)", gpu->coreCount);
|
||||
|
||||
ffPrintAndAppendToCache(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu, cache, &output, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->driver},
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, &gpu->temperature}
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, &gpu->temperature},
|
||||
{FF_FORMAT_ARG_TYPE_INT, &gpu->coreCount},
|
||||
});
|
||||
|
||||
ffStrbufDestroy(&output);
|
||||
|
||||
@@ -118,5 +118,5 @@ void ffPrintOpenCL(FFinstance* instance)
|
||||
#endif
|
||||
|
||||
if(error != NULL)
|
||||
ffPrintError(instance, FF_OPENCL_MODULE_NAME, 0, &instance->config.openCL, error);
|
||||
ffPrintError(instance, FF_OPENCL_MODULE_NAME, 0, &instance->config.openCL, "%s", error);
|
||||
}
|
||||
|
||||
@@ -453,5 +453,5 @@ void ffPrintOpenGL(FFinstance* instance)
|
||||
#endif
|
||||
|
||||
if(error != NULL)
|
||||
ffPrintError(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL, error);
|
||||
ffPrintError(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL, "%s", error);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ static void printKonsole(FFinstance* instance)
|
||||
|
||||
if(profile.length == 0)
|
||||
{
|
||||
ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Couldn't find \"DefaultProfile=%[^\\n]\" in \".config/konsolerc\"");
|
||||
ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "%s", "Couldn't find \"DefaultProfile=%[^\\n]\" in \".config/konsolerc\"");
|
||||
ffStrbufDestroy(&profile);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ void ffPrintVulkan(FFinstance* instance)
|
||||
|
||||
if(vulkan->error)
|
||||
{
|
||||
ffPrintError(instance, FF_VULKAN_MODULE_NAME, 0, &instance->config.vulkan, vulkan->error);
|
||||
ffPrintError(instance, FF_VULKAN_MODULE_NAME, 0, &instance->config.vulkan, "%s", vulkan->error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FASTFETCH_INCLUDED_FFCHECKMACROS
|
||||
#define FASTFETCH_INCLUDED_FFCHECKMACROS
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define FF_C_NODISCARD __attribute__((warn_unused_result))
|
||||
#else
|
||||
#define FF_C_NODISCARD
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define FF_C_PRINTF(formatStrIndex, argsStartIndex) __attribute__((__format__ (printf, formatStrIndex, argsStartIndex)))
|
||||
#else
|
||||
#define FF_C_PRINTF(formatStrIndex, argsStartIndex)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define FF_C_SCANF(formatStrIndex, argsStartIndex) __attribute__((__format__ (scanf, formatStrIndex, argsStartIndex)))
|
||||
#else
|
||||
#define FF_C_SCANF(formatStrIndex, argsStartIndex)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+8
-5
@@ -12,7 +12,7 @@ void ffListInitA(FFlist* list, uint32_t elementSize, uint32_t capacity)
|
||||
list->elementSize = elementSize;
|
||||
list->capacity = capacity;
|
||||
list->length = 0;
|
||||
list->data = malloc(list->capacity * list->elementSize);
|
||||
list->data = capacity == 0 ? NULL : malloc((size_t)list->capacity * list->elementSize);
|
||||
}
|
||||
|
||||
void* ffListGet(const FFlist* list, uint32_t index)
|
||||
@@ -24,12 +24,13 @@ void* ffListAdd(FFlist* list)
|
||||
{
|
||||
if(list->length == list->capacity)
|
||||
{
|
||||
list->capacity = list->capacity * 2 * list->elementSize;
|
||||
list->data = realloc(list->data, list->capacity);
|
||||
list->capacity = list->capacity == 0 ? FF_LIST_DEFAULT_ALLOC : list->capacity * 2;
|
||||
// realloc(NULL, newSize) is same as malloc(newSize)
|
||||
list->data = realloc(list->data, (size_t)list->capacity * list->elementSize);
|
||||
}
|
||||
void* adress = list->data + (list->length * list->elementSize);
|
||||
void* address = list->data + (list->length * list->elementSize);
|
||||
++list->length;
|
||||
return adress;
|
||||
return address;
|
||||
}
|
||||
|
||||
uint32_t ffListFirstIndexComp(const FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*))
|
||||
@@ -45,5 +46,7 @@ uint32_t ffListFirstIndexComp(const FFlist* list, void* compElement, bool(*compF
|
||||
|
||||
void ffListDestroy(FFlist* list)
|
||||
{
|
||||
list->length = list->capacity = 0;
|
||||
free(list->data);
|
||||
list->data = NULL;
|
||||
}
|
||||
|
||||
+4
-2
@@ -3,6 +3,8 @@
|
||||
#ifndef FF_INCLUDED_FFLIST
|
||||
#define FF_INCLUDED_FFLIST
|
||||
|
||||
#include "FFcheckmacros.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -19,11 +21,11 @@ typedef struct FFlist
|
||||
void ffListInit(FFlist* list, uint32_t elementSize);
|
||||
void ffListInitA(FFlist* list, uint32_t elementSize, uint32_t capacity);
|
||||
|
||||
void* ffListGet(const FFlist* list, uint32_t index);
|
||||
FF_C_NODISCARD void* ffListGet(const FFlist* list, uint32_t index);
|
||||
|
||||
void* ffListAdd(FFlist* list);
|
||||
|
||||
uint32_t ffListFirstIndexComp(const FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*));
|
||||
FF_C_NODISCARD uint32_t ffListFirstIndexComp(const FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*));
|
||||
|
||||
void ffListDestroy(FFlist* list);
|
||||
|
||||
|
||||
+18
-16
@@ -3,6 +3,8 @@
|
||||
#ifndef FASTFETCH_INCLUDED_FFSTRBUF
|
||||
#define FASTFETCH_INCLUDED_FFSTRBUF
|
||||
|
||||
#include "FFcheckmacros.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
@@ -25,7 +27,7 @@ void ffStrbufInitCopy(FFstrbuf* strbuf, const FFstrbuf* src);
|
||||
|
||||
void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free);
|
||||
|
||||
uint32_t ffStrbufGetFree(const FFstrbuf* strbuf);
|
||||
FF_C_NODISCARD uint32_t ffStrbufGetFree(const FFstrbuf* strbuf);
|
||||
|
||||
void ffStrbufClear(FFstrbuf* strbuf);
|
||||
|
||||
@@ -37,7 +39,7 @@ void ffStrbufAppendS(FFstrbuf* strbuf, const char* value);
|
||||
void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value);
|
||||
void ffStrbufAppendNSExludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude);
|
||||
void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int(*transformFunc)(int));
|
||||
void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...);
|
||||
FF_C_PRINTF(2, 3) void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...);
|
||||
void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments);
|
||||
|
||||
void ffStrbufPrependS(FFstrbuf* strbuf, const char* value);
|
||||
@@ -46,11 +48,11 @@ void ffStrbufPrependNS(FFstrbuf* strbuf, uint32_t length, const char* value);
|
||||
void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value);
|
||||
void ffStrbufSetS(FFstrbuf* strbuf, const char* value);
|
||||
|
||||
int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp);
|
||||
int ffStrbufCompS(const FFstrbuf* strbuf, const char* comp);
|
||||
FF_C_NODISCARD int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp);
|
||||
FF_C_NODISCARD int ffStrbufCompS(const FFstrbuf* strbuf, const char* comp);
|
||||
|
||||
int ffStrbufIgnCaseComp(const FFstrbuf* strbuf, const FFstrbuf* comp);
|
||||
int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, const char* comp);
|
||||
FF_C_NODISCARD int ffStrbufIgnCaseComp(const FFstrbuf* strbuf, const FFstrbuf* comp);
|
||||
FF_C_NODISCARD int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, const char* comp);
|
||||
|
||||
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c);
|
||||
void ffStrbufTrimRight(FFstrbuf* strbuf, char c);
|
||||
@@ -62,16 +64,16 @@ void ffStrbufRemoveStringsA(FFstrbuf* strbuf, uint32_t numStrings, const char* s
|
||||
void ffStrbufRemoveStringsV(FFstrbuf* strbuf, uint32_t numStrings, va_list arguments);
|
||||
void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, ...);
|
||||
|
||||
uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c);
|
||||
uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str);
|
||||
FF_C_NODISCARD uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c);
|
||||
FF_C_NODISCARD uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str);
|
||||
|
||||
uint32_t ffStrbufFirstIndexC(const FFstrbuf* strbuf, char c);
|
||||
uint32_t ffStrbufFirstIndex(const FFstrbuf* strbuf, const FFstrbuf* searched);
|
||||
uint32_t ffStrbufFirstIndexS(const FFstrbuf* strbuf, const char* str);
|
||||
FF_C_NODISCARD uint32_t ffStrbufFirstIndexC(const FFstrbuf* strbuf, char c);
|
||||
FF_C_NODISCARD uint32_t ffStrbufFirstIndex(const FFstrbuf* strbuf, const FFstrbuf* searched);
|
||||
FF_C_NODISCARD uint32_t ffStrbufFirstIndexS(const FFstrbuf* strbuf, const char* str);
|
||||
|
||||
uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c);
|
||||
FF_C_NODISCARD uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c);
|
||||
|
||||
uint32_t ffStrbufLastIndexC(const FFstrbuf* strbuf, char c);
|
||||
FF_C_NODISCARD uint32_t ffStrbufLastIndexC(const FFstrbuf* strbuf, char c);
|
||||
|
||||
void ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index);
|
||||
void ffStrbufSubstrBeforeFirstC(FFstrbuf* strbuf, char c);
|
||||
@@ -89,7 +91,7 @@ bool ffStrbufStartsWithIgnCaseS(const FFstrbuf* strbuf, const char* start);
|
||||
bool ffStrbufEndsWithC(const FFstrbuf* strbuf, char c);
|
||||
bool ffStrbufEndsWithS(const FFstrbuf* strbuf, const char* end);
|
||||
|
||||
uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c);
|
||||
FF_C_NODISCARD uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c);
|
||||
|
||||
bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end);
|
||||
|
||||
@@ -98,8 +100,8 @@ void ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c);
|
||||
void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file);
|
||||
void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file);
|
||||
|
||||
double ffStrbufToDouble(const FFstrbuf* strbuf);
|
||||
uint16_t ffStrbufToUInt16(const FFstrbuf* strbuf, uint16_t defaultValue);
|
||||
FF_C_NODISCARD double ffStrbufToDouble(const FFstrbuf* strbuf);
|
||||
FF_C_NODISCARD uint16_t ffStrbufToUInt16(const FFstrbuf* strbuf, uint16_t defaultValue);
|
||||
|
||||
void ffStrbufDestroy(FFstrbuf* strbuf);
|
||||
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
#ifndef FASTFETCH_INCLUDED_FFVALUESTORE
|
||||
#define FASTFETCH_INCLUDED_FFVALUESTORE
|
||||
|
||||
#include "util/FFlist.h"
|
||||
#include "FFlist.h"
|
||||
#include "FFcheckmacros.h"
|
||||
|
||||
typedef FFlist FFvaluestore;
|
||||
|
||||
void ffValuestoreInit(FFvaluestore* vs, uint32_t valueSize);
|
||||
void* ffValuestoreGet(FFvaluestore* vs, const char* key);
|
||||
FF_C_NODISCARD void* ffValuestoreGet(FFvaluestore* vs, const char* key);
|
||||
void* ffValuestoreSet(FFvaluestore* vs, const char* key, bool* created); //created may be NULL
|
||||
void ffValuestoreDestroy(FFvaluestore* vs);
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "cfdict_helpers.h"
|
||||
|
||||
const void* ffCfDictGetValue(CFMutableDictionaryRef dict, const char* key)
|
||||
{
|
||||
CFStringRef cfKey = CFStringCreateWithCStringNoCopy(NULL, key, kCFStringEncodingASCII, kCFAllocatorNull);
|
||||
return CFDictionaryGetValue(dict, cfKey);
|
||||
}
|
||||
|
||||
bool ffCfDictGetString(CFMutableDictionaryRef dict, const char* key, FFstrbuf* result)
|
||||
{
|
||||
CFStringRef cf = (CFStringRef)ffCfDictGetValue(dict, key);
|
||||
if(cf == NULL || CFGetTypeID(cf) != CFStringGetTypeID())
|
||||
return false;
|
||||
|
||||
uint32_t length = (uint32_t)CFStringGetLength(cf);
|
||||
ffStrbufEnsureFree(result, length + 1);
|
||||
if(CFStringGetCString(cf, result->chars, length + 1, kCFStringEncodingASCII))
|
||||
{
|
||||
result->length = length;
|
||||
// CFStringGetCString ensures the buffer is NUL terminated
|
||||
// https://developer.apple.com/documentation/corefoundation/1542721-cfstringgetcstring
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffCfDictGetBool(CFMutableDictionaryRef dict, const char* key, bool* result)
|
||||
{
|
||||
CFBooleanRef cf = (CFBooleanRef)ffCfDictGetValue(dict, key);
|
||||
if(cf == NULL || CFGetTypeID(cf) != CFNumberGetTypeID())
|
||||
return false;
|
||||
|
||||
*result = CFBooleanGetValue(cf);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffCfDictGetInt(CFMutableDictionaryRef dict, const char* key, int* result)
|
||||
{
|
||||
CFNumberRef cf = (CFNumberRef)ffCfDictGetValue(dict, key);
|
||||
if (cf == NULL || CFGetTypeID(cf) != CFStringGetTypeID())
|
||||
return false;
|
||||
|
||||
if(!CFNumberGetValue(cf, kCFNumberSInt32Type, result))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FASTFETCH_INCLUDED_cfdict_helpers
|
||||
#define FASTFETCH_INCLUDED_cfdict_helpers
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
const void* ffCfDictGetValue(CFMutableDictionaryRef dict, const char* str);
|
||||
bool ffCfDictGetString(CFMutableDictionaryRef dict, const char* key, FFstrbuf* result);
|
||||
bool ffCfDictGetBool(CFMutableDictionaryRef dict, const char* key, bool* result);
|
||||
bool ffCfDictGetInt(CFMutableDictionaryRef dict, const char* key, int* result);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user