Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -240,15 +240,18 @@ 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
src/detection/host/host_android.c
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
)
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion presets/verbose
Original file line number Diff line number Diff line change
Expand Up @@ -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: {}
Expand Down
2 changes: 1 addition & 1 deletion src/common/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 2 additions & 2 deletions src/common/printing.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
19 changes: 19 additions & 0 deletions src/detection/battery/battery.h
Original file line number Diff line number Diff line change
@@ -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
10 changes: 10 additions & 0 deletions src/detection/battery/battery_android.c
Original file line number Diff line number Diff line change
@@ -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";
}
68 changes: 68 additions & 0 deletions src/detection/battery/battery_apple.c
Original file line number Diff line number Diff line change
@@ -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;
}
117 changes: 117 additions & 0 deletions src/detection/battery/battery_linux.c
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 2 additions & 0 deletions src/detection/gpu/gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
#include "fastfetch.h"

#define FF_GPU_TEMP_UNSET (0/0.0)
#define FF_GPU_CORE_COUNT_UNSET -1

typedef struct FFGPUResult
{
FFstrbuf vendor;
FFstrbuf name;
FFstrbuf driver;
double temperature;
int coreCount;
} FFGPUResult;

const FFlist* ffDetectGPU(const FFinstance* instance);
Expand Down
3 changes: 2 additions & 1 deletion src/detection/gpu/gpu_android.c
Original file line number Diff line number Diff line change
@@ -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";
}
48 changes: 14 additions & 34 deletions src/detection/gpu/gpu_apple.c
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -39,30 +24,25 @@ 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);
IOObjectRelease(registryEntry);
}

IOObjectRelease(iterator);
return NULL;
}
Loading