diff --git a/CMakeLists.txt b/CMakeLists.txt index 95ecba43..66e48dae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,14 +72,16 @@ endif() set(CMAKE_C_STANDARD 11) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion") + +# Used for dlopen finding dylibs installed by homebrew +# `/opt/homebrew/lib` is not on in dlopen search path by default if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX}) - # Used for dlopen finding dylibs installed by homebrew, reversed for future usage - # `/opt/homebrew/lib` is not on dlopen search path by default set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,$ENV{HOMEBREW_PREFIX}/lib") endif() -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined") -set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -rdynamic -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined") +set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined") +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}") +set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG} -rdynamic") include(CheckIPOSupported) check_ipo_supported(RESULT IPO_SUPPORTED) @@ -197,6 +199,7 @@ set(LIBFASTFETCH_SRC src/detection/gpu/gpu.c src/detection/memory/memory.c src/detection/displayserver/displayserver.c + src/detection/terminalfont/terminalfont.c src/modules/break.c src/modules/custom.c src/modules/title.c @@ -247,7 +250,7 @@ if(APPLE) src/detection/battery/battery_apple.c src/detection/memory/memory_apple.c src/detection/displayserver/displayserver_apple.c - src/modules/terminalfont_apple.c + src/detection/terminalfont/terminalfont_apple.c src/util/apple/cfdict_helpers.c src/util/apple/osascript.m ) @@ -260,7 +263,6 @@ elseif(ANDROID) src/detection/battery/battery_android.c src/detection/memory/memory_linux.c src/detection/displayserver/displayserver_android.c - src/modules/terminalfont_linux.c ) else() list(APPEND LIBFASTFETCH_SRC @@ -275,7 +277,7 @@ else() src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c src/detection/displayserver/linux/wmde.c - src/modules/terminalfont_linux.c + src/detection/terminalfont/terminalfont_linux.c ) endif() diff --git a/README.md b/README.md index 8dbec36f..bacbff29 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#
Fastfetch
+# Fastfetch Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written in pure c, with performance and customizability in mind. Currently Linux, Android and MacOS are supported. @@ -81,7 +81,7 @@ KDE Plasma, Gnome, Cinnamon, Mate, XFCE4, LXQt ##### Terminal fonts ``` -konsole, gnome-terminal-server, tilix, xfce4-terminal, alacritty, lxterminal, TTY +Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, ITerm2, Apple Terminal, TTY ``` ## Building diff --git a/src/common/settings.c b/src/common/settings.c index 1e718de8..9b14c1be 100644 --- a/src/common/settings.c +++ b/src/common/settings.c @@ -89,7 +89,7 @@ typedef struct GSettingsData GVariantGetters variantGetters; } GSettingsData; -static const GSettingsData* getGSettingsData(FFinstance* instance) +static const GSettingsData* getGSettingsData(const FFinstance* instance) { FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance->config.libGIO, "libgio-2.0.so", 1); @@ -114,7 +114,7 @@ static const GSettingsData* getGSettingsData(FFinstance* instance) FF_LIBRARY_DATA_LOAD_RETURN } -FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type) +FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type) { const GSettingsData* data = getGSettingsData(instance); if(data == NULL) @@ -143,7 +143,7 @@ FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, c return getGVariantValue(variant, type, &data->variantGetters); } #else //FF_HAVE_GIO -FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type) +FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type) { FF_UNUSED(instance, schemaName, path, key, type) return FF_VARIANT_NULL; @@ -161,7 +161,7 @@ typedef struct DConfData DConfClient* client; } DConfData; -static const DConfData* getDConfData(FFinstance* instance) +static const DConfData* getDConfData(const FFinstance* instance) { FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance->config.libDConf, "libdconf.so", 2); @@ -181,7 +181,7 @@ static const DConfData* getDConfData(FFinstance* instance) FF_LIBRARY_DATA_LOAD_RETURN } -FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type) +FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type) { const DConfData* data = getDConfData(instance); if(data == NULL) @@ -199,14 +199,14 @@ FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttyp return getGVariantValue(variant, type, &data->variantGetters); } #else //FF_HAVE_DCONF -FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type) +FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type) { FF_UNUSED(instance, key, type) return FF_VARIANT_NULL; } #endif //FF_HAVE_DCONF -FFvariant ffSettingsGet(FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type) +FFvariant ffSettingsGet(const FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type) { FFvariant gsettings = ffSettingsGetGSettings(instance, gsettingsSchemaName, gsettingsPath, gsettingsKey, type); @@ -231,7 +231,7 @@ typedef struct XFConfData FF_LIBRARY_SYMBOL(xfconf_init) } XFConfData; -static const XFConfData* getXFConfData(FFinstance* instance) +static const XFConfData* getXFConfData(const FFinstance* instance) { FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance->config.libXFConf, "libxfconf-0.so", 4); @@ -248,7 +248,7 @@ static const XFConfData* getXFConfData(FFinstance* instance) FF_LIBRARY_DATA_LOAD_RETURN } -FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type) +FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type) { const XFConfData* data = getXFConfData(instance); if(data == NULL) @@ -271,7 +271,7 @@ FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, con return FF_VARIANT_NULL; } #else //FF_HAVE_XFCONF -FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type) +FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type) { FF_UNUSED(instance, channelName, propertyName, type) return FF_VARIANT_NULL; diff --git a/src/common/settings.h b/src/common/settings.h index acc299d6..9513b309 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -25,10 +25,10 @@ typedef union FFvariant #define FF_VARIANT_NULL ((FFvariant){.strValue = NULL}) -FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type); -FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type); -FFvariant ffSettingsGet(FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type); -FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type); +FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type); +FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type); +FFvariant ffSettingsGet(const FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type); +FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type); int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query); diff --git a/src/detection/terminalShell.c b/src/detection/terminalShell.c index bfbbabd0..2aadccd0 100644 --- a/src/detection/terminalShell.c +++ b/src/detection/terminalShell.c @@ -240,7 +240,7 @@ static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* versio getShellVersionGeneric(exe, exeName, version); } -const FFTerminalShellResult* ffDetectTerminalShell(FFinstance* instance) +const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) { FF_UNUSED(instance); diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c new file mode 100644 index 00000000..1eff1738 --- /dev/null +++ b/src/detection/terminalfont/terminalfont.c @@ -0,0 +1,88 @@ +#include "terminalfont.h" +#include "common/properties.h" +#include "common/processing.h" +#include "detection/internal.h" +#include "detection/terminalshell.h" + +static void detectAlacritty(const FFinstance* instance, FFTerminalFontResult* terminalFont) { + FFstrbuf fontName; + ffStrbufInit(&fontName); + + FFstrbuf fontSize; + ffStrbufInit(&fontSize); + + FFpropquery fontQuery[] = { + {"family:", &fontName}, + {"size:", &fontSize}, + }; + + // alacritty parses config files in this order + ffParsePropFileConfigValues(instance, "alacritty/alacritty.yml", 2, fontQuery); + if(fontName.length == 0 || fontSize.length == 0) + ffParsePropFileConfigValues(instance, "alacritty.yml", 2, fontQuery); + if(fontName.length == 0 || fontSize.length == 0) + ffParsePropFileConfigValues(instance, ".alacritty.yml", 2, fontQuery); + + //by default alacritty uses its own font called alacritty + if(fontName.length == 0) + ffStrbufAppendS(&fontName, "alacritty"); + + // the default font size is 11 + if(fontSize.length == 0) + ffStrbufAppendS(&fontSize, "11"); + + ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); + + ffStrbufDestroy(&fontName); + ffStrbufDestroy(&fontSize); +} + +static void detectTTY(FFTerminalFontResult* terminalFont) +{ + FFstrbuf fontName; + ffStrbufInit(&fontName); + + ffParsePropFile(FASTFETCH_TARGET_DIR_ROOT"/etc/vconsole.conf", "Font =", &fontName); + + if(fontName.length == 0) + { + ffStrbufAppendS(&fontName, "VGA default kernel font "); + ffProcessAppendStdOut(&fontName, (char* const[]){ + "showconsolefont", + "--info", + NULL + }); + + ffStrbufTrimRight(&fontName, ' '); + } + + if(fontName.length > 0) + ffFontInitCopy(&terminalFont->font, fontName.chars); + else + ffStrbufAppendS(&terminalFont->error, "Couldn't find Font in /etc/vconsole.conf"); + + ffStrbufDestroy(&fontName); +} + +void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont); + +const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance) +{ + FF_DETECTION_INTERNAL_GUARD(FFTerminalFontResult, + ffStrbufInitA(&result.error, 0); + + const FFTerminalShellResult* terminalShell = ffDetectTerminalShell(instance); + + if(terminalShell->terminalProcessName.length == 0) + ffStrbufAppendS(&result.error, "Terminal font needs successfull terminal detection"); + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "alacritty") == 0) + detectAlacritty(instance, &result); + else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty")) + detectTTY(&result); + else + ffDetectTerminalFontPlatform(instance, terminalShell, &result); + + if(result.error.length == 0 && result.font.pretty.length == 0) + ffStrbufAppendF(&result.error, "Unknown terminal: %s", terminalShell->terminalProcessName.chars); + ); +} diff --git a/src/detection/terminalfont/terminalfont.h b/src/detection/terminalfont/terminalfont.h new file mode 100644 index 00000000..0adc2e2a --- /dev/null +++ b/src/detection/terminalfont/terminalfont.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_terminalfont_terminalfont +#define FF_INCLUDED_detection_terminalfont_terminalfont + +#include "fastfetch.h" +#include "common/font.h" + +typedef struct FFTerminalFontResult +{ + FFstrbuf error; + FFfont font; +} FFTerminalFontResult; + +const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance); + +#endif diff --git a/src/detection/terminalfont/terminalfont_android.c b/src/detection/terminalfont/terminalfont_android.c new file mode 100644 index 00000000..06eab584 --- /dev/null +++ b/src/detection/terminalfont/terminalfont_android.c @@ -0,0 +1,7 @@ +#include "terminalfont.h" +#include "detection/terminalshell.h" + +void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) +{ + FF_UNUSED(instance, terminalShell, terminalFont); +} diff --git a/src/modules/terminalfont_apple.c b/src/detection/terminalfont/terminalfont_apple.c similarity index 59% rename from src/modules/terminalfont_apple.c rename to src/detection/terminalfont/terminalfont_apple.c index d7454a30..6d747c94 100644 --- a/src/modules/terminalfont_apple.c +++ b/src/detection/terminalfont/terminalfont_apple.c @@ -1,19 +1,18 @@ -#include "fastfetch.h" +#include "terminalfont.h" #include "common/printing.h" #include "common/font.h" #include "common/io.h" #include "common/library.h" +#include "detection/terminalshell.h" #include "util/apple/osascript.h" -#include "terminalfont.h" #include #include #ifdef FF_HAVE_LIBPLIST - #include -static char* printIterm2Impl(FFinstance* instance, const char* profile, FFstrbuf* content) +static const char* iterm2ParsePList(const FFinstance* instance, const FFstrbuf* content, const char* profile, FFTerminalFontResult* terminalFont) { FF_LIBRARY_LOAD(libplist, instance->config.libplist, "dlopen libplist failed", "libplist-2.0"FF_LIBRARY_EXTENSION, 2); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libplist, plist_is_binary); @@ -62,23 +61,18 @@ static char* printIterm2Impl(FFinstance* instance, const char* profile, FFstrbuf return "find Normal Font key failed"; } - FFfont font; - ffFontInitWithSpace(&font, ffplist_get_string_ptr(item, NULL)); - ffPrintTerminalFontResult(instance, font.name.chars, &font); - ffFontDestroy(&font); + ffFontInitWithSpace(&terminalFont->font, ffplist_get_string_ptr(item, NULL)); + ffplist_free(root_node); return NULL; } -#endif //FF_HAVE_LIBPLIST - -static void printIterm2(FFinstance* instance) +static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* terminalFont) { - #ifdef FF_HAVE_LIBPLIST const char* profile = getenv("ITERM_PROFILE"); if (profile == NULL) { - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Unknown iTerm profile"); + ffStrbufAppendS(&terminalFont->error, "environment variable ITERM_PROFILE not set"); return; } @@ -89,31 +83,40 @@ static void printIterm2(FFinstance* instance) FFstrbuf content; ffStrbufInit(&content); - bool success = ffAppendFileBuffer(fileName.chars, &content); + fAppendFileBuffer(fileName.chars, &content); ffStrbufDestroy(&fileName); - - if(success) + if(content.length == 0) { - const char* error = printIterm2Impl(instance, profile, &content); - if (error) - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "%s", error); + ffStrbufAppendS(&terminalFont->error, "reading iTerm preference file failed"); + ffStrbufDestroy(&content); + return; } - else - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Read iTerm preference file failed"); + + const char* error = iterm2ParsePList(instance, &content, profile, terminalFont); + if(error != NULL) + ffStrbufAppendS(&terminalFont->error, error); ffStrbufDestroy(&content); - #else - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Parse iTerm preferences requires libplist to be installed"); - #endif } -static void printAppleTerminal(FFinstance* instance) +#else +static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* terminalFont) +{ + FF_UNUSED(instance); + ffStrbufAppendS(&terminalFont->error, "Fastfetch was compiled without libplist support"); +} +#endif + +static void detectAppleTerminal(FFTerminalFontResult* terminalFont) { FFstrbuf fontName; ffStrbufInit(&fontName); - if(!ffOsascript("tell application \"Terminal\" to font name of window frontmost", &fontName)) + ffOsascript("tell application \"Terminal\" to font name of window frontmost", &fontName); + + if(fontName.length == 0) { - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "osascript failed"); + ffStrbufAppendS(&terminalFont->error, "executing osascript failed"); + ffStrbufDestroy(&fontName); return; } @@ -121,23 +124,16 @@ static void printAppleTerminal(FFinstance* instance) ffStrbufInit(&fontSize); ffOsascript("tell application \"Terminal\" to font size of window frontmost", &fontSize); - FFfont font; - ffFontInitValues(&font, fontName.chars, fontSize.chars); - ffPrintTerminalFontResult(instance, fontName.chars, &font); - ffFontDestroy(&font); + ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); ffStrbufDestroy(&fontName); ffStrbufDestroy(&fontSize); } -bool ffPrintTerminalFontPlatform(FFinstance* instance, const FFTerminalShellResult* shellInfo) +void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { - bool success = true; - if(ffStrbufIgnCaseCompS(&shellInfo->terminalProcessName, "iterm.app") == 0) - printIterm2(instance); - else if(ffStrbufIgnCaseCompS(&shellInfo->terminalProcessName, "Apple_Terminal") == 0) - printAppleTerminal(instance); - else - success = false; - return success; + if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "iterm.app") == 0) + detectIterm2(instance, terminalFont); + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Apple_Terminal") == 0) + detectAppleTerminal(terminalFont); } diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c new file mode 100644 index 00000000..79dc0521 --- /dev/null +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -0,0 +1,155 @@ +#include "terminalfont.h" +#include "common/settings.h" +#include "common/properties.h" +#include "common/parsing.h" +#include "detection/terminalshell.h" +#include "detection/displayserver/displayserver.h" + +static const char* getSystemMonospaceFont(const FFinstance* instance) +{ + const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance); + + if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Cinnamon") == 0) + { + const char* systemMonospaceFont = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/monospace-font-name", "org.cinnamon.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; + if(ffStrSet(systemMonospaceFont)) + return systemMonospaceFont; + } + else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Mate") == 0) + { + const char* systemMonospaceFont = ffSettingsGet(instance, "/org/mate/interface/monospace-font-name", "org.mate.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; + if(ffStrSet(systemMonospaceFont)) + return systemMonospaceFont; + } + + return ffSettingsGet(instance, "/org/gnome/desktop/interface/monospace-font-name", "org.gnome.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; +} + +static void detectFromGSettings(const FFinstance* instance, char* profilePath, char* profileList, char* profile, FFTerminalFontResult* terminalFont) +{ + const char* defaultProfile = ffSettingsGetGSettings(instance, profileList, NULL, "default", FF_VARIANT_TYPE_STRING).strValue; + if(!ffStrSet(defaultProfile)) + { + ffStrbufAppendF(&terminalFont->error, "Could not get default profile from gsettings: %s", profileList); + return; + } + + FFstrbuf path; + ffStrbufInitA(&path, 128); + ffStrbufAppendS(&path, profilePath); + ffStrbufAppendS(&path, defaultProfile); + ffStrbufAppendC(&path, '/'); + + if(!ffSettingsGetGSettings(instance, profile, path.chars, "use-system-font", FF_VARIANT_TYPE_BOOL).boolValue) + { + const char* fontName = ffSettingsGetGSettings(instance, profile, path.chars, "font", FF_VARIANT_TYPE_STRING).strValue; + if(ffStrSet(fontName)) + ffFontInitPango(&terminalFont->font, fontName); + else + ffStrbufAppendF(&terminalFont->error, "Couldn't get terminal font from GSettings (%s::%s::font)", profile, path.chars); + } + else + { + const char* fontName = getSystemMonospaceFont(instance); + if(ffStrSet(fontName)) + ffFontInitPango(&terminalFont->font, fontName); + else + ffStrbufAppendS(&terminalFont->error, "Could't get system monospace font name from GSettings / DConf"); + } + + ffStrbufDestroy(&path); +} + +static void detectFromConfigFile(const FFinstance* instance, const char* configFile, const char* start, FFTerminalFontResult* terminalFont) +{ + FFstrbuf fontName; + ffStrbufInit(&fontName); + ffParsePropFileConfig(instance, configFile, start, &fontName); + + if(fontName.length == 0) + ffStrbufAppendF(&terminalFont->error, "Couldn't find %s in .config/%s", start, configFile); + else + ffFontInitPango(&terminalFont->font, fontName.chars); + + ffStrbufDestroy(&fontName); +} + +static void detectKonsole(const FFinstance* instance, FFTerminalFontResult* terminalFont) +{ + FFstrbuf profile; + ffStrbufInit(&profile); + ffParsePropFileConfig(instance, "konsolerc", "DefaultProfile =", &profile); + + if(profile.length == 0) + { + ffStrbufAppendS(&terminalFont->error, "Couldn't find \"DefaultProfile=%[^\\n]\" in \".config/konsolerc\""); + ffStrbufDestroy(&profile); + return; + } + + FFstrbuf profilePath; + ffStrbufInitA(&profilePath, 64); + ffStrbufAppendS(&profilePath, ".local/share/konsole/"); + ffStrbufAppend(&profilePath, &profile); + + ffStrbufDestroy(&profile); + + FFstrbuf fontName; + ffStrbufInit(&fontName); + ffParsePropFileHome(instance, profilePath.chars, "Font =", &fontName); + + if(fontName.length == 0) + ffStrbufAppendF(&terminalFont->error, "Couldn't find \"Font=%%[^\\n]\" in \"%s\"", profilePath.chars); + else + ffFontInitQt(&terminalFont->font, fontName.chars); + + ffStrbufDestroy(&fontName); + ffStrbufDestroy(&profilePath); +} + +static void detectXFCETerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) +{ + FFstrbuf useSysFont; + ffStrbufInit(&useSysFont); + + FFstrbuf fontName; + ffStrbufInit(&fontName); + + ffParsePropFileConfigValues(instance, "xfce4/terminal/terminalrc", 2, (FFpropquery[]) { + {"FontUseSystem = ", &useSysFont}, + {"FontName = ", &fontName} + }); + + if(useSysFont.length == 0 || ffStrbufIgnCaseCompS(&useSysFont, "false") == 0) + { + if(fontName.length == 0) + ffStrbufAppendS(&terminalFont->error, "Couldn't find FontName in .config/xfce4/terminal/terminalrc"); + else + ffFontInitPango(&terminalFont->font, fontName.chars); + } + else + { + const char* systemFontName = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/MonospaceFontName", FF_VARIANT_TYPE_STRING).strValue; + if(ffStrSet(systemFontName)) + ffFontInitPango(&terminalFont->font, systemFontName); + else + ffStrbufAppendS(&terminalFont->error, "Couldn't find xsettings::/Gtk/MonospaceFontName in XFConf"); + } + + ffStrbufDestroy(&fontName); + ffStrbufDestroy(&useSysFont); +} + +void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) +{ + if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "konsole") == 0) + detectKonsole(instance, terminalFont); + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "xfce4-terminal") == 0) + detectXFCETerminal(instance, terminalFont); + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "lxterminal") == 0) + detectFromConfigFile(instance, "lxterminal/lxterminal.conf", "fontname =", terminalFont); + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "tilix") == 0) + detectFromGSettings(instance, "/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", terminalFont); + else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "gnome-terminal-") == 0) + detectFromGSettings(instance, "/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", terminalFont); +} diff --git a/src/detection/terminalshell.h b/src/detection/terminalshell.h index 9687eba3..2791856a 100644 --- a/src/detection/terminalshell.h +++ b/src/detection/terminalshell.h @@ -21,6 +21,6 @@ typedef struct FFTerminalShellResult FFstrbuf userShellVersion; } FFTerminalShellResult; -const FFTerminalShellResult* ffDetectTerminalShell(FFinstance* instance); +const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance); #endif diff --git a/src/fastfetch.c b/src/fastfetch.c index 155237af..ec1ea90a 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -246,12 +246,11 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "terminal-font-format") == 0) { - constructAndPrintCommandHelpFormat("terminal-font", "{5}", 5, - "Terminal font raw", + constructAndPrintCommandHelpFormat("terminal-font", "{}", 4, + "Terminal font", "Terminal font name", "Termianl font size", "Terminal font styles" - "Terminal font pretty" ); } else if(strcasecmp(command, "cpu-format") == 0) diff --git a/src/modules/terminalfont.c b/src/modules/terminalfont.c index c7ccd610..25082654 100644 --- a/src/modules/terminalfont.c +++ b/src/modules/terminalfont.c @@ -1,112 +1,32 @@ #include "fastfetch.h" -#include "common/properties.h" #include "common/printing.h" -#include "common/font.h" -#include "common/processing.h" -#include "terminalfont.h" +#include "detection/terminalfont/terminalfont.h" -void ffPrintTerminalFontResult(FFinstance* instance, const char* raw, FFfont* font) +#define FF_TERMFONT_MODULE_NAME "Terminal Font" +#define FF_TERMFONT_NUM_FORMAT_ARGS 4 + +void ffPrintTerminalFont(FFinstance* instance) { - if(font->pretty.length == 0) + const FFTerminalFontResult* terminalFont = ffDetectTerminalFont(instance); + + if(terminalFont->error.length > 0) { - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Terminal font is an empty value"); + ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, terminalFont->error.chars); return; } if(instance->config.terminalFont.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont.key); - ffStrbufPutTo(&font->pretty, stdout); + ffStrbufPutTo(&terminalFont->font.pretty, stdout); } else { ffPrintFormat(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, FF_TERMFONT_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRING, raw}, - {FF_FORMAT_ARG_TYPE_STRBUF, &font->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &font->size}, - {FF_FORMAT_ARG_TYPE_LIST, &font->styles}, - {FF_FORMAT_ARG_TYPE_STRBUF, &font->pretty} + {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.pretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.size}, + {FF_FORMAT_ARG_TYPE_LIST, &terminalFont->font.styles} }); } } - -static void printAlacritty(FFinstance* instance) { - FFstrbuf fontName; - FFstrbuf fontSize; - ffStrbufInit(&fontName); - ffStrbufInit(&fontSize); - - FFpropquery fontQuery[] = { - {"family:", &fontName}, - {"size:", &fontSize}, - }; - - // alacritty parses config files in this order - ffParsePropFileConfigValues(instance, "alacritty/alacritty.yml", 2, fontQuery); - if(fontName.length == 0 || fontSize.length == 0) - ffParsePropFileConfigValues(instance, "alacritty.yml", 2, fontQuery); - if(fontName.length == 0 || fontSize.length == 0) - ffParsePropFileConfigValues(instance, ".alacritty.yml", 2, fontQuery); - - //by default alacritty uses its own font called alacritty - if(fontName.length == 0) - ffStrbufAppendS(&fontName, "alacritty"); - - // the default font size is 11 - if(fontSize.length == 0) - ffStrbufAppendS(&fontSize, "11"); - - FFfont font; - ffFontInitValues(&font, fontName.chars, fontSize.chars); - ffPrintTerminalFontResult(instance, fontName.chars, &font); - ffFontDestroy(&font); - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&fontSize); -} - -static void printTTY(FFinstance* instance) -{ - FFstrbuf fontName; - ffStrbufInit(&fontName); - - ffParsePropFile(FASTFETCH_TARGET_DIR_ROOT"/etc/vconsole.conf", "Font =", &fontName); - - if(fontName.length == 0) - { - ffStrbufAppendS(&fontName, "VGA default kernel font "); - ffProcessAppendStdOut(&fontName, (char* const[]){ - "showconsolefont", - "--info", - NULL - }); - } - - ffStrbufTrimRight(&fontName, ' '); - - FFfont font; - ffFontInitCopy(&font, fontName.chars); - ffPrintTerminalFontResult(instance, fontName.chars, &font); - ffFontDestroy(&font); - ffStrbufDestroy(&fontName); -} - -void ffPrintTerminalFont(FFinstance* instance) -{ - const FFTerminalShellResult* result = ffDetectTerminalShell(instance); - - if(result->terminalProcessName.length == 0) - { - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Terminal font needs successfull terminal detection"); - return; - } - - if(ffPrintTerminalFontPlatform(instance, result)) - return; - if(ffStrbufStartsWithIgnCaseS(&result->terminalExe, "/dev/tty")) - printTTY(instance); - else if(ffStrbufIgnCaseCompS(&result->terminalProcessName, "alacritty") == 0) - printAlacritty(instance); - else - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Unknown terminal: %s", result->terminalProcessName.chars); -} diff --git a/src/modules/terminalfont.h b/src/modules/terminalfont.h deleted file mode 100644 index 45c6f080..00000000 --- a/src/modules/terminalfont.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#ifndef FF_INCLUDED_modules_terminalfont -#define FF_INCLUDED_modules_terminalfont - -#include "fastfetch.h" -#include "detection/terminalshell.h" - -#define FF_TERMFONT_MODULE_NAME "Terminal Font" -#define FF_TERMFONT_NUM_FORMAT_ARGS 5 - -void ffPrintTerminalFontResult(FFinstance* instance, const char* raw, FFfont* font); -bool ffPrintTerminalFontPlatform(FFinstance* instance, const FFTerminalShellResult* shellInfo); - -#endif diff --git a/src/modules/terminalfont_linux.c b/src/modules/terminalfont_linux.c deleted file mode 100644 index 26652683..00000000 --- a/src/modules/terminalfont_linux.c +++ /dev/null @@ -1,177 +0,0 @@ -#include "fastfetch.h" -#include "common/properties.h" -#include "common/printing.h" -#include "common/font.h" -#include "common/settings.h" -#include "detection/displayserver/displayserver.h" -#include "detection/terminalshell.h" -#include "terminalfont.h" - -static const char* getSystemMonospaceFont(FFinstance* instance) -{ - const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance); - - if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Cinnamon") == 0) - { - const char* systemMonospaceFont = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/monospace-font-name", "org.cinnamon.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; - if(systemMonospaceFont != NULL) - return systemMonospaceFont; - } - else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Mate") == 0) - { - const char* systemMonospaceFont = ffSettingsGet(instance, "/org/mate/interface/monospace-font-name", "org.mate.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; - if(systemMonospaceFont != NULL) - return systemMonospaceFont; - } - - return ffSettingsGet(instance, "/org/gnome/desktop/interface/monospace-font-name", "org.gnome.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; -} - -static void printTerminalFontFromConfigFile(FFinstance* instance, const char* configFile, const char* start) -{ - FFstrbuf fontName; - ffStrbufInit(&fontName); - ffParsePropFileConfig(instance, configFile, start, &fontName); - - if(fontName.length == 0) - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Couldn't find terminal font in \"$XDG_CONFIG_HOME/%s\"", configFile); - else - { - FFfont font; - ffFontInitPango(&font, fontName.chars); - ffPrintTerminalFontResult(instance, fontName.chars, &font); - ffFontDestroy(&font); - } - - ffStrbufDestroy(&fontName); -} - -static void printTerminalFontFromGSettings(FFinstance* instance, char* profilePath, char* profileList, char* profile) -{ - const char* defaultProfile = ffSettingsGetGSettings(instance, profileList, NULL, "default", FF_VARIANT_TYPE_STRING).strValue; - if(defaultProfile == NULL) - { - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Couldn't get \"default\" profile from gsettings"); - return; - } - - FFstrbuf path; - ffStrbufInitA(&path, 128); - ffStrbufAppendS(&path, profilePath); - ffStrbufAppendS(&path, defaultProfile); - ffStrbufAppendC(&path, '/'); - - const char* fontName; - - if(!ffSettingsGetGSettings(instance, profile, path.chars, "use-system-font", FF_VARIANT_TYPE_BOOL).boolValue) // custom font - { - fontName = ffSettingsGetGSettings(instance, profile, path.chars, "font", FF_VARIANT_TYPE_STRING).strValue; - if(fontName == NULL) - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Couldn't get terminal font from GSettings (%s::%s::font)", profile, path.chars); - } - else // system font - { - fontName = getSystemMonospaceFont(instance); - if(fontName == NULL) - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Could't get system monospace font name from GSettings / DConf"); - } - - ffStrbufDestroy(&path); - - if(fontName == NULL) - return; - - FFfont font; - ffFontInitPango(&font, fontName); - ffPrintTerminalFontResult(instance, fontName, &font); - ffFontDestroy(&font); -} - -static void printKonsole(FFinstance* instance) -{ - FFstrbuf profile; - ffStrbufInit(&profile); - ffParsePropFileConfig(instance, "konsolerc", "DefaultProfile =", &profile); - - if(profile.length == 0) - { - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "%s", "Couldn't find \"DefaultProfile=%[^\\n]\" in \".config/konsolerc\""); - ffStrbufDestroy(&profile); - return; - } - - FFstrbuf profilePath; - ffStrbufInitA(&profilePath, 64); - ffStrbufAppendS(&profilePath, ".local/share/konsole/"); - ffStrbufAppend(&profilePath, &profile); - - FFstrbuf fontName; - ffStrbufInit(&fontName); - ffParsePropFileHome(instance, profilePath.chars, "Font =", &fontName); - - if(fontName.length == 0) - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Couldn't find \"Font=%%[^\\n]\" in \"%s\"", profilePath.chars); - else - { - FFfont font; - ffFontInitQt(&font, fontName.chars); - ffPrintTerminalFontResult(instance, fontName.chars, &font); - ffFontDestroy(&font); - } - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&profilePath); - ffStrbufDestroy(&profile); -} - -static void printXCFETerminal(FFinstance* instance) -{ - FFstrbuf useSysFont; - ffStrbufInit(&useSysFont); - - if(!ffParsePropFileConfig(instance, "xfce4/terminal/terminalrc", "FontUseSystem =", &useSysFont)) - { - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Couldn't open \"$XDG_CONFIG_HOME/xfce4/terminal/terminalrc\""); - ffStrbufDestroy(&useSysFont); - return; - } - - if(useSysFont.length == 0 || ffStrbufIgnCaseCompS(&useSysFont, "FALSE") == 0) - { - printTerminalFontFromConfigFile(instance, "xfce4/terminal/terminalrc", "FontName ="); - ffStrbufDestroy(&useSysFont); - return; - } - - ffStrbufDestroy(&useSysFont); - - const char* fontName = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/MonospaceFontName", FF_VARIANT_TYPE_STRING).strValue; - - if(fontName == NULL) - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "Couldn't find \"xsettings::/Gtk/MonospaceFontName\" in XFConf"); - else - { - FFfont font; - ffFontInitPango(&font, fontName); - ffPrintTerminalFontResult(instance, fontName, &font); - ffFontDestroy(&font); - } -} - -bool ffPrintTerminalFontPlatform(FFinstance* instance, const FFTerminalShellResult* shellInfo) -{ - bool success = true; - if(ffStrbufIgnCaseCompS(&shellInfo->terminalProcessName, "konsole") == 0) - printKonsole(instance); - else if(ffStrbufIgnCaseCompS(&shellInfo->terminalProcessName, "xfce4-terminal") == 0) - printXCFETerminal(instance); - else if(ffStrbufIgnCaseCompS(&shellInfo->terminalProcessName, "lxterminal") == 0) - printTerminalFontFromConfigFile(instance, "lxterminal/lxterminal.conf", "fontname ="); - else if(ffStrbufIgnCaseCompS(&shellInfo->terminalProcessName, "tilix") == 0) - printTerminalFontFromGSettings(instance, "/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile"); - else if(ffStrbufIgnCaseCompS(&shellInfo->terminalProcessName, "gnome-terminal-") == 0) - printTerminalFontFromGSettings(instance, "/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile"); - else - success = false; - return success; -} diff --git a/src/util/FFlist.c b/src/util/FFlist.c index 1044db5c..8dc563cf 100644 --- a/src/util/FFlist.c +++ b/src/util/FFlist.c @@ -28,9 +28,9 @@ void* ffListAdd(FFlist* list) // realloc(NULL, newSize) is same as malloc(newSize) list->data = realloc(list->data, (size_t)list->capacity * list->elementSize); } - void* address = list->data + (list->length * list->elementSize); + ++list->length; - return address; + return ffListGet(list, list->length - 1); } uint32_t ffListFirstIndexComp(const FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*)) @@ -46,7 +46,6 @@ uint32_t ffListFirstIndexComp(const FFlist* list, void* compElement, bool(*compF void ffListDestroy(FFlist* list) { - list->length = list->capacity = 0; - free(list->data); - list->data = NULL; + if(list->data != NULL) + free(list->data); }