From 3ad5d5c8b0274ea44eaca544922bf30f1e493f96 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 26 Jan 2025 14:10:24 +0800 Subject: [PATCH 01/44] Sound (FreeBSD): report OSS ABI version --- src/detection/sound/sound_bsd.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/detection/sound/sound_bsd.c b/src/detection/sound/sound_bsd.c index fcc2730a..5fccf896 100644 --- a/src/detection/sound/sound_bsd.c +++ b/src/detection/sound/sound_bsd.c @@ -13,12 +13,20 @@ const char* ffDetectSound(FFlist* devices) if (defaultDev == -1) return "sysctl(hw.snd.default_unit) failed"; - for (int idev = 0; idev <= 9; ++idev) + struct oss_sysinfo info = { .nummixers = 9 }; + + for (int idev = 0; idev <= info.nummixers; ++idev) { path[strlen("/dev/mixer")] = (char) ('0' + idev); FF_AUTO_CLOSE_FD int fd = open(path, O_RDWR); if (fd < 0) break; + if (idev == 0) + { + if (ioctl(fd, SNDCTL_SYSINFO, &info) != 0) + return "ioctl(SNDCTL_SYSINFO) failed"; + } + uint32_t devmask = 0; if (ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devmask) < 0) continue; @@ -40,7 +48,7 @@ const char* ffDetectSound(FFlist* devices) ffStrbufInitS(&device->identifier, path); ffStrbufInitF(&device->name, "%s %s", ci.longname, ci.hw_info); ffStrbufTrimRightSpace(&device->name); - ffStrbufInitStatic(&device->platformApi, "OSS"); + ffStrbufInitF(&device->platformApi, "%s %s", info.product, info.version); device->volume = mutemask & SOUND_MASK_VOLUME ? 0 : ((uint8_t) volume /*left*/ + (uint8_t) (volume >> 8) /*right*/) / 2; From 1c4953a467bb9ba84011eb5f57f66281b52a80d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 26 Jan 2025 21:03:27 +0800 Subject: [PATCH 02/44] Sound (NetBSD): use OSS instead of pulseaudio Fix #1527 --- CMakeLists.txt | 5 +++-- src/detection/sound/sound_bsd.c | 30 ++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 785b340f..14b7f3c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,7 @@ cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD O cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF) cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS" OFF) cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) -cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR OpenBSD OR NetBSD OR SunOS" OFF) +cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR OpenBSD OR SunOS" OFF) cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF) cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF) cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly" OFF) @@ -761,7 +761,7 @@ elseif(NetBSD) src/detection/poweradapter/poweradapter_nosupport.c src/detection/processes/processes_nbsd.c src/detection/gtk_qt/qt.c - src/detection/sound/sound_linux.c + src/detection/sound/sound_bsd.c src/detection/swap/swap_obsd.c src/detection/terminalfont/terminalfont_linux.c src/detection/terminalshell/terminalshell_linux.c @@ -1509,6 +1509,7 @@ elseif(NetBSD) target_link_libraries(libfastfetch PRIVATE "m" PRIVATE "prop" + PRIVATE "ossaudio" ) elseif(SunOS) target_link_libraries(libfastfetch diff --git a/src/detection/sound/sound_bsd.c b/src/detection/sound/sound_bsd.c index 5fccf896..b3b813b2 100644 --- a/src/detection/sound/sound_bsd.c +++ b/src/detection/sound/sound_bsd.c @@ -4,14 +4,27 @@ #include #include +#include const char* ffDetectSound(FFlist* devices) { - char path[] = "/dev/mixer0"; + #ifndef __NetBSD__ int defaultDev = ffSysctlGetInt("hw.snd.default_unit", -1); - if (defaultDev == -1) return "sysctl(hw.snd.default_unit) failed"; + #else + int defaultDev; + { + char mixerp[8]; + if (readlink("/dev/mixer", mixerp, ARRAY_SIZE(mixerp)) != 6) + return "readlink(/dev/mixer) failed"; + defaultDev = mixerp[5] - '0'; + if (defaultDev < 0 || defaultDev > 9) + return "Invalid mixer device"; + } + #endif + + char path[] = "/dev/mixer0"; struct oss_sysinfo info = { .nummixers = 9 }; @@ -33,8 +46,11 @@ const char* ffDetectSound(FFlist* devices) if (!(devmask & SOUND_MASK_VOLUME)) continue; + #if defined(SOUND_MIXER_MUTE) && (SOUND_MIXER_MUTE != SOUND_MIXER_NONE) + #define FF_SOUND_HAVE_MIXER_MUTE 1 uint32_t mutemask = 0; - ioctl(fd, SOUND_MIXER_READ_MUTE, &mutemask); // doesn't seem to be available on DragonFly + ioctl(fd, SOUND_MIXER_READ_MUTE, &mutemask); + #endif struct oss_card_info ci = { .card = idev }; if (ioctl(fd, SNDCTL_CARDINFO, &ci) < 0) @@ -49,9 +65,11 @@ const char* ffDetectSound(FFlist* devices) ffStrbufInitF(&device->name, "%s %s", ci.longname, ci.hw_info); ffStrbufTrimRightSpace(&device->name); ffStrbufInitF(&device->platformApi, "%s %s", info.product, info.version); - device->volume = mutemask & SOUND_MASK_VOLUME - ? 0 - : ((uint8_t) volume /*left*/ + (uint8_t) (volume >> 8) /*right*/) / 2; + device->volume = + #ifdef FF_SOUND_HAVE_MIXER_MUTE + mutemask & SOUND_MASK_VOLUME ? 0 : + #endif + ((uint8_t) volume /*left*/ + (uint8_t) (volume >> 8) /*right*/) / 2; device->active = true; device->main = defaultDev == idev; } From 4e9fecc767104a1f3cbc462d877028be2fa22dc3 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 26 Jan 2025 23:17:30 +0800 Subject: [PATCH 03/44] Sound (NetBSD): don't assume readlink reports file name only --- src/detection/sound/sound_bsd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/detection/sound/sound_bsd.c b/src/detection/sound/sound_bsd.c index b3b813b2..fd6236cf 100644 --- a/src/detection/sound/sound_bsd.c +++ b/src/detection/sound/sound_bsd.c @@ -15,10 +15,11 @@ const char* ffDetectSound(FFlist* devices) #else int defaultDev; { - char mixerp[8]; - if (readlink("/dev/mixer", mixerp, ARRAY_SIZE(mixerp)) != 6) + char mixerp[12]; + ssize_t plen = readlink("/dev/mixer", mixerp, ARRAY_SIZE(mixerp)); + if (plen < 6) return "readlink(/dev/mixer) failed"; - defaultDev = mixerp[5] - '0'; + defaultDev = mixerp[plen - 1] - '0'; if (defaultDev < 0 || defaultDev > 9) return "Invalid mixer device"; } From 1279bbcf281857634d14bd1f227ed53e4364419e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 27 Jan 2025 13:06:08 +0800 Subject: [PATCH 04/44] CPU (Linux): rework cpuinfo parsing --- src/detection/cpu/cpu_linux.c | 203 ++++++++++++++++++++-------------- 1 file changed, 123 insertions(+), 80 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 1df2ef57..6e561c63 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -283,11 +283,7 @@ static const char* parseCpuInfo( while(ffStrbufGetline(&line, &len, cpuinfo)) { //Stop after reasonable information is acquired - if((*line == '\0' || *line == '\n') - #if __arm__ || __aarch64__ || __loongarch__ - && cpu->name.length > 0 // #1202 #1204 - #endif - ) + if((*line == '\0' || *line == '\n') && cpu->name.length > 0) { ffStrbufGetlineRestore(&line, &len, cpuinfo); break; @@ -296,28 +292,37 @@ static const char* parseCpuInfo( (void)( // arm64 doesn't have "model name"; arm32 does have "model name" but its value is not useful. // "Hardware" should always be used in this case - #if !(__arm__ || __aarch64__) + #if __x86_64__ || __i386__ (cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) || (cpu->vendor.length == 0 && ffParsePropLine(line, "vendor_id :", &cpu->vendor)) || (physicalCoresBuffer->length == 0 && ffParsePropLine(line, "cpu cores :", physicalCoresBuffer)) || (cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz :", cpuMHz)) || #endif - #if !(__x86_64__ || __i386__ || __arm__ || __aarch64__) - (cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) || - (cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) || - #endif - #if __arm__ || __aarch64__ (cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) || (cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices #endif + #if __powerpc__ || __powerpc + (cpuMHz->length == 0 && ffParsePropLine(line, "clock :", &cpuMHz)) || //For POWER (cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER #endif - #if __mips__ + + #if __mips__ || __mips (cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || //For MIPS #endif + + #if __loongarch__ + (cpu->name.length == 0 && ffParsePropLine(line, "Model Name :", &cpu->name)) || + (cpuMHz->length == 0 && ffParsePropLine(line, "CPU MHz :", cpuMHz)) || + #endif + + #if __riscv__ || __loongarch__ + (cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) || + (cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) || + #endif + false ); } @@ -414,6 +419,59 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options) return true; } +#if __i386__ || __x86_64__ + +FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo) +{ + const char* p = cpuinfo->chars; + uint64_t low = 0, high = 0; + + while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), "\nphysical id\t:", strlen("\nphysical id\t:")))) + { + if (!p) break; + p += strlen("\nphysical id\t:"); + char* pend; + unsigned long id = strtoul(p, &pend, 10); + if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist? + high |= 1 << (id - 64); + else + low |= 1 << id; + p = pend; + } + + return (uint16_t) (__builtin_popcountll(low) + __builtin_popcountll(high)); +} + +FF_MAYBE_UNUSED static const char* detectCPUX86(const FFCPUOptions* options, FFCPUResult* cpu) +{ + FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ); + if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0) + return "ffReadFileBuffer(\"/proc/cpuinfo\") failed"; + + FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate(); + const char* error = parseCpuInfo(&cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, NULL,NULL, NULL); + if (error) return error; + + cpu->coresLogical = (uint16_t) get_nprocs_conf(); + cpu->coresOnline = (uint16_t) get_nprocs(); + cpu->packages = getPackageCount(&cpuinfo); + cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, 0); // physical cores in single package + if (cpu->coresPhysical == 0) + cpu->coresPhysical = cpu->coresLogical; + else if (cpu->packages > 1) + cpu->coresPhysical *= cpu->packages; + + // Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252 + ffCPUDetectSpeedByCpuid(cpu); + if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0) + cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0); + + return NULL; +} + +#else + FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa) { // Always use the last part of the ISA string. Ref: #590 #1204 @@ -517,89 +575,74 @@ FF_MAYBE_UNUSED static void detectSocName(FFCPUResult* cpu) } } -FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo) +FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, FFCPUResult* cpu) { - const char* p = cpuinfo->chars; - uint64_t low = 0, high = 0; - - while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), "\nphysical id\t:", strlen("\nphysical id\t:")))) - { - if (!p) break; - p += strlen("\nphysical id\t:"); - char* pend; - unsigned long id = strtoul(p, &pend, 10); - if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist? - high |= 1 << (id - 64); - else - low |= 1 << id; - p = pend; - } - - return (uint16_t) (__builtin_popcountll(low) + __builtin_popcountll(high)); -} - -const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) -{ - FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ); - if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0) - return "ffReadFileBuffer(\"/proc/cpuinfo\") failed"; - - cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET; - - FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate(); - FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate(); - FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate(); - FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate(); - FF_STRBUF_AUTO_DESTROY cpuImplementerStr = ffStrbufCreate(); - - const char* error = parseCpuInfo(&cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr); - if (error) return error; - - cpu->coresLogical = (uint16_t) get_nprocs_conf(); + cpu->coresPhysical = cpu->coresLogical = (uint16_t) get_nprocs_conf(); cpu->coresOnline = (uint16_t) get_nprocs(); - cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical); - #if __x86_64__ || __i386__ - cpu->packages = getPackageCount(&cpuinfo); - if (cpu->packages > 1) - cpu->coresPhysical *= cpu->packages; // https://github.com/hykilpikonna/hyfetch/issues/374#issuecomment-2571578914 - #endif - - // Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252 - ffCPUDetectSpeedByCpuid(cpu); - if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0) - cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0); #if __ANDROID__ detectAndroid(cpu); - #elif !(__x86_64__ || __i386__) + #else detectSocName(cpu); #endif - #if __arm__ || __aarch64__ - uint32_t cpuImplementer = (uint32_t) strtoul(cpuImplementerStr.chars, NULL, 16); - ffStrbufSetStatic(&cpu->vendor, hwImplId2Vendor(cpuImplementer)); + detectFrequency(cpu, options); - if (cpu->name.length == 0) - detectArmName(&cpuinfo, cpu, cpuImplementer); - #elif !(__x86_64__ || __i386__) if (cpu->name.length == 0) { - if(cpuUarch.length > 0) - { - if(cpu->name.length > 0) - ffStrbufAppendC(&cpu->name, ' '); - ffStrbufAppend(&cpu->name, &cpuUarch); - } + FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ); + if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0) + return "ffReadFileBuffer(\"/proc/cpuinfo\") failed"; - if(cpuIsa.length > 0) + FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cpuImplementerStr = ffStrbufCreate(); + + const char* error = parseCpuInfo(&cpuinfo, cpu, NULL, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr); + if (error) return error; + + if (cpu->frequencyBase == 0) + cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0); + + #if __arm__ || __aarch64__ + uint32_t cpuImplementer = (uint32_t) strtoul(cpuImplementerStr.chars, NULL, 16); + ffStrbufSetStatic(&cpu->vendor, hwImplId2Vendor(cpuImplementer)); + + if (cpu->name.length == 0) + detectArmName(&cpuinfo, cpu, cpuImplementer); + #elif __riscv__ || __riscv + if (cpu->name.length == 0) { - parseIsa(&cpuIsa); - if(cpu->name.length > 0) - ffStrbufAppendC(&cpu->name, ' '); - ffStrbufAppend(&cpu->name, &cpuIsa); + if(cpuUarch.length > 0) + { + if(cpu->name.length > 0) + ffStrbufAppendC(&cpu->name, ' '); + ffStrbufAppend(&cpu->name, &cpuUarch); + } + + if(cpuIsa.length > 0) + { + parseIsa(&cpuIsa); + if(cpu->name.length > 0) + ffStrbufAppendC(&cpu->name, ' '); + ffStrbufAppend(&cpu->name, &cpuIsa); + } } + #endif } - #endif return NULL; } +#endif + +const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) +{ + cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET; + + #if __x86_64__ || __i386__ + return detectCPUX86(options, cpu); + #else + return detectCPUOthers(options, cpu); + #endif +} From b76e62685e3866a080e867ecfe5c8fa2c3956cb3 Mon Sep 17 00:00:00 2001 From: carterli Date: Mon, 27 Jan 2025 00:30:55 +0800 Subject: [PATCH 05/44] Sound (OpenBSD): Use sndio instead of pulseaudio --- CMakeLists.txt | 3 +- src/detection/sound/sound_obsd.c | 86 ++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/detection/sound/sound_obsd.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 14b7f3c7..c82e70ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -843,7 +843,7 @@ elseif(OpenBSD) src/detection/poweradapter/poweradapter_nosupport.c src/detection/processes/processes_obsd.c src/detection/gtk_qt/qt.c - src/detection/sound/sound_linux.c + src/detection/sound/sound_obsd.c src/detection/swap/swap_obsd.c src/detection/terminalfont/terminalfont_linux.c src/detection/terminalshell/terminalshell_linux.c @@ -1504,6 +1504,7 @@ elseif(OpenBSD) target_link_libraries(libfastfetch PRIVATE "m" PRIVATE "kvm" + PRIVATE "sndio" ) elseif(NetBSD) target_link_libraries(libfastfetch diff --git a/src/detection/sound/sound_obsd.c b/src/detection/sound/sound_obsd.c new file mode 100644 index 00000000..baac25dd --- /dev/null +++ b/src/detection/sound/sound_obsd.c @@ -0,0 +1,86 @@ +#include "sound.h" +#include "util/stringUtils.h" + +#include +#include + +static void close_hdl(struct sioctl_hdl** phdl) +{ + assert(phdl); + if (*phdl) sioctl_close(*phdl); +} + +enum { MAX_CHANNEL_NUM = 8 }; + +typedef struct FFSoundDeviceBundle +{ + char name[SIOCTL_DISPLAYMAX]; + double level[MAX_CHANNEL_NUM]; + uint8_t iLevel; + bool mute[MAX_CHANNEL_NUM]; + uint8_t iMute; +} FFSoundDeviceBundle; + +static void enumerate_props(FFSoundDeviceBundle* bundle, struct sioctl_desc* desc, int val) +{ + if (!desc) return; + + if (desc->type == SIOCTL_SEL) + { + if (desc->display[0] != '\0' && ffStrEquals(desc->node0.name, "server")) + ffStrCopy(bundle->name, desc->display, SIOCTL_DISPLAYMAX); + return; + } + + if (desc->type != SIOCTL_NUM && desc->type != SIOCTL_SW) + return; + + if (!ffStrEquals(desc->node0.name, "output")) + return; + + if (ffStrEquals(desc->func, "level")) + { + if (__builtin_expect(bundle->iLevel == MAX_CHANNEL_NUM, false)) + return; + bundle->level[bundle->iLevel] = (double) val / (double) desc->maxval; + ++bundle->iLevel; + } + else if (ffStrEquals(desc->func, "mute")) + { + if (__builtin_expect(bundle->iMute == MAX_CHANNEL_NUM, false)) + return; + bundle->mute[bundle->iMute] = !!val; + ++bundle->iMute; + } +} + +const char* ffDetectSound(FFlist* devices) +{ + __attribute__((__cleanup__(close_hdl))) struct sioctl_hdl* hdl = sioctl_open(SIO_DEVANY, SIOCTL_READ, 0); + if (!hdl) return "sio_open() failed"; + + FFSoundDeviceBundle bundle = {}; + if (sioctl_ondesc(hdl, (void*) enumerate_props, &bundle) == 0) + return "sioctl_ondesc() failed"; + + if (bundle.iLevel != bundle.iMute || bundle.iLevel == 0) + return "Unexpecd sioctl_ondesc() result"; + + FFSoundDevice* device = ffListAdd(devices); + ffStrbufInitS(&device->name, bundle.name); + ffStrbufInitS(&device->identifier, SIO_DEVANY); + ffStrbufInitStatic(&device->platformApi, "sndio"); + device->active = true; + device->main = true; + device->volume = 0; + + double totalLevel = 0; + for (uint8_t i = 0; i < bundle.iLevel; ++i) + { + if (!bundle.mute[i]) + totalLevel += bundle.level[i]; + } + device->volume = (uint8_t) (totalLevel * 100 / bundle.iLevel); + + return NULL; +} From 4d842ac6b68f82a6bd69f043bc08678df02bc000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 27 Jan 2025 21:41:55 +0800 Subject: [PATCH 06/44] CPU (Linux): fix build on PPC --- src/detection/cpu/cpu_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 6e561c63..8e6030bb 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -305,7 +305,7 @@ static const char* parseCpuInfo( #endif #if __powerpc__ || __powerpc - (cpuMHz->length == 0 && ffParsePropLine(line, "clock :", &cpuMHz)) || //For POWER + (cpuMHz->length == 0 && ffParsePropLine(line, "clock :", cpuMHz)) || //For POWER (cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER #endif From 3d8050fd5cce358a4ab9ef25408ab152d4fe6fb0 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 27 Jan 2025 23:49:42 +0800 Subject: [PATCH 07/44] Sound (NetBSD): use kernel APIs instead of the OSS wrapper --- CMakeLists.txt | 3 +- src/detection/sound/sound_nbsd.c | 50 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/detection/sound/sound_nbsd.c diff --git a/CMakeLists.txt b/CMakeLists.txt index c82e70ce..066ba2e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -761,7 +761,7 @@ elseif(NetBSD) src/detection/poweradapter/poweradapter_nosupport.c src/detection/processes/processes_nbsd.c src/detection/gtk_qt/qt.c - src/detection/sound/sound_bsd.c + src/detection/sound/sound_nbsd.c src/detection/swap/swap_obsd.c src/detection/terminalfont/terminalfont_linux.c src/detection/terminalshell/terminalshell_linux.c @@ -1510,7 +1510,6 @@ elseif(NetBSD) target_link_libraries(libfastfetch PRIVATE "m" PRIVATE "prop" - PRIVATE "ossaudio" ) elseif(SunOS) target_link_libraries(libfastfetch diff --git a/src/detection/sound/sound_nbsd.c b/src/detection/sound/sound_nbsd.c new file mode 100644 index 00000000..03d76ac8 --- /dev/null +++ b/src/detection/sound/sound_nbsd.c @@ -0,0 +1,50 @@ +#include "sound.h" +#include "common/io/io.h" + +#include +#include +#include +#include +#include + +const char* ffDetectSound(FFlist* devices) +{ + int defaultDev; + { + char audiop[12]; + ssize_t plen = readlink("/dev/audio", audiop, ARRAY_SIZE(audiop)); + if (plen < (ssize_t) strlen("audioN")) + return "readlink(/dev/audio) failed"; + defaultDev = audiop[plen - 1] - '0'; + if (defaultDev < 0 || defaultDev > 9) + return "Invalid audio device"; + } + + char path[] = "/dev/audio0"; + + for (int idev = 0; idev < 9; ++idev) + { + path[strlen("/dev/audio")] = (char) ('0' + idev); + FF_AUTO_CLOSE_FD int fd = open(path, O_RDWR); + if (fd < 0) break; + + audio_device_t ad; + if (ioctl(fd, AUDIO_GETDEV, &ad) < 0) + continue; + + audio_info_t ai; + if (ioctl(fd, AUDIO_GETINFO, &ai) < 0) + continue; + + FFSoundDevice* device = ffListAdd(devices); + ffStrbufInitS(&device->identifier, path); + ffStrbufInitS(&device->name, ad.name); + ffStrbufTrimRightSpace(&device->name); + ffStrbufInitF(&device->platformApi, "%s", "SunAudio"); + device->volume = (uint8_t) (ai.play.gain * 100 / AUDIO_MAX_GAIN); + device->active = true; + device->main = defaultDev == idev; + } + + return NULL; +} From abadcb95bdfd714e4e0394f02a4aefb5207e2eb2 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 27 Jan 2025 23:52:25 +0800 Subject: [PATCH 08/44] CMake (OpenBSD): remove pulseaudio detection --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 066ba2e7..d120d37b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,7 @@ cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD O cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF) cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS" OFF) cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) -cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR OpenBSD OR SunOS" OFF) +cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF) cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF) cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF) cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly" OFF) From fe7c4f724e617b40454fecad25655ebf27807045 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 27 Jan 2025 23:52:59 +0800 Subject: [PATCH 09/44] Disk (BSD): silence compiler warnings --- src/detection/disk/disk_bsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/disk/disk_bsd.c b/src/detection/disk/disk_bsd.c index 3ad7e745..b3ddf2e4 100644 --- a/src/detection/disk/disk_bsd.c +++ b/src/detection/disk/disk_bsd.c @@ -143,7 +143,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) for(struct statfs* fs = buf; fs < buf + size; ++fs) { - if(__builtin_expect(options->folders.length, 0)) + if(__builtin_expect(options->folders.length > 0, 0)) { if(!ffDiskMatchMountpoint(options, fs->f_mntonname)) continue; From 33c905aa99ac7e7f81e204af4c9167f9c4c1307d Mon Sep 17 00:00:00 2001 From: sirenuf <51026586+sirenuf@users.noreply.github.com> Date: Fri, 31 Jan 2025 16:03:07 +0100 Subject: [PATCH 10/44] Logo (Builtin): change arch_old logo colours to be more accurate to the actual original logo. --- src/logo/builtin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 18ab417e..bc0961e1 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -384,11 +384,11 @@ static const FFlogo A[] = { .type = FF_LOGO_LINE_TYPE_ALTER_BIT, .lines = FASTFETCH_DATATEXT_LOGO_ARCH_OLD, .colors = { - FF_COLOR_FG_CYAN, + FF_COLOR_FG_BLUE, FF_COLOR_FG_WHITE, }, .colorTitle = FF_COLOR_FG_DEFAULT, - .colorKeys = FF_COLOR_FG_CYAN, + .colorKeys = FF_COLOR_FG_BLUE, }, // Archlabs { From 01f400c15f1bff8217c9d4c6f24316b7b254757d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Wed, 5 Feb 2025 02:08:28 +0100 Subject: [PATCH 11/44] Haiku: minimal implementation (#1538) --- CMakeLists.txt | 77 ++++++++++++++++++- src/common/io/io_unix.c | 2 +- src/common/netif/netif_haiku.c | 63 +++++++++++++++ .../displayserver/displayserver_haiku.cpp | 72 +++++++++++++++++ src/detection/dns/dns_linux.c | 8 +- src/detection/font/font.h | 1 + src/detection/font/font_haiku.cpp | 65 ++++++++++++++++ src/detection/localip/localip_linux.c | 23 +++++- src/detection/memory/memory_haiku.c | 15 ++++ src/detection/os/os_haiku.c | 20 +++++ src/detection/packages/packages.c | 2 +- src/detection/packages/packages_haiku.c | 13 ++++ src/detection/processes/processes_haiku.c | 14 ++++ src/detection/swap/swap_haiku.c | 17 ++++ src/detection/uptime/uptime_haiku.c | 11 +++ src/detection/version/version.c | 2 + src/util/platform/FFPlatform_unix.c | 23 ++++++ 17 files changed, 420 insertions(+), 8 deletions(-) create mode 100644 src/common/netif/netif_haiku.c create mode 100644 src/detection/displayserver/displayserver_haiku.cpp create mode 100644 src/detection/font/font_haiku.cpp create mode 100644 src/detection/memory/memory_haiku.c create mode 100644 src/detection/os/os_haiku.c create mode 100644 src/detection/packages/packages_haiku.c create mode 100644 src/detection/processes/processes_haiku.c create mode 100644 src/detection/swap/swap_haiku.c create mode 100644 src/detection/uptime/uptime_haiku.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d120d37b..85922e0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,8 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly") set(DragonFly TRUE CACHE BOOL "..." FORCE) elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS") set(SunOS TRUE CACHE BOOL "..." FORCE) +elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Haiku") + set(Haiku TRUE CACHE BOOL "..." FORCE) elseif(NOT APPLE AND NOT WIN32) message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") endif() @@ -139,7 +141,7 @@ set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=retu set(CMAKE_C_STANDARD 11) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion") -if(WIN32 OR ENABLE_DIRECTX_HEADERS) +if(WIN32 OR HAIKU OR ENABLE_DIRECTX_HEADERS) enable_language(CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}") @@ -1088,6 +1090,74 @@ elseif(SunOS) src/util/platform/FFPlatform_unix.c src/util/binary_linux.c ) +elseif(Haiku) + list(APPEND LIBFASTFETCH_SRC + src/common/io/io_unix.c + src/common/netif/netif_haiku.c + src/common/networking_linux.c + src/common/processing_linux.c + src/detection/battery/battery_nosupport.c + src/detection/bios/bios_nosupport.c + src/detection/board/board_nosupport.c + src/detection/bootmgr/bootmgr_nosupport.c + src/detection/brightness/brightness_nosupport.c + src/detection/btrfs/btrfs_nosupport.c + src/detection/chassis/chassis_nosupport.c + src/detection/cpu/cpu_nosupport.c + src/detection/cpucache/cpucache_nosupport.c + src/detection/cpuusage/cpuusage_nosupport.c + src/detection/cursor/cursor_nosupport.c + src/detection/bluetooth/bluetooth_nosupport.c + src/detection/bluetoothradio/bluetoothradio_nosupport.c + src/detection/disk/disk_nosupport.c + src/detection/dns/dns_linux.c + src/detection/physicaldisk/physicaldisk_nosupport.c + src/detection/physicalmemory/physicalmemory_nosupport.c + src/detection/diskio/diskio_nosupport.c + src/detection/displayserver/displayserver_haiku.cpp + src/detection/font/font_haiku.cpp + src/detection/gpu/gpu_nosupport.c + src/detection/gpu/gpu_pci.c + src/detection/gtk_qt/gtk.c + src/detection/host/host_nosupport.c + src/detection/icons/icons_nosupport.c + src/detection/initsystem/initsystem_nosupport.c + src/detection/keyboard/keyboard_nosupport.c + src/detection/libc/libc_nosupport.c + src/detection/lm/lm_nosupport.c + src/detection/loadavg/loadavg_nosupport.c + src/detection/locale/locale_linux.c + src/detection/localip/localip_linux.c + src/detection/gamepad/gamepad_nosupport.c + src/detection/media/media_nosupport.c + src/detection/memory/memory_haiku.c + src/detection/mouse/mouse_nosupport.c + src/detection/netio/netio_nosupport.c + src/detection/opengl/opengl_linux.c + src/detection/os/os_uname.c + src/detection/packages/packages_haiku.c + src/detection/poweradapter/poweradapter_nosupport.c + src/detection/processes/processes_haiku.c + src/detection/gtk_qt/qt.c + src/detection/sound/sound_nosupport.c + src/detection/swap/swap_haiku.c + src/detection/terminalfont/terminalfont_linux.c + src/detection/terminalshell/terminalshell_linux.c + src/detection/terminalsize/terminalsize_linux.c + src/detection/theme/theme_nosupport.c + src/detection/tpm/tpm_nosupport.c + src/detection/uptime/uptime_haiku.c + src/detection/users/users_linux.c + src/detection/wallpaper/wallpaper_nosupport.c + src/detection/wifi/wifi_nosupport.c + src/detection/wm/wm_nosupport.c + src/detection/de/de_nosupport.c + src/detection/wmtheme/wmtheme_nosupport.c + src/detection/camera/camera_nosupport.c + src/detection/zpool/zpool_nosupport.c + src/util/platform/FFPlatform_unix.c + src/util/binary_linux.c + ) endif() if(ENABLE_DIRECTX_HEADERS) @@ -1534,6 +1604,11 @@ elseif(ANDROID) ) endif() endif() +elseif(Haiku) + target_link_libraries(libfastfetch + PRIVATE "network" + PRIVATE "be" + ) endif() target_include_directories(libfastfetch diff --git a/src/common/io/io_unix.c b/src/common/io/io_unix.c index 69b6fbca..5623d2dc 100644 --- a/src/common/io/io_unix.c +++ b/src/common/io/io_unix.c @@ -310,7 +310,7 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta continue; bool isDir = false; -#ifndef __sun +#if !defined(__sun) && !defined(__HAIKU__) if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK) isDir = entry->d_type == DT_DIR; else diff --git a/src/common/netif/netif_haiku.c b/src/common/netif/netif_haiku.c new file mode 100644 index 00000000..a08f6358 --- /dev/null +++ b/src/common/netif/netif_haiku.c @@ -0,0 +1,63 @@ +#include "netif.h" +#include "common/io/io.h" +#include "util/mallocHelper.h" + +#include +#include +#include +#include +#include +#include + +// losely based on Haiku's src/bin/network/route/route.cpp + +bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex) +{ + // TODO: AF_INET6 + FF_AUTO_CLOSE_FD int pfRoute = socket(AF_INET, SOCK_RAW, AF_INET); + if (pfRoute < 0) + return false; + + struct ifconf config; + config.ifc_len = sizeof(config.ifc_value); + if (ioctl(pfRoute, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0) + return false; + + int size = config.ifc_value; + if (size == 0) + return false; + + FF_AUTO_FREE void *buffer = malloc(size); + if (buffer == NULL) { + return false; + } + + config.ifc_len = size; + config.ifc_buf = buffer; + if (ioctl(pfRoute, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0) + return false; + + struct ifreq *interface = (struct ifreq*)buffer; + struct ifreq *end = (struct ifreq*)((uint8_t*)buffer + size); + + while (interface < end) { + if (interface->ifr_route.flags & RTF_DEFAULT) { + strlcpy(iface, interface->ifr_name, IF_NAMESIZE); + *ifIndex = if_nametoindex(interface->ifr_name); + return true; + } + + size_t addressSize = 0; + if (interface->ifr_route.destination != NULL) + addressSize += interface->ifr_route.destination->sa_len; + if (interface->ifr_route.mask != NULL) + addressSize += interface->ifr_route.mask->sa_len; + if (interface->ifr_route.gateway != NULL) + addressSize += interface->ifr_route.gateway->sa_len; + + interface = (struct ifreq*)((addr_t)interface + IF_NAMESIZE + + sizeof(struct route_entry) + addressSize); + } + + return false; +} diff --git a/src/detection/displayserver/displayserver_haiku.cpp b/src/detection/displayserver/displayserver_haiku.cpp new file mode 100644 index 00000000..b6f2e869 --- /dev/null +++ b/src/detection/displayserver/displayserver_haiku.cpp @@ -0,0 +1,72 @@ +extern "C" { +#include "displayserver.h" +#include "common/settings.h" +#include "common/processing.h" +} + +#include + +#include +#include + +extern "C" void ffConnectDisplayServerImpl(FFDisplayServerResult* ds); + +static void detectDisplays(FFDisplayServerResult* ds) +{ + // We need a valid be_app to query the app_server here. + BApplication app("application/x-vnd.fastfetch-cli-fastfetch"); + BScreen s{}; // default screen is the main one + bool main = true; + + do + { + if (!s.IsValid()) + continue; + + display_mode mode; + if (s.GetMode(&mode) != B_OK) + continue; + + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateA(128); + monitor_info monitor; + // WARNING: This is experimental new Haiku API + status_t err = s.GetMonitorInfo(&monitor); + if (err == B_OK) { + ffStrbufSetF(&name, "%s %s", monitor.vendor, monitor.name); + } + + uint32_t width = (uint32_t) s.Frame().Width() + 1; + uint32_t height = (uint32_t) (uint32_t)s.Frame().Height() + 1; + double scaleFactor = (double) 1.0; + ffdsAppendDisplay(ds, + width, + height, + (double)mode.timing.pixel_clock * 1000 / (mode.timing.v_total * mode.timing.h_total), + (uint32_t) (width / scaleFactor + .5), + (uint32_t) (height / scaleFactor + .5), + 0, + 0, + 0, + 0, + &name, + FF_DISPLAY_TYPE_UNKNOWN, + main, + s.ID().id, + 0, + 0, + "BScreen" + ); + main = false; + } while (s.SetToNext() == B_OK); + + return; +} + +void ffConnectDisplayServerImpl(FFDisplayServerResult* ds) +{ + ffStrbufSetStatic(&ds->wmProcessName, "app_server"); + ffStrbufSetStatic(&ds->wmPrettyName, "Application Server"); + ffStrbufSetStatic(&ds->dePrettyName, "Application Kit"); + + detectDisplays(ds); +} diff --git a/src/detection/dns/dns_linux.c b/src/detection/dns/dns_linux.c index 1179ea4a..8bf1da0c 100644 --- a/src/detection/dns/dns_linux.c +++ b/src/detection/dns/dns_linux.c @@ -4,9 +4,15 @@ #include "util/mallocHelper.h" #include "util/stringUtils.h" +#ifdef __HAIKU__ +#define RESOLV_CONF "/system/settings/network/resolv.conf" +#else +#define RESOLV_CONF "/etc/resolv.conf" +#endif + const char* ffDetectDNS(FFDNSOptions* options, FFlist* results) { - FF_AUTO_CLOSE_FILE FILE* file = fopen(FASTFETCH_TARGET_DIR_ROOT "/etc/resolv.conf", "r"); + FF_AUTO_CLOSE_FILE FILE* file = fopen(FASTFETCH_TARGET_DIR_ROOT RESOLV_CONF, "r"); if (!file) return "fopen (" FASTFETCH_TARGET_DIR_ROOT "/etc/resolv.conf) failed"; diff --git a/src/detection/font/font.h b/src/detection/font/font.h index f0c59bba..0f0e28d1 100644 --- a/src/detection/font/font.h +++ b/src/detection/font/font.h @@ -10,6 +10,7 @@ typedef struct FFFontResult * Linux / BSD: Qt, GTK2, GTK3, GTK4 * MacOS: System, User, System Mono, User Mono * Windows: Caption, Menu, Message, Status + * Haiku: Plain, Menu, Bold, Mono * Other: Unset, Unset, Unset, Unset */ FFstrbuf fonts[FF_DETECT_FONT_NUM_FONTS]; diff --git a/src/detection/font/font_haiku.cpp b/src/detection/font/font_haiku.cpp new file mode 100644 index 00000000..5f64aecd --- /dev/null +++ b/src/detection/font/font_haiku.cpp @@ -0,0 +1,65 @@ +extern "C" { +#include "common/font.h" +#include "common/parsing.h" +#include "font.h" +} + +#include +#include +#include + +extern "C" { + const char* ffDetectFontImpl(FFFontResult* result); +} + +static void generateString(FFFontResult* font) +{ + const char* types[] = { "Plain", "Menu", "Bold", "Mono" }; + for(uint32_t i = 0; i < ARRAY_SIZE(types); ++i) + { + if(i == 0 || !ffStrbufEqual(&font->fonts[i - 1], &font->fonts[i])) + { + if(i > 0) + ffStrbufAppendS(&font->display, "], "); + ffStrbufAppendF(&font->display, "%s [%s", font->fonts[i].chars, types[i]); + } + else + { + ffStrbufAppendS(&font->display, " / "); + ffStrbufAppendS(&font->display, types[i]); + } + } + ffStrbufAppendC(&font->display, ']'); +} + +const char* ffDetectFontImpl(FFFontResult* result) +{ + struct menu_info menuInfo; + const BFont *f; + // We need a valid be_app to query the app_server here. + BApplication app("application/x-vnd.fastfetch-cli-fastfetch"); + + if ((f = be_plain_font) != NULL) + { + f->GetFamilyAndStyle(&menuInfo.f_family, &menuInfo.f_style); + ffStrbufAppendF(&result->fonts[0], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)f->Size()); + } + if (get_menu_info(&menuInfo) == B_OK) + { + ffStrbufAppendF(&result->fonts[1], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)menuInfo.font_size); + } + if ((f = be_bold_font) != NULL) + { + f->GetFamilyAndStyle(&menuInfo.f_family, &menuInfo.f_style); + ffStrbufAppendF(&result->fonts[2], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)f->Size()); + } + if ((f = be_fixed_font) != NULL) + { + f->GetFamilyAndStyle(&menuInfo.f_family, &menuInfo.f_style); + ffStrbufAppendF(&result->fonts[3], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)f->Size()); + } + + generateString(result); + + return NULL; +} diff --git a/src/detection/localip/localip_linux.c b/src/detection/localip/localip_linux.c index 7a855281..f9cc343d 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -18,23 +18,27 @@ #include #endif -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) || defined(__HAIKU__) #include #include #else #include #endif -#ifdef __sun +#if defined(__sun) || defined(__HAIKU__) #include #endif static const FFLocalIpNIFlag niFlagOptions[] = { { IFF_UP, "UP" }, { IFF_BROADCAST, "BROADCAST" }, +#ifdef IFF_DEBUG { IFF_DEBUG, "DEBUG" }, +#endif { IFF_LOOPBACK, "LOOPBACK" }, { IFF_POINTOPOINT, "POINTOPOINT" }, +#ifdef IFF_RUNNING { IFF_RUNNING, "RUNNING" }, +#endif { IFF_NOARP, "NOARP" }, { IFF_PROMISC, "PROMISC" }, { IFF_ALLMULTI, "ALLMULTI" }, @@ -64,6 +68,13 @@ static const FFLocalIpNIFlag niFlagOptions[] = { #endif #ifdef IFF_CANTCONFIG { IFF_CANTCONFIG, "CANTCONFIG" }, +#endif +#ifdef __HAIKU__ + { IFF_AUTOUP, "IAUTOUP" }, + { IFF_SIMPLEX, "SIMPLEX" }, + { IFF_LINK, "LINK" }, + { IFF_AUTO_CONFIGURED, "AUTO_CONFIGURED" }, + { IFF_CONFIGURING, "CONFIGURING" }, #endif // sentinel {}, @@ -128,8 +139,12 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) for (struct ifaddrs* ifa = ifAddrStruct; ifa; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr || !(ifa->ifa_flags & IFF_RUNNING)) + if (!ifa->ifa_addr) continue; +#ifdef IFF_RUNNING + if (!(ifa->ifa_flags & IFF_RUNNING)) + continue; +#endif bool isDefaultRoute = ffStrEquals(defaultRouteIfName, ifa->ifa_name); if ((options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT) && !isDefaultRoute) @@ -190,7 +205,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute, flags, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT)); } - #if __FreeBSD__ || __OpenBSD__ || __APPLE__ || __NetBSD__ + #if __FreeBSD__ || __OpenBSD__ || __APPLE__ || __NetBSD__ || __HAIKU__ else if (ifa->ifa_addr->sa_family == AF_LINK) { if (!(options->showType & FF_LOCALIP_TYPE_MAC_BIT)) diff --git a/src/detection/memory/memory_haiku.c b/src/detection/memory/memory_haiku.c new file mode 100644 index 00000000..b69ddfa3 --- /dev/null +++ b/src/detection/memory/memory_haiku.c @@ -0,0 +1,15 @@ +#include "memory.h" + +#include + +const char* ffDetectMemory(FFMemoryResult* ram) +{ + system_info info; + if (get_system_info(&info) != B_OK) + return "Error getting system info"; + + ram->bytesTotal = B_PAGE_SIZE * info.max_pages; + ram->bytesUsed = B_PAGE_SIZE * info.used_pages; + + return NULL; +} diff --git a/src/detection/os/os_haiku.c b/src/detection/os/os_haiku.c new file mode 100644 index 00000000..f31fb28f --- /dev/null +++ b/src/detection/os/os_haiku.c @@ -0,0 +1,20 @@ +#include "os.h" +#include "common/io/io.h" + +#include + +void ffDetectOSImpl(FFOSResult* os) +{ + system_info info; + + ffStrbufSetStatic(&os->name, "Haiku"); + ffStrbufSetStatic(&os->prettyName, "Haiku"); + + ffStrbufSetStatic(&os->id, "haiku"); + + if (get_system_info(&info) != B_OK) + return; + ffStrbufAppendF(&os->version, "R%lld", info.kernel_version); + + // TODO: check kernel resources? +} diff --git a/src/detection/packages/packages.c b/src/detection/packages/packages.c index 47cf99b6..37325656 100644 --- a/src/detection/packages/packages.c +++ b/src/detection/packages/packages.c @@ -100,7 +100,7 @@ uint32_t ffPackagesGetNumElements(const char* dirname, bool isdir) { bool ok = false; -#ifndef __sun +#if !defined(__sun) && !defined(__HAIKU__) if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK) ok = entry->d_type == (isdir ? DT_DIR : DT_REG); else diff --git a/src/detection/packages/packages_haiku.c b/src/detection/packages/packages_haiku.c new file mode 100644 index 00000000..b66edefb --- /dev/null +++ b/src/detection/packages/packages_haiku.c @@ -0,0 +1,13 @@ +#include "packages.h" + +#include "common/io/io.h" + +void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options) +{ + // TODO: Use the Package Kit C++ API instead (would account for disabled packages) + + if (!(options->disabled & FF_PACKAGES_FLAG_PKG_BIT)) + result->pkg = ffPackagesGetNumElements(FASTFETCH_TARGET_DIR_ROOT "/system/packages", false); + if (!(options->disabled & FF_PACKAGES_FLAG_PKGSRC_BIT)) + result->pkgsrc = ffPackagesGetNumElements(FASTFETCH_TARGET_DIR_ROOT "/boot/home/config/packages", false); +} diff --git a/src/detection/processes/processes_haiku.c b/src/detection/processes/processes_haiku.c new file mode 100644 index 00000000..8e373729 --- /dev/null +++ b/src/detection/processes/processes_haiku.c @@ -0,0 +1,14 @@ +#include "processes.h" + +#include + +const char* ffDetectProcesses(uint32_t* result) +{ + system_info info; + if (get_system_info(&info) != B_OK) + return "Error getting system info"; + + *result = info.used_teams; + + return NULL; +} diff --git a/src/detection/swap/swap_haiku.c b/src/detection/swap/swap_haiku.c new file mode 100644 index 00000000..b61f213e --- /dev/null +++ b/src/detection/swap/swap_haiku.c @@ -0,0 +1,17 @@ +#include "swap.h" + +#include + +enum { FFMaxNSwap = 8 }; + +const char* ffDetectSwap(FFSwapResult* swap) +{ + system_info info; + if (get_system_info(&info) != B_OK) + return "Error getting system info"; + + swap->bytesTotal = B_PAGE_SIZE * info.max_swap_pages; + swap->bytesUsed = B_PAGE_SIZE * (info.max_swap_pages - info.free_swap_pages); + + return NULL; +} diff --git a/src/detection/uptime/uptime_haiku.c b/src/detection/uptime/uptime_haiku.c new file mode 100644 index 00000000..46af1115 --- /dev/null +++ b/src/detection/uptime/uptime_haiku.c @@ -0,0 +1,11 @@ +#include "uptime.h" +#include "common/time.h" + +#include + +const char* ffDetectUptime(FFUptimeResult* result) +{ + result->uptime = system_time() / 1000; + result->bootTime = (real_time_clock_usecs() / 1000) - result->uptime; + return NULL; +} diff --git a/src/detection/version/version.c b/src/detection/version/version.c index a979bde5..ce493344 100644 --- a/src/detection/version/version.c +++ b/src/detection/version/version.c @@ -42,6 +42,8 @@ #define FF_SYSNAME "OpenBSD" #elif defined(__NetBSD__) #define FF_SYSNAME "NetBSD" +#elif defined(__HAIKU__) + #define FF_SYSNAME "Haiku" #else #define FF_SYSNAME "unknown" #endif diff --git a/src/util/platform/FFPlatform_unix.c b/src/util/platform/FFPlatform_unix.c index c8b5c7c6..88944c4a 100644 --- a/src/util/platform/FFPlatform_unix.c +++ b/src/util/platform/FFPlatform_unix.c @@ -14,6 +14,9 @@ #include #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #include +#elif defined(__HAIKU__) + #include + #include #endif static void getExePath(FFPlatform* platform) @@ -47,6 +50,17 @@ static void getExePath(FFPlatform* platform) ssize_t exePathLen = readlink("/proc/self/path/a.out", exePath, sizeof(exePath) - 1); if (exePathLen >= 0) exePath[exePathLen] = '\0'; + #elif defined(__HAIKU__) + size_t exePathLen = 0; + image_info info; + int32 cookie = 0; + + while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) { + if (info.type == B_APP_IMAGE) { + exePathLen = strlcpy(exePath, info.name, PATH_MAX); + break; + } + } #endif if (exePathLen > 0) { @@ -117,6 +131,9 @@ static void getConfigDirs(FFPlatform* platform) ffPlatformPathAddHome(&platform->configDirs, platform, "Library/Preferences/"); ffPlatformPathAddHome(&platform->configDirs, platform, "Library/Application Support/"); #endif + #if defined(__HAIKU__) + ffPlatformPathAddHome(&platform->configDirs, platform, "config/settings/"); + #endif ffPlatformPathAddHome(&platform->configDirs, platform, ""); platformPathAddEnv(&platform->configDirs, "XDG_CONFIG_DIRS"); @@ -185,6 +202,12 @@ static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts) ffStrbufAppendS(&info->name, uts->sysname); ffStrbufAppendS(&info->release, uts->release); ffStrbufAppendS(&info->version, uts->version); + #ifdef __HAIKU__ + /* historical reason */ + if (!strcmp(uts->machine, "BePC")) + ffStrbufAppendS(&info->architecture, "i386"); + else + #endif ffStrbufAppendS(&info->architecture, uts->machine); ffStrbufInit(&info->displayVersion); From d1ba690973f8ce91231b1a58b21485e4b9113204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 10:14:37 +0800 Subject: [PATCH 12/44] Chore: fix typo --- src/common/netif/netif_haiku.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/netif/netif_haiku.c b/src/common/netif/netif_haiku.c index a08f6358..07185a7e 100644 --- a/src/common/netif/netif_haiku.c +++ b/src/common/netif/netif_haiku.c @@ -9,7 +9,7 @@ #include #include -// losely based on Haiku's src/bin/network/route/route.cpp +// loosely based on Haiku's src/bin/network/route/route.cpp bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex) { From dd67010e5cc67f4df3dfc125899d9fb74908d598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 10:15:09 +0800 Subject: [PATCH 13/44] CMake (Haiku): fix an invalid file name --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 85922e0d..95d74a2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1134,7 +1134,7 @@ elseif(Haiku) src/detection/mouse/mouse_nosupport.c src/detection/netio/netio_nosupport.c src/detection/opengl/opengl_linux.c - src/detection/os/os_uname.c + src/detection/os/os_haiku.c src/detection/packages/packages_haiku.c src/detection/poweradapter/poweradapter_nosupport.c src/detection/processes/processes_haiku.c From fc8ddce1823d068d1ed865c3819f4461c6f5f08a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 10:15:41 +0800 Subject: [PATCH 14/44] Chore: use `ffStrEquals` instead of `strcmp` --- src/util/platform/FFPlatform_unix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/platform/FFPlatform_unix.c b/src/util/platform/FFPlatform_unix.c index 88944c4a..fbf59d85 100644 --- a/src/util/platform/FFPlatform_unix.c +++ b/src/util/platform/FFPlatform_unix.c @@ -204,8 +204,8 @@ static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts) ffStrbufAppendS(&info->version, uts->version); #ifdef __HAIKU__ /* historical reason */ - if (!strcmp(uts->machine, "BePC")) - ffStrbufAppendS(&info->architecture, "i386"); + if (ffStrEquals(uts->machine, "BePC")) + ffStrbufSetStatic(&info->architecture, "i386"); else #endif ffStrbufAppendS(&info->architecture, uts->machine); From dc5ff01e74de6e7f3d3284b7ed791a5eef748efc Mon Sep 17 00:00:00 2001 From: komaru Date: Wed, 5 Feb 2025 03:19:25 +0100 Subject: [PATCH 15/44] Logo (Builtin): add Nexa Linux logo (#1539) * Logo (Builtin): add Nexa Linux logo * Update nexalinux.txt Remove padding --------- Co-authored-by: Carter Li --- src/logo/ascii/nexalinux.txt | 19 +++++++++++++++++++ src/logo/builtin.c | 9 +++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/logo/ascii/nexalinux.txt diff --git a/src/logo/ascii/nexalinux.txt b/src/logo/ascii/nexalinux.txt new file mode 100644 index 00000000..4372a750 --- /dev/null +++ b/src/logo/ascii/nexalinux.txt @@ -0,0 +1,19 @@ + ******** + ***************** + ********************** + ************************** +********** ********** +******* ********* +****** ******** +******* ******* +********* ****** ******* + ***************** ****** + *************** ******* + *********** ******* + ******** + ******** + ********* + ********** + ********* + ******* + *** diff --git a/src/logo/builtin.c b/src/logo/builtin.c index bc0961e1..36c77318 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -3056,6 +3056,15 @@ static const FFlogo N[] = { FF_COLOR_FG_WHITE, }, }, + // NexaLinux + { + .names = {"nexalinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_NEXALINUX, + .colors = { + FF_COLOR_FG_LIGHT_BLUE, + FF_COLOR_FG_LIGHT_BLUE, + }, + }, // Nitrux { .names = {"Nitrux"}, From 71a2e558692ba66716b3b8c51ca4eaa792db14d4 Mon Sep 17 00:00:00 2001 From: Thomas Duckworth Date: Wed, 5 Feb 2025 13:23:00 +1100 Subject: [PATCH 16/44] Logo (Builtin): add filotimo logo (#1535) --- src/logo/ascii/filotimo.txt | 20 ++++++++++++++++++++ src/logo/builtin.c | 10 ++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/logo/ascii/filotimo.txt diff --git a/src/logo/ascii/filotimo.txt b/src/logo/ascii/filotimo.txt new file mode 100644 index 00000000..ca5bb45b --- /dev/null +++ b/src/logo/ascii/filotimo.txt @@ -0,0 +1,20 @@ + O ' + lk: ;xX. .0K ' + lodk ;lldK' .lld0O :okX; + lloo0 ;lllld0: .lllllxKx :clllkKk + llllo, ;llllloox .clllllloxK :cclllllx0N + lllll, ;llllllll .cclllllllo' :cccclllllld + cllll, ;cclllllc .ccccllllll' :cccccclllll + cllll, ;cccllllc ccccccllll' ::cccccclllc + ccccl, ;cccccllc :cccccccll' :::ccccccclc + ccccc, ;cccccccc ::cccccccl' :::::ccccccc + :cccc, ;:ccccccc ::::cccccc' :::::::ccccc + :cccc, ;:::ccccc ::::::cccc' :;::::::ccc: + :::cc, ;:::::ccc ;:::::::cc' :;;:::::::c: + :::::, ;:::::::c ;;:::::::c' :;;;;::::::: + :::::, ;;::::::c ;;;;::::::' :;;;;;:::::: + ;::::, ,;;;::::c ,;;;;;::::' ';;;;;;:::: + ';;::, ;;;;::: .;;;;;::' .;;;;;:: + ;;;, ;;;;: .;;;:' ;;;: + ,;, ,;: ';' + ., \ No newline at end of file diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 36c77318..349828a3 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1690,6 +1690,16 @@ static const FFlogo F[] = { .colorKeys = FF_COLOR_FG_BLUE, .colorTitle = FF_COLOR_FG_WHITE, }, + // Filotimo + { + .names = {"filotimo"}, + .lines = FASTFETCH_DATATEXT_LOGO_FILOTIMO, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, // Finnix { .names = {"Finnix"}, From 9221e2b41d40713eb0b2a24c17b218e0ca6e9dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 10:23:59 +0800 Subject: [PATCH 17/44] Logo (Builtin): remove left padding of filotimo --- src/logo/ascii/filotimo.txt | 40 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/logo/ascii/filotimo.txt b/src/logo/ascii/filotimo.txt index ca5bb45b..48ebb26d 100644 --- a/src/logo/ascii/filotimo.txt +++ b/src/logo/ascii/filotimo.txt @@ -1,20 +1,20 @@ - O ' - lk: ;xX. .0K ' - lodk ;lldK' .lld0O :okX; - lloo0 ;lllld0: .lllllxKx :clllkKk - llllo, ;llllloox .clllllloxK :cclllllx0N - lllll, ;llllllll .cclllllllo' :cccclllllld - cllll, ;cclllllc .ccccllllll' :cccccclllll - cllll, ;cccllllc ccccccllll' ::cccccclllc - ccccl, ;cccccllc :cccccccll' :::ccccccclc - ccccc, ;cccccccc ::cccccccl' :::::ccccccc - :cccc, ;:ccccccc ::::cccccc' :::::::ccccc - :cccc, ;:::ccccc ::::::cccc' :;::::::ccc: - :::cc, ;:::::ccc ;:::::::cc' :;;:::::::c: - :::::, ;:::::::c ;;:::::::c' :;;;;::::::: - :::::, ;;::::::c ;;;;::::::' :;;;;;:::::: - ;::::, ,;;;::::c ,;;;;;::::' ';;;;;;:::: - ';;::, ;;;;::: .;;;;;::' .;;;;;:: - ;;;, ;;;;: .;;;:' ;;;: - ,;, ,;: ';' - ., \ No newline at end of file +O ' +lk: ;xX. .0K ' +lodk ;lldK' .lld0O :okX; +lloo0 ;lllld0: .lllllxKx :clllkKk +llllo, ;llllloox .clllllloxK :cclllllx0N +lllll, ;llllllll .cclllllllo' :cccclllllld +cllll, ;cclllllc .ccccllllll' :cccccclllll +cllll, ;cccllllc ccccccllll' ::cccccclllc +ccccl, ;cccccllc :cccccccll' :::ccccccclc +ccccc, ;cccccccc ::cccccccl' :::::ccccccc +:cccc, ;:ccccccc ::::cccccc' :::::::ccccc +:cccc, ;:::ccccc ::::::cccc' :;::::::ccc: +:::cc, ;:::::ccc ;:::::::cc' :;;:::::::c: +:::::, ;:::::::c ;;:::::::c' :;;;;::::::: +:::::, ;;::::::c ;;;;::::::' :;;;;;:::::: +;::::, ,;;;::::c ,;;;;;::::' ';;;;;;:::: +';;::, ;;;;::: .;;;;;::' .;;;;;:: + ;;;, ;;;;: .;;;:' ;;;: + ,;, ,;: ';' + ., \ No newline at end of file From 70820e424beeaff8202e251699bd145d6111f8b5 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Wed, 5 Feb 2025 10:27:26 +0800 Subject: [PATCH 18/44] Packaging: update debian stuff [ci skip] --- debian/changelog | 6 ++++++ debian/files | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 0e146b63..5ebb8ed7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +fastfetch (2.35.0) jammy; urgency=medium + + * Update to 2.35.0 + + -- Carter Li Sun, 26 Jan 2025 10:15:22 +0800 + fastfetch (2.34.1) jammy; urgency=medium * Update to 2.34.1 diff --git a/debian/files b/debian/files index b5d98ece..45ff9c26 100644 --- a/debian/files +++ b/debian/files @@ -1 +1 @@ -fastfetch_2.34.1_source.buildinfo universe/utils optional +fastfetch_2.35.0_source.buildinfo universe/utils optional From 76710c8159f7dd358ae2c72d23a1f7eb274eac77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 11:01:09 +0800 Subject: [PATCH 19/44] Temps (macOS): support M4x --- src/detection/cpu/cpu_apple.c | 1 + src/detection/gpu/gpu_apple.c | 1 + src/util/apple/smc_temps.c | 32 ++++++++++++++++++++++++++++++-- src/util/apple/smc_temps.h | 4 +++- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index 8d5cbf0a..1226131e 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -15,6 +15,7 @@ static double detectCpuTemp(const FFstrbuf* cpuName) case 1: error = ffDetectSmcTemps(FF_TEMP_CPU_M1X, &result); break; case 2: error = ffDetectSmcTemps(FF_TEMP_CPU_M2X, &result); break; case 3: error = ffDetectSmcTemps(FF_TEMP_CPU_M3X, &result); break; + case 4: error = ffDetectSmcTemps(FF_TEMP_CPU_M4X, &result); break; default: error = "Unsupported Apple Silicon CPU"; } } diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c index 551b8bff..793db62a 100644 --- a/src/detection/gpu/gpu_apple.c +++ b/src/detection/gpu/gpu_apple.c @@ -21,6 +21,7 @@ static double detectGpuTemp(const FFstrbuf* gpuName) case 1: error = ffDetectSmcTemps(FF_TEMP_GPU_M1X, &result); break; case 2: error = ffDetectSmcTemps(FF_TEMP_GPU_M2X, &result); break; case 3: error = ffDetectSmcTemps(FF_TEMP_GPU_M3X, &result); break; + case 4: error = ffDetectSmcTemps(FF_TEMP_GPU_M4X, &result); break; default: error = "Unsupported Apple Silicon GPU"; } } diff --git a/src/util/apple/smc_temps.c b/src/util/apple/smc_temps.c index 1f9d8179..483d51e8 100644 --- a/src/util/apple/smc_temps.c +++ b/src/util/apple/smc_temps.c @@ -269,7 +269,7 @@ static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl return NULL; } -static bool detectTemp(io_connect_t conn, const char *sensor, double* sum) +static bool detectTemp(io_connect_t conn, const char* sensor, double* sum) { double temp = 0; const char* error = smcReadValue(conn, sensor, &temp); @@ -280,7 +280,7 @@ static bool detectTemp(io_connect_t conn, const char *sensor, double* sum) return true; } -const char *ffDetectSmcTemps(enum FFTempType type, double *result) +const char* ffDetectSmcTemps(enum FFTempType type, double* result) { static io_connect_t conn; if (!conn) @@ -353,6 +353,21 @@ const char *ffDetectSmcTemps(enum FFTempType type, double *result) count += detectTemp(conn, "Tf4E", result); // CPU performance core 12 break; + case FF_TEMP_CPU_M4X: + count += detectTemp(conn, "Te05", result); // CPU efficiency core 1 + count += detectTemp(conn, "Te0S", result); // CPU efficiency core 2 + count += detectTemp(conn, "Te09", result); // CPU efficiency core 3 + count += detectTemp(conn, "Te0H", result); // CPU efficiency core 4 + count += detectTemp(conn, "Tp01", result); // CPU performance core 1 + count += detectTemp(conn, "Tp05", result); // CPU performance core 2 + count += detectTemp(conn, "Tp09", result); // CPU performance core 3 + count += detectTemp(conn, "Tp0D", result); // CPU performance core 4 + count += detectTemp(conn, "Tp0V", result); // CPU performance core 5 + count += detectTemp(conn, "Tp0Y", result); // CPU performance core 6 + count += detectTemp(conn, "Tp0b", result); // CPU performance core 7 + count += detectTemp(conn, "Tp0e", result); // CPU performance core 8 + break; + case FF_TEMP_GPU_INTEL: count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics goto gpu_unknown; @@ -390,6 +405,19 @@ const char *ffDetectSmcTemps(enum FFTempType type, double *result) count += detectTemp(conn, "Tf2A", result); // GPU 8 break; + case FF_TEMP_GPU_M4X: + count += detectTemp(conn, "Tg0G", result); // GPU 1 (Basic) + count += detectTemp(conn, "Tg0H", result); // GPU 2 (Basic) + count += detectTemp(conn, "Tg1U", result); // GPU 1 (Pro / Max) + count += detectTemp(conn, "Tg1k", result); // GPU 2 (Pro / Max) + count += detectTemp(conn, "Tg0K", result); // GPU 3 + count += detectTemp(conn, "Tg0L", result); // GPU 4 + count += detectTemp(conn, "Tg0d", result); // GPU 5 + count += detectTemp(conn, "Tg0e", result); // GPU 6 + count += detectTemp(conn, "Tg0j", result); // GPU 7 + count += detectTemp(conn, "Tg0k", result); // GPU 8 + break; + case FF_TEMP_BATTERY: count += detectTemp(conn, "TB1T", result); // Battery count += detectTemp(conn, "TB2T", result); // Battery diff --git a/src/util/apple/smc_temps.h b/src/util/apple/smc_temps.h index 0d6e104c..4adc7a60 100644 --- a/src/util/apple/smc_temps.h +++ b/src/util/apple/smc_temps.h @@ -15,6 +15,7 @@ enum FFTempType FF_TEMP_CPU_M1X, FF_TEMP_CPU_M2X, FF_TEMP_CPU_M3X, + FF_TEMP_CPU_M4X, FF_TEMP_GPU_INTEL, FF_TEMP_GPU_AMD, @@ -22,10 +23,11 @@ enum FFTempType FF_TEMP_GPU_M1X, FF_TEMP_GPU_M2X, FF_TEMP_GPU_M3X, + FF_TEMP_GPU_M4X, FF_TEMP_BATTERY, FF_TEMP_MEMORY, }; -const char *ffDetectSmcTemps(enum FFTempType type, double* result); +const char* ffDetectSmcTemps(enum FFTempType type, double* result); From 994a8b4dd06e439a0193a7c5728abd990087cb2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 13:50:36 +0800 Subject: [PATCH 20/44] GPU (Nvidia): fall back to `nvmlDeviceGetMemoryInfo` if `nvmlDeviceGetMemoryInfo_v2` isn't supported --- src/detection/gpu/gpu_nvidia.c | 11 +++++++++++ src/detection/gpu/nvml.h | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/detection/gpu/gpu_nvidia.c b/src/detection/gpu/gpu_nvidia.c index e91d7eee..d9539ba5 100644 --- a/src/detection/gpu/gpu_nvidia.c +++ b/src/detection/gpu/gpu_nvidia.c @@ -10,6 +10,7 @@ struct FFNvmlData { FF_LIBRARY_SYMBOL(nvmlDeviceGetPciInfo_v3) FF_LIBRARY_SYMBOL(nvmlDeviceGetTemperature) FF_LIBRARY_SYMBOL(nvmlDeviceGetMemoryInfo_v2) + FF_LIBRARY_SYMBOL(nvmlDeviceGetMemoryInfo) FF_LIBRARY_SYMBOL(nvmlDeviceGetNumGpuCores) FF_LIBRARY_SYMBOL(nvmlDeviceGetMaxClockInfo) FF_LIBRARY_SYMBOL(nvmlDeviceGetUtilizationRates) @@ -36,6 +37,7 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetPciInfo_v3) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetTemperature) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMemoryInfo_v2) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMemoryInfo) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetNumGpuCores) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMaxClockInfo) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetUtilizationRates) @@ -130,6 +132,15 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR result.memory->total = memory.used + memory.free; result.memory->used = memory.used; } + else + { + nvmlMemory_t memory_v1; + if (nvmlData.ffnvmlDeviceGetMemoryInfo(device, &memory_v1) == NVML_SUCCESS) + { + result.memory->total = memory_v1.total; + result.memory->used = memory_v1.used; + } + } } if (result.coreCount) diff --git a/src/detection/gpu/nvml.h b/src/detection/gpu/nvml.h index 693f9bff..40ff3a49 100644 --- a/src/detection/gpu/nvml.h +++ b/src/detection/gpu/nvml.h @@ -56,6 +56,18 @@ typedef struct { // https://github.com/NVIDIA/nvidia-settings/issues/78#issuecomment-1012837988 enum { nvmlMemory_v2 = (unsigned int)(sizeof(nvmlMemory_v2_t) | (2 << 24U)) }; +// https://docs.nvidia.com/deploy/nvml-api/structnvmlMemory__t.html#structnvmlMemory__t +// Memory allocation information for a device (v1) +typedef struct +{ + // Total physical device memory (in bytes) + unsigned long long total; + // Unallocated device memory (in bytes) + unsigned long long free; + // Sum of Reserved and Allocated device memory (in bytes) + unsigned long long used; +} nvmlMemory_t; + // https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g805c0647be9996589fc5e3f6ff680c64 // Clock types typedef enum { @@ -124,6 +136,8 @@ extern nvmlReturn_t nvmlDeviceGetPciInfo_v3(nvmlDevice_t device, nvmlPciInfo_t* extern nvmlReturn_t nvmlDeviceGetTemperature(nvmlDevice_t device, nvmlTemperatureSensors_t sensorType, unsigned int* temp); // Retrieves the amount of used, free, reserved and total memory available on the device, in bytes. The reserved amount is supported on version 2 only extern nvmlReturn_t nvmlDeviceGetMemoryInfo_v2(nvmlDevice_t device, nvmlMemory_v2_t* memory); +// Retrieves the amount of used, free, total memory available on the device, in bytes. +extern nvmlReturn_t nvmlDeviceGetMemoryInfo(nvmlDevice_t device, nvmlMemory_t *memory); // Gets the device's core count extern nvmlReturn_t nvmlDeviceGetNumGpuCores(nvmlDevice_t device, unsigned int* numCores); // Retrieves the maximum clock speeds for the device From c3023259e2bbdc92717e58e2263a6eecbead0a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 14:06:06 +0800 Subject: [PATCH 21/44] GPU (macOS): use `recommendedMaxWorkingSetSize` as total GPU mem size Worth noting that the value is static. It won't change even if the free global memory is smaller than the value. --- src/detection/gpu/gpu_apple.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/detection/gpu/gpu_apple.m b/src/detection/gpu/gpu_apple.m index 95e4c305..9334c684 100644 --- a/src/detection/gpu/gpu_apple.m +++ b/src/detection/gpu/gpu_apple.m @@ -68,6 +68,9 @@ const char* ffGpuDetectMetal(FFlist* gpus) gpu->type = device.location == MTLDeviceLocationBuiltIn ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE; gpu->index = (uint32_t) device.locationNumber; #endif + + if (device.hasUnifiedMemory && device.recommendedMaxWorkingSetSize > 0) + gpu->shared.total = device.recommendedMaxWorkingSetSize; } return NULL; } From 63cc8e5523f0b40cfdb20b6a52d6b46f4ad246bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 14:40:49 +0800 Subject: [PATCH 22/44] Camera (macOS): make fastfetch compiled on newer macOS versions runs on older ones --- src/detection/camera/camera_apple.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/detection/camera/camera_apple.m b/src/detection/camera/camera_apple.m index ab15fb99..45da1246 100644 --- a/src/detection/camera/camera_apple.m +++ b/src/detection/camera/camera_apple.m @@ -6,6 +6,11 @@ // warning: 'AVCaptureDeviceTypeExternalUnknown' is deprecated #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#ifdef MAC_OS_VERSION_14_0 +// To make fastfetch compiled on newer macOS versions runs on older ones +AVF_EXPORT __attribute__((weak_import)) AVCaptureDeviceType const AVCaptureDeviceTypeExternal; +#endif + const char* ffDetectCamera(FFlist* result) { #ifdef MAC_OS_X_VERSION_10_15 From 7f212025dea41df2369ed922b46bf27932f653bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 15:36:09 +0800 Subject: [PATCH 23/44] Processing (Unix): better `pipe2(2)` existance check --- CMakeLists.txt | 7 +++++++ src/common/processing_linux.c | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 95d74a2b..103b20b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1182,6 +1182,9 @@ endif() if(LINUX) check_function_exists(statx HAVE_STATX) endif() +if(NOT WIN32) + check_function_exists(pipe2 HAVE_PIPE2) +endif() if(ENABLE_SYSTEM_YYJSON) find_package(yyjson) @@ -1296,6 +1299,10 @@ if(HAVE_WCWIDTH) target_compile_definitions(libfastfetch PUBLIC FF_HAVE_WCWIDTH) endif() +if(HAVE_PIPE2) + target_compile_definitions(libfastfetch PUBLIC FF_HAVE_PIPE2) +endif() + if(NOT "${CUSTOM_PCI_IDS_PATH}" STREQUAL "") message(STATUS "Custom file path of pci.ids: ${CUSTOM_PCI_IDS_PATH}") target_compile_definitions(libfastfetch PRIVATE FF_CUSTOM_PCI_IDS_PATH=${CUSTOM_PCI_IDS_PATH}) diff --git a/src/common/processing_linux.c b/src/common/processing_linux.c index 63d39511..1839a436 100644 --- a/src/common/processing_linux.c +++ b/src/common/processing_linux.c @@ -32,9 +32,9 @@ enum { FF_PIPE_BUFSIZ = 8192 }; -static inline int ffPipe2(int *fds, int flags) +static inline int ffPipe2(int* fds, int flags) { - #ifdef __APPLE__ + #ifndef FF_HAVE_PIPE2 if(pipe(fds) == -1) return -1; fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | flags); From edcd7995e58248f68339a25e3523fa290e39147a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 15:44:03 +0800 Subject: [PATCH 24/44] CMake (Haiku): fix build Ref: https://github.com/fastfetch-cli/fastfetch/pull/1538#issuecomment-2635866129 --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 103b20b1..24824d31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1615,6 +1615,7 @@ elseif(Haiku) target_link_libraries(libfastfetch PRIVATE "network" PRIVATE "be" + PRIVATE "gnu" ) endif() From 5a04a2ecc35f7ed102b8b4e2443805c535e74d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 15:45:34 +0800 Subject: [PATCH 25/44] Doc: update license --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index ac6f147e..3a3b50b1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ MIT License Copyright (c) 2021-2023 Linus Dierheimer -Copyright (c) 2022-2024 Carter Li +Copyright (c) 2022-2025 Carter Li Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 356501270ac7beb2473da283a4d50a739efea4e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 16:10:01 +0800 Subject: [PATCH 26/44] CPU (Linux): detect for `model name` on unknown platform --- src/detection/cpu/cpu_linux.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 8e6030bb..4ff2524d 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -297,30 +297,22 @@ static const char* parseCpuInfo( (cpu->vendor.length == 0 && ffParsePropLine(line, "vendor_id :", &cpu->vendor)) || (physicalCoresBuffer->length == 0 && ffParsePropLine(line, "cpu cores :", physicalCoresBuffer)) || (cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz :", cpuMHz)) || - #endif - - #if __arm__ || __aarch64__ + #elif __arm__ || __aarch64__ (cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) || (cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices - #endif - - #if __powerpc__ || __powerpc + #elif __powerpc__ || __powerpc (cpuMHz->length == 0 && ffParsePropLine(line, "clock :", cpuMHz)) || //For POWER (cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER - #endif - - #if __mips__ || __mips + #elif __mips__ || __mips (cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || //For MIPS - #endif - - #if __loongarch__ + #elif __loongarch__ (cpu->name.length == 0 && ffParsePropLine(line, "Model Name :", &cpu->name)) || (cpuMHz->length == 0 && ffParsePropLine(line, "CPU MHz :", cpuMHz)) || - #endif - - #if __riscv__ || __loongarch__ + #elif __riscv__ || __riscv (cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) || (cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) || + #else + (cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) || #endif false From 8774fb3fb7c9622c3c0b88f2d02dbc601fb09df9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 5 Feb 2025 16:10:42 +0800 Subject: [PATCH 27/44] Shell (OpenBSD): trim `-` for login shells --- src/common/processing_linux.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/common/processing_linux.c b/src/common/processing_linux.c index 1839a436..b865805c 100644 --- a/src/common/processing_linux.c +++ b/src/common/processing_linux.c @@ -301,7 +301,12 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons if (proc) { char** argv = kvm_getargv(kd, proc, 0); - if (argv) ffStrbufSetS(exe, argv[0]); + if (argv) + { + const char* arg0 = argv[0]; + if (arg0[0] == '-') arg0++; + ffStrbufSetS(exe, arg0); + } } kvm_close(kd); From 8f27e4392988b9bbebdbc1cbdc297e2d1d0f1eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Feb 2025 08:43:38 +0800 Subject: [PATCH 28/44] Logo (Builtin): fix color of Haiku in light mode --- src/logo/builtin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 349828a3..7b4f0da4 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2008,7 +2008,7 @@ static const FFlogo H[] = { .colors = { FF_COLOR_FG_RED, FF_COLOR_FG_YELLOW, - FF_COLOR_FG_WHITE, + FF_COLOR_FG_DEFAULT, FF_COLOR_FG_GREEN, }, .colorKeys = FF_COLOR_FG_RED, From 49bb957c864672662d7e4f876a55127461d9e76c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Feb 2025 09:02:07 +0800 Subject: [PATCH 29/44] Logo (Builtin): simplify RebornOS --- src/logo/ascii/{reborn.txt => rebornos.txt} | 0 .../ascii/{reborn_small.txt => rebornos_small.txt} | 0 src/logo/builtin.c | 10 +++++----- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/logo/ascii/{reborn.txt => rebornos.txt} (100%) rename src/logo/ascii/{reborn_small.txt => rebornos_small.txt} (100%) diff --git a/src/logo/ascii/reborn.txt b/src/logo/ascii/rebornos.txt similarity index 100% rename from src/logo/ascii/reborn.txt rename to src/logo/ascii/rebornos.txt diff --git a/src/logo/ascii/reborn_small.txt b/src/logo/ascii/rebornos_small.txt similarity index 100% rename from src/logo/ascii/reborn_small.txt rename to src/logo/ascii/rebornos_small.txt diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 7b4f0da4..604d0767 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -3900,10 +3900,10 @@ static const FFlogo R[] = { FF_COLOR_FG_WHITE, }, }, - // Reborn + // RebornOS { - .names = {"Reborn", "Reborn OS", "reborn-os", "rebornos", "rebornos-linux", "reborn-os-linux"}, - .lines = FASTFETCH_DATATEXT_LOGO_REBORN, + .names = {"RebornOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_REBORNOS, .colors = { FF_COLOR_FG_BLACK, FF_COLOR_FG_BLUE, @@ -3914,9 +3914,9 @@ static const FFlogo R[] = { }, // RebornSmall { - .names = {"Reborn_small", "Reborn OS_small", "reborn-os-small", "rebornos_small", "rebornos-linux-small", "reborn-os-linux-small"}, + .names = {"RebornOS_small"}, .type = FF_LOGO_LINE_TYPE_SMALL_BIT, - .lines = FASTFETCH_DATATEXT_LOGO_REBORN_SMALL, + .lines = FASTFETCH_DATATEXT_LOGO_REBORNOS_SMALL, .colors = { FF_COLOR_FG_BLUE, }, From b3062499f4cdb063ecba990b603d29fafe895997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Feb 2025 10:50:30 +0800 Subject: [PATCH 30/44] Logo (Builtin): update some distro names --- .../ascii/{endeavour.txt => endeavouros.txt} | 0 ...eavour_small.txt => endeavouros_small.txt} | 0 src/logo/builtin.c | 42 +++++++++---------- 3 files changed, 21 insertions(+), 21 deletions(-) rename src/logo/ascii/{endeavour.txt => endeavouros.txt} (100%) rename src/logo/ascii/{endeavour_small.txt => endeavouros_small.txt} (100%) diff --git a/src/logo/ascii/endeavour.txt b/src/logo/ascii/endeavouros.txt similarity index 100% rename from src/logo/ascii/endeavour.txt rename to src/logo/ascii/endeavouros.txt diff --git a/src/logo/ascii/endeavour_small.txt b/src/logo/ascii/endeavouros_small.txt similarity index 100% rename from src/logo/ascii/endeavour_small.txt rename to src/logo/ascii/endeavouros_small.txt diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 604d0767..e94c4073 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1428,10 +1428,10 @@ static const FFlogo E[] = { .colorKeys = FF_COLOR_FG_MAGENTA, .colorTitle = FF_COLOR_FG_GREEN, }, - // Endeavour + // EndeavourOS { - .names = {"Endeavour", "endeavour-linux", "endeavouros", "endeavouros-linux"}, - .lines = FASTFETCH_DATATEXT_LOGO_ENDEAVOUR, + .names = {"EndeavourOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_ENDEAVOUROS, .colors = { FF_COLOR_FG_MAGENTA, FF_COLOR_FG_RED, @@ -1440,11 +1440,11 @@ static const FFlogo E[] = { .colorKeys = FF_COLOR_FG_MAGENTA, .colorTitle = FF_COLOR_FG_RED, }, - // EndeavourSmall + // EndeavourOSSmall { - .names = {"Endeavour_small", "endeavour-linux_small", "endeavouros_small", "endeavouros-linux_small"}, + .names = {"EndeavourOS_small"}, .type = FF_LOGO_LINE_TYPE_SMALL_BIT, - .lines = FASTFETCH_DATATEXT_LOGO_ENDEAVOUR_SMALL, + .lines = FASTFETCH_DATATEXT_LOGO_ENDEAVOUROS_SMALL, .colors = { FF_COLOR_FG_RED, FF_COLOR_FG_MAGENTA, @@ -2570,7 +2570,7 @@ static const FFlogo L[] = { }, // LinuxMintOld { - .names = {"linux-mint_old", "linux-mint-old"}, + .names = {"linuxmint_old", "linux-mint_old"}, .type = FF_LOGO_LINE_TYPE_ALTER_BIT, .lines = FASTFETCH_DATATEXT_LOGO_MINT_OLD, .colors = { @@ -3307,7 +3307,7 @@ static const FFlogo O[] = { }, // OpenSuse { - .names = {"opensuse", "open_suse", "open-suse"}, + .names = {"opensuse"}, .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE, .colors = { FF_COLOR_FG_GREEN, @@ -3318,7 +3318,7 @@ static const FFlogo O[] = { }, // OpenSuseSmall { - .names = {"opensuse_small", "open_suse_small", "open-suse_small"}, + .names = {"opensuse_small"}, .type = FF_LOGO_LINE_TYPE_SMALL_BIT, .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_SMALL, .colors = { @@ -3337,7 +3337,7 @@ static const FFlogo O[] = { }, // OpenSuseLeap { - .names = {"opensuse_leap", "opensuse leap"}, + .names = {"opensuse-leap", "opensuse leap"}, .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_LEAP, .colors = { FF_COLOR_FG_WHITE, @@ -3347,7 +3347,7 @@ static const FFlogo O[] = { }, // OpenSuseLeapOld { - .names = {"opensuse_leap_old", "opensuse leap_old"}, + .names = {"opensuse-leap_old", "opensuse leap_old"}, .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_LEAP_OLD, .type = FF_LOGO_LINE_TYPE_ALTER_BIT, .colors = { @@ -3358,7 +3358,7 @@ static const FFlogo O[] = { }, // OpenSuseTumbleweed { - .names = {"opensuse-tumbleweed", "opensuse_tumbleweed"}, + .names = {"opensuse-tumbleweed"}, .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_TUMBLEWEED, .colors = { FF_COLOR_FG_WHITE, @@ -3368,7 +3368,7 @@ static const FFlogo O[] = { }, // OpenSuseTumbleweedOld { - .names = {"opensuse-tumbleweed-old", "opensuse_tumbleweed-old"}, + .names = {"opensuse-tumbleweed-old"}, .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_TUMBLEWEED_OLD, .type = FF_LOGO_LINE_TYPE_ALTER_BIT, .colors = { @@ -3379,7 +3379,7 @@ static const FFlogo O[] = { }, // openSUSESlowroll { - .names = {"opensuse_slowroll", "opensuse-slowroll", "opensuse-tumbleweed-slowroll"}, + .names = {"opensuse-slowroll", "opensuse-tumbleweed-slowroll"}, .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_SLOWROLL, .colors = { FF_COLOR_FG_WHITE, @@ -3696,7 +3696,7 @@ static const FFlogo P[] = { }, // Pop { - .names = {"pop", "popos", "pop_os", "pop-linux"}, + .names = {"pop", "popos"}, .lines = FASTFETCH_DATATEXT_LOGO_POP, .colors = { FF_COLOR_FG_CYAN, @@ -3707,7 +3707,7 @@ static const FFlogo P[] = { }, // PopSmall { - .names = {"pop_small", "popos_small", "pop_os_small", "pop-linux-small"}, + .names = {"pop_small", "popos_small"}, .type = FF_LOGO_LINE_TYPE_SMALL_BIT, .lines = FASTFETCH_DATATEXT_LOGO_POP_SMALL, .colors = { @@ -3979,7 +3979,7 @@ static const FFlogo R[] = { }, // RedstarOS { - .names = {"redstar", "redstar-os", "redstaros", "redstaros-linux", "redstar-os-linux"}, + .names = {"redstar", "redstar-os", "redstaros"}, .lines = FASTFETCH_DATATEXT_LOGO_REDSTAR, .colors = { FF_COLOR_FG_RED, @@ -4283,7 +4283,7 @@ static const FFlogo S[] = { }, // Slackware { - .names = {"slackware", "slackware-linux", "slackwarelinux"}, + .names = {"Slackware"}, .lines = FASTFETCH_DATATEXT_LOGO_SLACKWARE, .colors = { FF_COLOR_FG_BLUE, @@ -4294,7 +4294,7 @@ static const FFlogo S[] = { }, // SlackwareSmall { - .names = {"slackware-small", "slackware-linux-small", "slackware_small", "slackwarelinux_small"}, + .names = {"Slackware_small"}, .type = FF_LOGO_LINE_TYPE_SMALL_BIT, .lines = FASTFETCH_DATATEXT_LOGO_SLACKWARE_SMALL, .colors = { @@ -4353,7 +4353,7 @@ static const FFlogo S[] = { }, // SolarisSmall { - .names = {"solaris-small", "solaris_small", "sunos-small", "sunos_small"}, + .names = {"solaris_small", "sunos_small"}, .type = FF_LOGO_LINE_TYPE_SMALL_BIT, .lines = FASTFETCH_DATATEXT_LOGO_SOLARIS_SMALL, .colors = { @@ -4364,7 +4364,7 @@ static const FFlogo S[] = { }, // Solus { - .names = {"solus", "solus-linux"}, + .names = {"Solus", "solus-linux"}, .lines = FASTFETCH_DATATEXT_LOGO_SOLUS, .colors = { FF_COLOR_FG_BLUE, From 1d21d0287858d328b2ba7cceb0bed457ce3ade1b Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 7 Feb 2025 10:02:26 +0800 Subject: [PATCH 31/44] CPU (Linux): support physical core count and package count detection on loongarch --- src/detection/cpu/cpu_linux.c | 38 +++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 4ff2524d..cca85815 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -10,6 +10,8 @@ #include #include +#define FF_CPUINFO_PATH "/proc/cpuinfo" + static double parseHwmonDir(FFstrbuf* dir, FFstrbuf* buffer) { //https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface @@ -437,8 +439,8 @@ FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo) FF_MAYBE_UNUSED static const char* detectCPUX86(const FFCPUOptions* options, FFCPUResult* cpu) { FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ); - if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0) - return "ffReadFileBuffer(\"/proc/cpuinfo\") failed"; + if (!ffReadFileBuffer(FF_CPUINFO_PATH, &cpuinfo) || cpuinfo.length == 0) + return "ffReadFileBuffer(\"" FF_CPUINFO_PATH "\") failed"; FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate(); FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate(); @@ -567,6 +569,30 @@ FF_MAYBE_UNUSED static void detectSocName(FFCPUResult* cpu) } } +#ifdef __loongarch__ +FF_MAYBE_UNUSED static uint16_t getLoongarchPropCount(FFstrbuf* cpuinfo, const char* key) +{ + const char* p = cpuinfo->chars; + uint64_t low = 0, high = 0; + uint32_t keylen = (uint32_t) strlen(key); + + while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), key, keylen))) + { + if (!p) break; + p += keylen; + char* pend; + unsigned long id = strtoul(p, &pend, 10); + if (__builtin_expect(id > 64, false)) + high |= 1 << (id - 64); + else + low |= 1 << id; + p = pend; + } + + return (uint16_t) (__builtin_popcountll(low) + __builtin_popcountll(high)); +} +#endif + FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, FFCPUResult* cpu) { cpu->coresPhysical = cpu->coresLogical = (uint16_t) get_nprocs_conf(); @@ -583,8 +609,8 @@ FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, if (cpu->name.length == 0) { FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ); - if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0) - return "ffReadFileBuffer(\"/proc/cpuinfo\") failed"; + if (!ffReadFileBuffer(FF_CPUINFO_PATH, &cpuinfo) || cpuinfo.length == 0) + return "ffReadFileBuffer(\"" FF_CPUINFO_PATH "\") failed"; FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate(); FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate(); @@ -621,6 +647,10 @@ FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, ffStrbufAppend(&cpu->name, &cpuIsa); } } + #elif __loongarch__ + cpu->packages = getLoongarchPropCount(&cpuinfo, "\npackage\t\t\t:"); + cpu->coresPhysical = getLoongarchPropCount(&cpuinfo, "\ncore\t\t\t:"); + if (cpu->packages > 1) cpu->coresPhysical *= cpu->packages; #endif } From f2755a844bac2c2f62e82c36e5da6ae51527e9dd Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 7 Feb 2025 10:57:30 +0800 Subject: [PATCH 32/44] Logo (Builtin): split `ID_LIKE` before using Fix #1540 --- src/logo/logo.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/logo/logo.c b/src/logo/logo.c index c1c2b38d..8e95f862 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -387,13 +387,30 @@ static const FFlogo* logoGetBuiltinDetected(FFLogoSize size) if(logo != NULL) return logo; - logo = logoGetBuiltin(&os->prettyName, size); - if(logo != NULL) - return logo; + if (ffStrbufContainC(&os->idLike, ' ')) + { + FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate(); + for ( + uint32_t start = 0, end = ffStrbufFirstIndexC(&os->idLike, ' '); + true; + start = end + 1, end = ffStrbufNextIndexC(&os->idLike, start, ' ') + ) + { + ffStrbufSetNS(&buf, end - start, os->idLike.chars + start); + logo = logoGetBuiltin(&buf, size); + if(logo != NULL) + return logo; - logo = logoGetBuiltin(&os->idLike, size); - if(logo != NULL) - return logo; + if (end >= os->idLike.length) + break; + } + } + else + { + logo = logoGetBuiltin(&os->idLike, size); + if(logo != NULL) + return logo; + } logo = logoGetBuiltin(&instance.state.platform.sysinfo.name, size); if(logo != NULL) From 292fa0686fa96c2330114c4d375598f2ce97b29f Mon Sep 17 00:00:00 2001 From: Ng Zhun Onn <43035773+zhon12345@users.noreply.github.com> Date: Fri, 7 Feb 2025 21:48:31 +0800 Subject: [PATCH 33/44] Display: capitalize `{type}`'s output (#1543) * Display: capitalize {type}'s output * Update display.c * Update json_schema.json --------- Co-authored-by: Carter Li --- doc/json_schema.json | 2 +- src/modules/display/display.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/json_schema.json b/doc/json_schema.json index 05b27b9f..61308e83 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -179,7 +179,7 @@ "type": "string" }, "displayFormat": { - "description": "Output format of the module `Display`. See `-h format` for formatting syntax\n 1. {width}: Screen configured width (in pixels)\n 2. {height}: Screen configured height (in pixels)\n 3. {refresh-rate}: Screen configured refresh rate (in Hz)\n 4. {scaled-width}: Screen scaled width (in pixels)\n 5. {scaled-height}: Screen scaled height (in pixels)\n 6. {name}: Screen name\n 7. {type}: Screen type (builtin, external or unknown)\n 8. {rotation}: Screen rotation (in degrees)\n 9. {is-primary}: True if being the primary screen\n 10. {physical-width}: Screen physical width (in millimeters)\n 11. {physical-height}: Screen physical height (in millimeters)\n 12. {inch}: Physical diagonal length in inches\n 13. {ppi}: Pixels per inch (PPI)\n 14. {bit-depth}: Bits per color channel\n 15. {hdr-enabled}: True if high dynamic range (HDR) mode is enabled\n 16. {manufacture-year}: Year of manufacturing\n 17. {manufacture-week}: Nth week of manufacturing in the year\n 18. {serial}: Serial number\n 19. {platform-api}: The platform API used when detecting the display\n 20. {hdr-compatible}: True if the display is HDR compatible\n 21. {scale-factor}: HiDPI scale factor\n 22. {preferred-width}: Screen preferred width (in pixels)\n 23. {preferred-height}: Screen preferred height (in pixels)\n 24. {preferred-refresh-rate}: Screen preferred refresh rate (in Hz)", + "description": "Output format of the module `Display`. See `-h format` for formatting syntax\n 1. {width}: Screen configured width (in pixels)\n 2. {height}: Screen configured height (in pixels)\n 3. {refresh-rate}: Screen configured refresh rate (in Hz)\n 4. {scaled-width}: Screen scaled width (in pixels)\n 5. {scaled-height}: Screen scaled height (in pixels)\n 6. {name}: Screen name\n 7. {type}: Screen type (Built-in or External)\n 8. {rotation}: Screen rotation (in degrees)\n 9. {is-primary}: True if being the primary screen\n 10. {physical-width}: Screen physical width (in millimeters)\n 11. {physical-height}: Screen physical height (in millimeters)\n 12. {inch}: Physical diagonal length in inches\n 13. {ppi}: Pixels per inch (PPI)\n 14. {bit-depth}: Bits per color channel\n 15. {hdr-enabled}: True if high dynamic range (HDR) mode is enabled\n 16. {manufacture-year}: Year of manufacturing\n 17. {manufacture-week}: Nth week of manufacturing in the year\n 18. {serial}: Serial number\n 19. {platform-api}: The platform API used when detecting the display\n 20. {hdr-compatible}: True if the display is HDR compatible\n 21. {scale-factor}: HiDPI scale factor\n 22. {preferred-width}: Screen preferred width (in pixels)\n 23. {preferred-height}: Screen preferred height (in pixels)\n 24. {preferred-refresh-rate}: Screen preferred refresh rate (in Hz)", "type": "string" }, "diskFormat": { diff --git a/src/modules/display/display.c b/src/modules/display/display.c index fdf42768..604f1761 100644 --- a/src/modules/display/display.c +++ b/src/modules/display/display.c @@ -75,7 +75,7 @@ void ffPrintDisplay(FFDisplayOptions* options) { FFDisplayResult* result = FF_LIST_GET(FFDisplayResult, dsResult->displays, i); uint32_t moduleIndex = dsResult->displays.length == 1 ? 0 : i + 1; - const char* displayType = result->type == FF_DISPLAY_TYPE_UNKNOWN ? NULL : result->type == FF_DISPLAY_TYPE_BUILTIN ? "built-in" : "external"; + const char* displayType = result->type == FF_DISPLAY_TYPE_UNKNOWN ? NULL : result->type == FF_DISPLAY_TYPE_BUILTIN ? "Built-in" : "External"; ffStrbufClear(&key); if(options->moduleArgs.key.length == 0) @@ -448,7 +448,7 @@ static FFModuleBaseInfo ffModuleInfo = { {"Screen scaled width (in pixels)", "scaled-width"}, {"Screen scaled height (in pixels)", "scaled-height"}, {"Screen name", "name"}, - {"Screen type (builtin, external or unknown)", "type"}, + {"Screen type (Built-in or External)", "type"}, {"Screen rotation (in degrees)", "rotation"}, {"True if being the primary screen", "is-primary"}, {"Screen physical width (in millimeters)", "physical-width"}, From 263d2902dd0d7c31e991d0a2173cf4bc6889966c Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 8 Feb 2025 10:31:06 +0800 Subject: [PATCH 34/44] CPU (Linux): add cpu name detection for s390x --- src/detection/cpu/cpu_linux.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index cca85815..9a53a933 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -313,6 +313,10 @@ static const char* parseCpuInfo( #elif __riscv__ || __riscv (cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) || (cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) || + #elif __s390x__ + (cpu->name.length == 0 && ffParsePropLine(line, "processor 0:", &cpu->name)) || + (cpu->vendor.length == 0 && ffParsePropLine(line, "vendor_id :", &cpu->vendor)) || + (cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz static :", cpuMHz)) || // This one cannot be detected because of early return #else (cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) || #endif @@ -651,6 +655,9 @@ FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, cpu->packages = getLoongarchPropCount(&cpuinfo, "\npackage\t\t\t:"); cpu->coresPhysical = getLoongarchPropCount(&cpuinfo, "\ncore\t\t\t:"); if (cpu->packages > 1) cpu->coresPhysical *= cpu->packages; + #elif __s390x__ + if (ffStrbufSubstrAfterFirstS(&cpu->name, "machine = ")) + ffStrbufPrependS(&cpu->name, "Machine "); #endif } From 99e8d1f2bb09b98291a6cf1a345a29e0c4488043 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 8 Feb 2025 10:38:13 +0800 Subject: [PATCH 35/44] CPU (Linux): loosely detect cpu name of unknown platform --- src/detection/cpu/cpu_linux.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 9a53a933..a6214181 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -303,10 +303,10 @@ static const char* parseCpuInfo( (cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) || (cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices #elif __powerpc__ || __powerpc - (cpuMHz->length == 0 && ffParsePropLine(line, "clock :", cpuMHz)) || //For POWER - (cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER + (cpuMHz->length == 0 && ffParsePropLine(line, "clock :", cpuMHz)) || + (cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || #elif __mips__ || __mips - (cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || //For MIPS + (cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || #elif __loongarch__ (cpu->name.length == 0 && ffParsePropLine(line, "Model Name :", &cpu->name)) || (cpuMHz->length == 0 && ffParsePropLine(line, "CPU MHz :", cpuMHz)) || @@ -319,6 +319,10 @@ static const char* parseCpuInfo( (cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz static :", cpuMHz)) || // This one cannot be detected because of early return #else (cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) || + (cpu->name.length == 0 && ffParsePropLine(line, "model :", &cpu->name)) || + (cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || + (cpu->name.length == 0 && ffParsePropLine(line, "hardware :", &cpu->name)) || + (cpu->name.length == 0 && ffParsePropLine(line, "processor :", &cpu->name)) || #endif false From a0163979615644a8cd2b0d040ec718fe9358e7ff Mon Sep 17 00:00:00 2001 From: JohnTheCoolingFan <43478602+JohnTheCoolingFan@users.noreply.github.com> Date: Sat, 8 Feb 2025 09:54:04 +0300 Subject: [PATCH 36/44] OS (Linux): combine all armbian variants (#1547) --- src/detection/os/os_linux.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/detection/os/os_linux.c b/src/detection/os/os_linux.c index 65e5670a..487c651a 100644 --- a/src/detection/os/os_linux.c +++ b/src/detection/os/os_linux.c @@ -41,10 +41,13 @@ static bool parseOsRelease(const char* fileName, FFOSResult* result) // Common logic for detecting Armbian image version FF_MAYBE_UNUSED static bool detectArmbianVersion(FFOSResult* result) { - if (ffStrbufStartsWithS(&result->prettyName, "Armbian ")) // Official Armbian release images + // Possible values `PRETTY_NAME` starts with on Armbian: + // - `Armbian` for official releases + // - `Armbian_community` for community releases + // - `Armbian_Security` for images with kali repo added + // - `Armbian-unofficial` for an unofficial image built from source, e.g. during development and testing + if (ffStrbufStartsWithS(&result->prettyName, "Armbian")) ffStrbufSetS(&result->name, "Armbian"); - else if (ffStrbufStartsWithS(&result->prettyName, "Armbian-unofficial ")) // Unofficial Armbian image built from source - ffStrbufSetS(&result->name, "Armbian (custom build)"); else return false; ffStrbufSet(&result->idLike, &result->id); From e021cfe77a5576cf9c93f1c17b5cb14781b5b57a Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 8 Feb 2025 11:03:07 +0800 Subject: [PATCH 37/44] Doc: update changelog [ci skip] --- CHANGELOG.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c978cb5..760e5cbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,28 @@ +# 2.36.0 + +Bugfixes: +* Trim leading slash for login shells (Shell, OpenBSD) +* Prefer SOC name if available over CPU name (CPU, Linux) + +Features: +* Use kernel API to detect sound devices (Sound, NetBSD) +* Use sndio for sound server detection on OpenBSD (Sound, OpenBSD) +* Add minimal implementation for Haiku (#1538, Haiku) +* Support CPU & GPU temperature detection for M4x (CPU / GPU, macOS) +* Support VMEM size detection for old Nvidia cards (GPU, Linux) +* Use [recommendedMaxWorkingSetSize](https://developer.apple.com/documentation/metal/mtldevice/recommendedmaxworkingsetsize) as total GPU mem size (GPU, macOS) +* Support Physical core count and CPU package count detection for loongarch (CPU, Linux) +* Split ID_LIKE when used for distro matching (#1540, Logo) +* Capitalize `{type}`'s first letter in custom format (#1543, Display) +* Support model name detection for s390x (CPU, Linux) +* Support more Armbian variants detection (#1547, OS, Linux) + +Logo: +* Update arch_old +* Add Nexa Linux +* Add filotimo +* Update some distro names + # 2.35.0 Bugfixes: From 486ade0e71e4136fc3c402363063a957d7fe28dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 8 Feb 2025 16:43:56 +0800 Subject: [PATCH 38/44] Logo (Builtin): KDE -> KDE Neon --- src/logo/ascii/{kde.txt => kdeneon.txt} | 0 src/logo/builtin.c | 7 ++++--- 2 files changed, 4 insertions(+), 3 deletions(-) rename src/logo/ascii/{kde.txt => kdeneon.txt} (100%) diff --git a/src/logo/ascii/kde.txt b/src/logo/ascii/kdeneon.txt similarity index 100% rename from src/logo/ascii/kde.txt rename to src/logo/ascii/kdeneon.txt diff --git a/src/logo/builtin.c b/src/logo/builtin.c index e94c4073..f847c230 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2304,12 +2304,13 @@ static const FFlogo K[] = { FF_COLOR_FG_WHITE } }, - // KDENeon + // KDE Neon { - .names = {"KDE", "kde-neon", "kde neon"}, - .lines = FASTFETCH_DATATEXT_LOGO_KDE, + .names = {"KDE Neon"}, // Distro ID is `neon`; Distro name is `KDE Neon` + .lines = FASTFETCH_DATATEXT_LOGO_KDENEON, .colors = { FF_COLOR_FG_GREEN, + FF_COLOR_FG_DEFAULT, }, }, // Kibojoe From 016b1e6961f475852a6a7cb0ef1ab7d722845893 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 8 Feb 2025 22:11:41 +0800 Subject: [PATCH 39/44] Format: support syntax of `{$ENV_VAR}` in custom format Fix #1541 --- .github/workflows/ci.yml | 30 +++++++++++++++--------------- CHANGELOG.md | 2 ++ src/common/format.c | 31 ++++++++++++++++++++----------- src/data/help_format.txt | 2 ++ tests/format.c | 22 ++++++++++++++++++++++ 5 files changed, 61 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f3879ba..f3df5753 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: run: ldd fastfetch - name: run tests - run: ctest + run: ctest --output-on-failure linux-amd64: name: Linux-amd64 @@ -111,7 +111,7 @@ jobs: run: ldd fastfetch - name: run tests - run: ctest + run: ctest --output-on-failure - name: get fastfetch version id: ffversion @@ -150,7 +150,7 @@ jobs: time ./fastfetch -c presets/ci.jsonc --format json time ./flashfetch ldd fastfetch - ctest + ctest --output-on-failure - name: upload artifacts uses: actions/upload-artifact@v4 @@ -189,7 +189,7 @@ jobs: time ./fastfetch -c presets/ci.jsonc --format json time ./flashfetch ldd fastfetch - ctest + ctest --output-on-failure - name: upload artifacts uses: actions/upload-artifact@v4 @@ -225,7 +225,7 @@ jobs: time ./fastfetch -c presets/ci.jsonc --format json time ./flashfetch ldd fastfetch - ctest + ctest --output-on-failure - name: upload artifacts uses: actions/upload-artifact@v4 @@ -260,7 +260,7 @@ jobs: time ./fastfetch -c presets/ci.jsonc --format json time ./flashfetch ldd fastfetch - ctest + ctest --output-on-failure - name: upload artifacts uses: actions/upload-artifact@v4 @@ -295,7 +295,7 @@ jobs: time ./fastfetch -c presets/ci.jsonc --format json time ./flashfetch ldd fastfetch - ctest + ctest --output-on-failure - name: upload artifacts uses: actions/upload-artifact@v4 @@ -334,7 +334,7 @@ jobs: time ./fastfetch -c presets/ci.jsonc --format json time ./flashfetch ldd fastfetch - ctest + ctest --output-on-failure shell: alpine.sh {0} - name: upload artifacts @@ -390,7 +390,7 @@ jobs: run: otool -L fastfetch - name: run tests - run: ctest + run: ctest --output-on-failure - name: upload artifacts uses: actions/upload-artifact@v4 @@ -422,7 +422,7 @@ jobs: time ./fastfetch -c presets/ci.jsonc --format json time ./flashfetch ldd fastfetch - ctest + ctest --output-on-failure cpack - name: upload artifacts @@ -460,7 +460,7 @@ jobs: time ./fastfetch -c presets/ci.jsonc --format json time ./flashfetch ldd fastfetch - ctest + ctest --output-on-failure - name: upload artifacts uses: actions/upload-artifact@v4 @@ -495,7 +495,7 @@ jobs: time ./fastfetch -c presets/ci.jsonc --format json time ./flashfetch ldd fastfetch - ctest + ctest --output-on-failure - name: upload artifacts uses: actions/upload-artifact@v4 @@ -531,7 +531,7 @@ jobs: time ./fastfetch -c presets/ci.jsonc --format json time ./flashfetch ldd fastfetch - ctest + ctest --output-on-failure - name: upload artifacts uses: actions/upload-artifact@v4 @@ -567,7 +567,7 @@ jobs: time ./fastfetch -c presets/ci.jsonc --format json time ./flashfetch ldd fastfetch - ctest + ctest --output-on-failure - name: upload artifacts uses: actions/upload-artifact@v4 @@ -626,7 +626,7 @@ jobs: run: ldd fastfetch - name: run tests - run: ctest + run: ctest --output-on-failure - name: create zip archive run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets diff --git a/CHANGELOG.md b/CHANGELOG.md index 760e5cbc..d7ba9f4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ Features: * Capitalize `{type}`'s first letter in custom format (#1543, Display) * Support model name detection for s390x (CPU, Linux) * Support more Armbian variants detection (#1547, OS, Linux) +* Support the syntax of `{$ENV_VAR}` in custom format, which will be replaced by the value of the environment variable `ENV_VAR` (#1541) + * This is another way to pass 3rd-party data to fastfetch besides `Custom` module. Logo: * Update arch_old diff --git a/src/common/format.c b/src/common/format.c index 19564a3f..204c1d8d 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -259,24 +259,33 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n continue; } - //test for constant, if so evaluate it + //test for constant or env var, if so evaluate it if (firstChar == '$') { char* pend = NULL; int32_t indexSigned = (int32_t) strtol(placeholderValue.chars + 1, &pend, 10); - uint32_t index = (uint32_t) indexSigned; - bool backward = indexSigned < 0; - - if (indexSigned == 0 || *pend != '\0' || instance.config.display.constants.length < index) + if (pend == placeholderValue.chars + 1) { - appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length); - continue; + // treat placeholder as an environment variable + char* envValue = getenv(placeholderValue.chars + 1); + if (envValue) + ffStrbufAppendS(buffer, envValue); + else + appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length); } + else + { + // treat placeholder as a constant + uint32_t index = (uint32_t) (indexSigned < 0 ? (int32_t) instance.config.display.constants.length + indexSigned : indexSigned - 1); - FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, backward - ? instance.config.display.constants.length - index - : index - 1); - ffStrbufAppend(buffer, item); + if (*pend != '\0' || instance.config.display.constants.length <= index) + appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length); + else + { + FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, index); + ffStrbufAppend(buffer, item); + } + } continue; } diff --git a/src/data/help_format.txt b/src/data/help_format.txt index 0c77ba86..5a66086e 100644 --- a/src/data/help_format.txt +++ b/src/data/help_format.txt @@ -21,6 +21,8 @@ In 2.24.0 or newer, `{~startIndex,endIndex}` can be specified to slice a string. If an index is omitted, 0 is used. For example, both `{~,0}` `{~0,}` and `{~,}` are same as `{~0,0}` and will always generate a empty string. If `,endIndex` is omitted or greater than the length of the string, the length of string is used. +In 2.36.0 or newer, `{$NUM}` can be specified to reference a constant defined in `display.constants`. `{$ENV_VAR}` can be specified to reference an environment variable. + If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index. This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})". Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again. diff --git a/tests/format.c b/tests/format.c index 6b7d0a72..0e94cec8 100644 --- a/tests/format.c +++ b/tests/format.c @@ -2,6 +2,8 @@ #include "util/textModifier.h" #include "fastfetch.h" +#include + static void verify(const char* format, const char* arg, const char* expected, int lineNo) { FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate(); @@ -113,6 +115,26 @@ int main(void) VERIFY("output({?1}OK{?}{/1}NOT OK{/})", "", "output(NOT OK)"); } + #ifndef _WIN32 // Windows doesn't have setenv + { + ffListInit(&instance.config.display.constants, sizeof(FFstrbuf)); + ffStrbufInitStatic(ffListAdd(&instance.config.display.constants), "CONST1"); + ffStrbufInitStatic(ffListAdd(&instance.config.display.constants), "CONST2"); + setenv("FF_TEST", "ENVVAR", 1); + VERIFY("output({$FF_TEST})", "", "output(ENVVAR)"); + VERIFY("output({$1})", "", "output(CONST1)"); + VERIFY("output({$FF_TEST}{$1})", "", "output(ENVVARCONST1)"); + VERIFY("output({$1}{$FF_TEST})", "", "output(CONST1ENVVAR)"); + VERIFY("output({$FF_TEST}{$FF_TEST})", "", "output(ENVVARENVVAR)"); + VERIFY("output({$1}{$-1})", "", "output(CONST1CONST2)"); + + VERIFY("output({$FF_INVAL})", "", "output({$FF_INVAL})"); + VERIFY("output({$9}{$0}${-9})", "", "output({$9}{$0}${-9})"); + VERIFY("output({$1NO})", "", "output({$1NO})"); + ffListDestroy(&instance.config.display.constants); + } + #endif + //Success puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET); } From 5957831f3f2eb1e1193fdbe4abece93d012781d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Feb 2025 19:17:02 +0800 Subject: [PATCH 40/44] OpenGL (Haiku): enable support --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24824d31..d3bd3e99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,8 +72,8 @@ cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR F cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR SunOS" OFF) cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF) cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF) -cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR WIN32 OR SunOS" OFF) -cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS" OFF) +cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR WIN32 OR SunOS OR Haiku" OFF) +cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR Haiku" OFF) cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF) cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS" OFF) cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) From 339e08fef146a5596bd724ee5e5f8e2f4d07d6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 9 Feb 2025 19:17:44 +0800 Subject: [PATCH 41/44] Release: v2.36.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d3bd3e99..426cd0e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url project(fastfetch - VERSION 2.35.0 + VERSION 2.36.0 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch" From 85ed4b136fd52596e4eefa3f72f92e8e832c75c4 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 10 Feb 2025 09:14:24 +0800 Subject: [PATCH 42/44] Terminal (Linux): improve performance of Tilix version detection Fix #1550 --- CHANGELOG.md | 1 + src/detection/terminalshell/terminalshell.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ba9f4b..68385e81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Features: * Support more Armbian variants detection (#1547, OS, Linux) * Support the syntax of `{$ENV_VAR}` in custom format, which will be replaced by the value of the environment variable `ENV_VAR` (#1541) * This is another way to pass 3rd-party data to fastfetch besides `Custom` module. +* Improve performance of Tilix version detection (Terminal, Linux) Logo: * Update arch_old diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index f2990272..21c11448 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -669,6 +669,12 @@ FF_MAYBE_UNUSED static bool getTerminalVersionPtyxis(FF_MAYBE_UNUSED FFstrbuf* e FF_MAYBE_UNUSED static bool getTerminalVersionTilix(FFstrbuf* exe, FFstrbuf* version) { + if (exe->chars[0] == '/') + { + ffBinaryExtractStrings(exe->chars, extractGeneralVersion, version, (uint32_t) strlen("0.0.0")); + if (version->length) return true; + } + if(ffProcessAppendStdOut(version, (char* const[]) { exe->chars, "--version", From 1eef6f837bb3061897d0971e0eb182b8f7e0d857 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 10 Feb 2025 09:25:10 +0800 Subject: [PATCH 43/44] CPU: remove useless `w/ Radeon 780M Graphics` --- src/detection/cpu/cpu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/detection/cpu/cpu.c b/src/detection/cpu/cpu.c index 2b9d41dc..40ae66ac 100644 --- a/src/detection/cpu/cpu.c +++ b/src/detection/cpu/cpu.c @@ -10,10 +10,14 @@ const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu) const char* removeStrings[] = { " CPU", " FPU", " APU", " Processor", " Dual-Core", " Quad-Core", " Six-Core", " Eight-Core", " Ten-Core", - " 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core", - " with Radeon Graphics" + " 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core" }; ffStrbufRemoveStrings(&cpu->name, ARRAY_SIZE(removeStrings), removeStrings); + uint32_t radeonGraphics = ffStrbufFirstIndexS(&cpu->name, " w/ Radeon "); // w/ Radeon 780M Graphics + if (radeonGraphics >= cpu->name.length) + radeonGraphics = ffStrbufFirstIndexS(&cpu->name, " with Radeon "); + if (radeonGraphics < cpu->name.length) + ffStrbufSubstrBefore(&cpu->name, radeonGraphics); ffStrbufSubstrBeforeFirstC(&cpu->name, '@'); //Cut the speed output in the name as we append our own ffStrbufTrimRight(&cpu->name, ' '); //If we removed the @ in previous step there was most likely a space before it ffStrbufRemoveDupWhitespaces(&cpu->name); From 3bc6be91398bbd89ec4dcb43d8c3c3e429ac1f3d Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 10 Feb 2025 09:32:31 +0800 Subject: [PATCH 44/44] CI: add linux-s390x --- .github/workflows/ci.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3df5753..89afea2e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -303,6 +303,41 @@ jobs: name: fastfetch-linux-ppc64le path: ./fastfetch-*.* + linux-s390x: + name: Linux-s390x + runs-on: ubuntu-22.04 + permissions: + security-events: write + contents: read + steps: + - name: checkout repository + uses: actions/checkout@v4 + + - name: run VM + uses: uraimo/run-on-arch-action@v2 + id: runcmd + with: + arch: s390x + distro: ubuntu20.04 + githubToken: ${{ github.token }} + run: | + uname -a + apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm + cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . + cmake --build . --target package --verbose -j4 + ./fastfetch --list-features + time ./fastfetch -c presets/ci.jsonc --stat false + time ./fastfetch -c presets/ci.jsonc --format json + time ./flashfetch + ldd fastfetch + ctest --output-on-failure + + - name: upload artifacts + uses: actions/upload-artifact@v4 + with: + name: fastfetch-linux-s390x + path: ./fastfetch-*.* + musl-amd64: name: Musl-amd64 runs-on: ubuntu-latest @@ -651,6 +686,7 @@ jobs: - linux-armv6 - linux-riscv64 - linux-ppc64le + - linux-s390x - musl-amd64 - macos-universal - freebsd-amd64