From 1d6fefd40be3354bb176a15d75ed198b492751f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 21 Sep 2022 10:47:15 +0800 Subject: [PATCH 1/7] CpuUsage: support macOS --- CMakeLists.txt | 3 ++ src/detection/cpuUsage/cpuUsage.h | 8 +++++ src/detection/cpuUsage/cpuUsage_apple.c | 46 +++++++++++++++++++++++++ src/detection/cpuUsage/cpuUsage_linux.c | 46 +++++++++++++++++++++++++ src/modules/cpuUsage.c | 30 ++++------------ 5 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 src/detection/cpuUsage/cpuUsage.h create mode 100644 src/detection/cpuUsage/cpuUsage_apple.c create mode 100644 src/detection/cpuUsage/cpuUsage_linux.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 037e9dfd9c..f3c96e9b50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,6 +256,7 @@ endif() if(LINUX OR BSD) list(APPEND LIBFASTFETCH_SRC + src/detection/cpuUsage/cpuUsage_linux.c src/detection/host/host_linux.c src/detection/os/os_linux.c src/detection/gpu/gpu_linux.c @@ -272,6 +273,7 @@ endif() if(APPLE) list(APPEND LIBFASTFETCH_SRC + src/detection/cpuUsage/cpuUsage_apple.c src/util/apple/cf_helpers.c src/util/apple/osascript.m src/detection/host/host_apple.c @@ -295,6 +297,7 @@ endif() if(ANDROID) list(APPEND LIBFASTFETCH_SRC + src/detection/cpuUsage/cpuUsage_linux.c src/detection/host/host_android.c src/detection/os/os_android.c src/detection/gpu/gpu_android.c diff --git a/src/detection/cpuUsage/cpuUsage.h b/src/detection/cpuUsage/cpuUsage.h new file mode 100644 index 0000000000..577d2a3746 --- /dev/null +++ b/src/detection/cpuUsage/cpuUsage.h @@ -0,0 +1,8 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_cpu_cpuUsage +#define FF_INCLUDED_detection_cpu_cpuUsage + +const char* ffGetCpuUsagePercent(double* result); + +#endif diff --git a/src/detection/cpuUsage/cpuUsage_apple.c b/src/detection/cpuUsage/cpuUsage_apple.c new file mode 100644 index 0000000000..49f1d34c88 --- /dev/null +++ b/src/detection/cpuUsage/cpuUsage_apple.c @@ -0,0 +1,46 @@ +#include "fastfetch.h" +#include "cpuUsage.h" + +#include +#include +#include + +static const char* getCpuUsageInfo(long* inUseAll, long* totalAll) +{ + natural_t numCPUs = 0U; + processor_info_array_t cpuInfo; + mach_msg_type_number_t numCpuInfo; + + if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numCPUs, &cpuInfo, &numCpuInfo) != KERN_SUCCESS) + return "host_processor_info() failed"; + if (numCPUs * CPU_STATE_MAX != numCpuInfo) + return "Unexpected host_processor_info() result"; + + for (natural_t i = 0U; i < numCPUs; ++i) { + integer_t inUse = cpuInfo[CPU_STATE_MAX * i + CPU_STATE_USER] + + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_SYSTEM] + + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_NICE]; + integer_t total = inUse + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_IDLE]; + *inUseAll += inUse; + *totalAll += total; + } + return NULL; +} + +const char* ffGetCpuUsagePercent(double* result) +{ + long inUseAll1 = 0, totalAll1 = 0; + const char* error = getCpuUsageInfo(&inUseAll1, &totalAll1); + if(error) + return error; + + sleep(1); + + long inUseAll2 = 0, totalAll2 = 0; + error = getCpuUsageInfo(&inUseAll2, &totalAll2); + if(error) + return error; + + *result = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100; + return NULL; +} diff --git a/src/detection/cpuUsage/cpuUsage_linux.c b/src/detection/cpuUsage/cpuUsage_linux.c new file mode 100644 index 0000000000..499759a822 --- /dev/null +++ b/src/detection/cpuUsage/cpuUsage_linux.c @@ -0,0 +1,46 @@ +#include "fastfetch.h" +#include "cpuUsage.h" + +#include +#include + +static const char* getCpuUsageInfo(FILE* procStat, long* inUseAll, long* totalAll) +{ + long user, nice, system, idle, iowait, irq, softirq; + + if (fscanf(procStat, "cpu%ld%ld%ld%ld%ld%ld%ld", &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0) + { + fclose(procStat); + return "fscanf() failed"; + } + *inUseAll = user + nice + system; + *totalAll = *inUseAll + idle + iowait + irq + softirq; + return NULL; +} + +const char* ffGetCpuUsagePercent(double* result) +{ + FILE* procStat = fopen("/proc/stat", "r"); + if(procStat == NULL) + return "fopen(\"""/proc/stat\", \"r\") == NULL"; + + const char* error = NULL; + long inUseAll1 = 0, totalAll1 = 0; + error = getCpuUsageInfo(procStat, &inUseAll1, &totalAll1); + if(error) + goto exit; + + sleep(1); + rewind(procStat); + + long inUseAll2 = 0, totalAll2 = 0; + error = getCpuUsageInfo(procStat, &inUseAll2, &totalAll2); + if(error) + goto exit; + + *result = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100; + +exit: + fclose(procStat); + return error; +} diff --git a/src/modules/cpuUsage.c b/src/modules/cpuUsage.c index c4b56873dd..fe655af990 100644 --- a/src/modules/cpuUsage.c +++ b/src/modules/cpuUsage.c @@ -1,35 +1,20 @@ #include "fastfetch.h" #include "common/printing.h" - -#include +#include "detection/cpuUsage/cpuUsage.h" #define FF_CPU_USAGE_MODULE_NAME "CPU Usage" #define FF_CPU_USAGE_NUM_FORMAT_ARGS 1 void ffPrintCPUUsage(FFinstance* instance) { - long user, nice, system, idle, iowait, irq, softirq; - FILE* procStat = fopen("/proc/stat", "r"); - if(procStat == NULL) + double cpuPercent = 0; + const char* error = ffGetCpuUsagePercent(&cpuPercent); + + if(error) { - ffPrintError(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpu, "fopen(\"""/proc/stat\", \"r\") == NULL"); + ffPrintError(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpu, "%s", error); return; } - if (fscanf(procStat, "cpu%ld%ld%ld%ld%ld%ld%ld", &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0) goto exit; - long workJiffies1 = user + nice + system; - long totalJiffies1 = workJiffies1 + idle + iowait + irq + softirq; - - sleep(1); - - rewind(procStat); - if (fscanf(procStat, "cpu%ld%ld%ld%ld%ld%ld%ld", &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0) goto exit; - long workJiffies2 = user + nice + system; - long totalJiffies2 = workJiffies2 + idle + iowait + irq + softirq; - - // https://stackoverflow.com/questions/3017162/how-to-get-total-cpu-usage-in-linux-using-c#answer-3017438 - long workOverPeriod = workJiffies2 - workJiffies1; - long totalOverPeriod = totalJiffies2 - totalJiffies1; - double cpuPercent = (double)workOverPeriod / (double)totalOverPeriod * 100; if(instance->config.cpuUsage.outputFormat.length == 0) { @@ -43,7 +28,4 @@ void ffPrintCPUUsage(FFinstance* instance) {FF_FORMAT_ARG_TYPE_DOUBLE, &cpuPercent} }); } - -exit: - fclose(procStat); } From 664017ba8111725dd84c75ab2d2fda437f040ad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 21 Sep 2022 14:52:07 +0800 Subject: [PATCH 2/7] OS: print codename ( macOS ) --- src/detection/os/os_apple.c | 38 ++++++++++++++++++++++++++++++++++--- src/modules/os.c | 8 ++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/detection/os/os_apple.c b/src/detection/os/os_apple.c index acf7cdd6c7..a18870c813 100644 --- a/src/detection/os/os_apple.c +++ b/src/detection/os/os_apple.c @@ -3,6 +3,7 @@ #include "common/sysctl.h" #include +#include typedef enum PListKey { @@ -12,7 +13,7 @@ typedef enum PListKey PLIST_KEY_OTHER } PListKey; -static void parseFile(FFOSResult* os) +static void parseSystemVersion(FFOSResult* os) { FILE* plist = fopen("/System/Library/CoreServices/SystemVersion.plist", "r"); if(plist == NULL) @@ -58,6 +59,33 @@ static void parseFile(FFOSResult* os) fclose(plist); } +void parseOSXSoftwareLicense(FFOSResult* os) +{ + FILE* rtf = fopen("/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf", "r"); + if(rtf == NULL) + return; + + char* line = NULL; + size_t len = 0; + const char* searchStr = "\\f0\\b SOFTWARE LICENSE AGREEMENT FOR macOS "; + const size_t searchLen = strlen(searchStr); + while(getline(&line, &len, rtf) != EOF) + { + if (strncmp(line, searchStr, searchLen) == 0) + { + ffStrbufAppendS(&os->codename, line + searchLen); + ffStrbufTrimRight(&os->codename, '\n'); + ffStrbufTrimRight(&os->codename, '\\'); + break; + } + } + + if(line != NULL) + free(line); + + fclose(rtf); +} + void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) { FF_UNUSED(instance); @@ -76,7 +104,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufInitA(&os->variant, 0); ffStrbufInitA(&os->variantID, 0); - parseFile(os); + parseSystemVersion(os); if(ffStrbufStartsWithIgnCaseS(&os->name, "MacOS")) ffStrbufAppendS(&os->id, "macos"); @@ -84,9 +112,13 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) if(os->version.length == 0) ffSysctlGetString("kern.osproductversion", &os->version); - //TODO map version to pretty name + if(os->buildID.length == 0) + ffSysctlGetString("kern.osversion", &os->buildID); + ffStrbufAppend(&os->prettyName, &os->name); ffStrbufAppend(&os->versionID, &os->version); ffSysctlGetString("kern.ostype", &os->systemName); ffSysctlGetString("hw.machine", &os->architecture); + + parseOSXSoftwareLicense(os); } diff --git a/src/modules/os.c b/src/modules/os.c index 39132c3a1b..3d110f3a45 100644 --- a/src/modules/os.c +++ b/src/modules/os.c @@ -19,6 +19,14 @@ static void buildOutputDefault(const FFOSResult* os, FFstrbuf* result) else ffStrbufAppend(result, &os->systemName); + #ifdef __APPLE__ + if(os->codename.length > 0) + { + ffStrbufAppendC(result, ' '); + ffStrbufAppend(result, &os->codename); + } + #endif + //Append version if it is missing if(os->versionID.length > 0 && ffStrbufFirstIndex(result, &os->versionID) == result->length) { From fa065c1040717c785476c2ea336f5f2c9bd27358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 21 Sep 2022 15:15:36 +0800 Subject: [PATCH 3/7] Terminal: fix Alacritty detection on macOS --- src/detection/terminalShell.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/detection/terminalShell.c b/src/detection/terminalShell.c index 98766772bf..fbd898f60a 100644 --- a/src/detection/terminalShell.c +++ b/src/detection/terminalShell.c @@ -130,6 +130,13 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) getenv("WT_PROFILE_ID") != NULL )) term = "Windows Terminal"; + //Alacritty + if(!ffStrSet(term) && ( + getenv("ALACRITTY_SOCKET") != NULL || + getenv("ALACRITTY_LOG") != NULL || + getenv("ALACRITTY_WINDOW_ID") != NULL + )) term = "Alacritty"; + //Termux if(!ffStrSet(term) && ( getenv("TERMUX_VERSION") != NULL || From 9da97f586029ce5737595af3192f773ad8be4c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 21 Sep 2022 15:16:47 +0800 Subject: [PATCH 4/7] WMTheme: fix detection on macOS; metion macOS support in README --- README.md | 4 ++-- src/modules/wmtheme.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a6fb617edf..761fd167d9 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts ##### WM themes ``` -KWin, Mutter, Muffin, Marco, XFWM, Openbox (LXDE, LXQT & without DE) +KWin, Mutter, Muffin, Marco, XFWM, Openbox (LXDE, LXQT & without DE), Quartz Compositor (macOS) ``` ##### DE versions @@ -81,7 +81,7 @@ KDE Plasma, Gnome, Cinnamon, Mate, XFCE4, LXQt ##### Terminal fonts ``` -Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, ITerm2, Apple Terminal, TTY +Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, iTerm2, Apple Terminal, TTY ``` ## Building diff --git a/src/modules/wmtheme.c b/src/modules/wmtheme.c index 8e422e672b..ea78a68c3d 100644 --- a/src/modules/wmtheme.c +++ b/src/modules/wmtheme.c @@ -259,14 +259,15 @@ static const char* quartzCompositorParsePlist(FFinstance* instance, const FFstrb ffplist_get_uint_val(pWmThemeColor, &wmThemeColor); switch (wmThemeColor) { - case (uint64_t)-1: ffStrbufAppendS(theme, " (Graphite)"); + case (uint64_t)-1: ffStrbufAppendS(theme, "Graphite"); break; case 0: ffStrbufAppendS(theme, "Red"); break; case 1: ffStrbufAppendS(theme, "Orange"); break; case 2: ffStrbufAppendS(theme, "Yellow"); break; case 3: ffStrbufAppendS(theme, "Green"); break; + case 4: ffStrbufAppendS(theme, "Blue"); break; case 5: ffStrbufAppendS(theme, "Purple"); break; case 6: ffStrbufAppendS(theme, "Pink"); break; - default: ffStrbufAppendS(theme, "Blue"); break; + default: ffStrbufAppendS(theme, "Multicolor"); break; } plist_t pWmTheme = ffplist_dict_get_item(root_node, "AppleInterfaceStyle"); From 3068b5bcb2a1edb5ba6306bfb292020919ca6f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 21 Sep 2022 15:19:46 +0800 Subject: [PATCH 5/7] Memory: fix percentage calculation --- src/detection/memory/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/memory/memory.c b/src/detection/memory/memory.c index 14b86cc39b..f777554c3d 100644 --- a/src/detection/memory/memory.c +++ b/src/detection/memory/memory.c @@ -5,7 +5,7 @@ void ffDetectMemoryImpl(FFMemoryResult* memory); static void calculatePercentage(FFMemoryStorage* storage) { - if(storage->error.length == 0) + if(storage->error.length != 0) return; if(storage->bytesTotal == 0) From 65ed48a1bc12fc105e573c1b728fb15dc295f2dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 21 Sep 2022 15:21:51 +0800 Subject: [PATCH 6/7] Swap: prints `Disabled` instead of `0 B / 0 B (0%)` which seems a bug --- src/modules/memory.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/modules/memory.c b/src/modules/memory.c index 45cabec283..f3f2c17eea 100644 --- a/src/modules/memory.c +++ b/src/modules/memory.c @@ -27,7 +27,10 @@ static void printMemory(FFinstance* instance, const char* name, const FFModuleAr if(moduleArgs->outputFormat.length == 0) { ffPrintLogoAndKey(instance, name, 0, &moduleArgs->key); - printf("%s / %s (%u%%)\n", usedPretty.chars, totalPretty.chars, storage->percentage); + if (storage->bytesTotal == 0) + puts("Disabled"); + else + printf("%s / %s (%u%%)\n", usedPretty.chars, totalPretty.chars, storage->percentage); } else { From f9fa482b833dfc0eb4475386099266f9fb08f012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 21 Sep 2022 16:03:51 +0800 Subject: [PATCH 7/7] Locale: try detecting with `locale` command in case $LC_* envs are not set ( macOS ) --- src/common/processing.c | 8 +++++--- src/common/processing.h | 2 +- src/modules/locale.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/common/processing.c b/src/common/processing.c index d361a63afe..d8bb4e0bd8 100644 --- a/src/common/processing.c +++ b/src/common/processing.c @@ -6,16 +6,16 @@ #include #include -void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) +const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) { int pipes[2]; if(pipe(pipes) == -1) - return; + return "pipe() failed"; pid_t childPid = fork(); if(childPid == -1) - return; + return "fork() failed"; //Child if(childPid == 0) @@ -33,4 +33,6 @@ void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) waitpid(childPid, NULL, 0); ffAppendFDBuffer(pipes[0], buffer); close(pipes[0]); + + return NULL; } diff --git a/src/common/processing.h b/src/common/processing.h index 8bb67be85a..51164b0e9d 100644 --- a/src/common/processing.h +++ b/src/common/processing.h @@ -5,6 +5,6 @@ #include "util/FFstrbuf.h" -void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]); +const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]); #endif diff --git a/src/modules/locale.c b/src/modules/locale.c index 5b5b632697..444ed5a11f 100644 --- a/src/modules/locale.c +++ b/src/modules/locale.c @@ -2,6 +2,8 @@ #include "common/properties.h" #include "common/printing.h" #include "common/caching.h" +#include "common/processing.h" +#include "common/parsing.h" #include @@ -21,6 +23,31 @@ static void getLocaleFromEnv(FFstrbuf* locale) ffStrbufAppendS(locale, getenv("LC_MESSAGES")); } +static void getLocaleFromCmd(FFstrbuf* locale) +{ + FFstrbuf buffer; + ffStrbufInitA(&buffer, 0); + char* args[] = { "locale", NULL }; + if(ffProcessAppendStdOut(&buffer, args) == NULL) + { + ffParsePropLines(buffer.chars, "LANG=\"", locale); + ffStrbufTrimRight(locale, '"'); + + if(locale->length == 0) + { + ffParsePropLines(buffer.chars, "LC_ALL=\"", locale); + ffStrbufTrimRight(locale, '"'); + + if(locale->length == 0) + { + ffParsePropLines(buffer.chars, "LC_MESSAGES=\"", locale); + ffStrbufTrimRight(locale, '"'); + } + } + } + ffStrbufDestroy(&buffer); +} + void ffPrintLocale(FFinstance* instance) { if(ffPrintFromCache(instance, FF_LOCALE_MODULE_NAME, &instance->config.locale, FF_LOCALE_NUM_FORMAT_ARGS)) @@ -44,6 +71,11 @@ void ffPrintLocale(FFinstance* instance) getLocaleFromEnv(&locale); } + if(locale.length == 0) + { + getLocaleFromCmd(&locale); + } + if(locale.length == 0) { ffPrintError(instance, FF_LOCALE_MODULE_NAME, 0, &instance->config.locale, "No locale found");