mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-11-02 19:31:10 +01:00
Global: adds general cache layer
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include "displayserver.h"
|
||||
#include "common/FFcache.h"
|
||||
|
||||
FFDisplayResult* ffdsAppendDisplay(
|
||||
FFDisplayServerResult* result,
|
||||
@@ -50,18 +51,45 @@ FFDisplayResult* ffdsAppendDisplay(
|
||||
|
||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds);
|
||||
|
||||
const FFDisplayServerResult* ffConnectDisplayServer() {
|
||||
static FFDisplayServerResult result;
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
ffStrbufInit(&result.wmProcessName);
|
||||
ffStrbufInit(&result.wmPrettyName);
|
||||
ffStrbufInit(&result.wmProtocolName);
|
||||
ffStrbufInit(&result.deProcessName);
|
||||
ffStrbufInit(&result.dePrettyName);
|
||||
ffListInit(&result.displays);
|
||||
ffConnectDisplayServerImpl(&result);
|
||||
}
|
||||
return &result;
|
||||
static FFDisplayServerResult result;
|
||||
|
||||
static void initDisplayServerResult(void* storage) {
|
||||
FFDisplayServerResult* ds = storage;
|
||||
|
||||
ffStrbufInit(&ds->wmProcessName);
|
||||
ffStrbufInit(&ds->wmPrettyName);
|
||||
ffStrbufInit(&ds->wmProtocolName);
|
||||
ffStrbufInit(&ds->deProcessName);
|
||||
ffStrbufInit(&ds->dePrettyName);
|
||||
ffListInit(&ds->displays);
|
||||
|
||||
ffConnectDisplayServerImpl(ds);
|
||||
}
|
||||
|
||||
static void destroyDisplayServerResult(void* storage) {
|
||||
FFDisplayServerResult* ds = storage;
|
||||
|
||||
ffStrbufDestroy(&ds->wmProcessName);
|
||||
ffStrbufDestroy(&ds->wmPrettyName);
|
||||
ffStrbufDestroy(&ds->wmProtocolName);
|
||||
ffStrbufDestroy(&ds->deProcessName);
|
||||
ffStrbufDestroy(&ds->dePrettyName);
|
||||
|
||||
// Every display owns its name and serial, which are lost if the list is dropped as a whole
|
||||
FF_LIST_FOR_EACH (FFDisplayResult, display, ds->displays) {
|
||||
ffStrbufDestroy(&display->name);
|
||||
ffStrbufDestroy(&display->serial);
|
||||
}
|
||||
ffListDestroy(&ds->displays);
|
||||
}
|
||||
|
||||
static FFcacheEntry ffCacheEntryDisplayServer = {
|
||||
.name = "displayServer",
|
||||
.storage = &result,
|
||||
.init = initDisplayServerResult,
|
||||
.destroy = destroyDisplayServerResult,
|
||||
};
|
||||
|
||||
const FFDisplayServerResult* ffConnectDisplayServer() {
|
||||
return ffCacheGet(&ffCacheEntryDisplayServer);
|
||||
}
|
||||
|
||||
+117
-47
@@ -1,7 +1,7 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/thread.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/FFcache.h"
|
||||
#include "detection/gtk_qt/gtk_qt.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
|
||||
@@ -11,29 +11,42 @@ static inline bool allPropertiesSet(FFGTKResult* result) {
|
||||
result->font.length > 0;
|
||||
}
|
||||
|
||||
static inline void applyGTKSettings(FFGTKResult* result, const char* themeName, const char* iconsName, const char* fontName, const char* cursorTheme, int cursorSize, const char* wallpaper) {
|
||||
// The values read from the desktop settings daemons, shared by the GTK2/3/4 results. They are
|
||||
// owned copies on purpose: `settings.c` hands out strings it leaks deliberately (see the
|
||||
// "Leaks value.chars" notes there), so borrowing them past a `--dynamic-interval` round would
|
||||
// leak one set per round. Copying them also lets `destroy` release them.
|
||||
typedef struct FFGTKSettings {
|
||||
FFstrbuf theme;
|
||||
FFstrbuf icons;
|
||||
FFstrbuf font;
|
||||
FFstrbuf cursor;
|
||||
FFstrbuf wallpaper;
|
||||
int32_t cursorSize;
|
||||
} FFGTKSettings;
|
||||
|
||||
static inline void applyGTKSettings(FFGTKResult* result, const FFGTKSettings* settings) {
|
||||
if (result->theme.length == 0) {
|
||||
ffStrbufAppendS(&result->theme, themeName);
|
||||
ffStrbufAppend(&result->theme, &settings->theme);
|
||||
}
|
||||
|
||||
if (result->icons.length == 0) {
|
||||
ffStrbufAppendS(&result->icons, iconsName);
|
||||
ffStrbufAppend(&result->icons, &settings->icons);
|
||||
}
|
||||
|
||||
if (result->font.length == 0) {
|
||||
ffStrbufAppendS(&result->font, fontName);
|
||||
ffStrbufAppend(&result->font, &settings->font);
|
||||
}
|
||||
|
||||
if (result->cursor.length == 0) {
|
||||
ffStrbufAppendS(&result->cursor, cursorTheme);
|
||||
ffStrbufAppend(&result->cursor, &settings->cursor);
|
||||
}
|
||||
|
||||
if (result->cursorSize.length == 0 && cursorSize > 0) {
|
||||
ffStrbufAppendF(&result->cursorSize, "%i", cursorSize);
|
||||
if (result->cursorSize.length == 0 && settings->cursorSize > 0) {
|
||||
ffStrbufAppendSInt(&result->cursorSize, settings->cursorSize);
|
||||
}
|
||||
|
||||
if (result->wallpaper.length == 0) {
|
||||
ffStrbufAppendS(&result->wallpaper, wallpaper);
|
||||
ffStrbufAppend(&result->wallpaper, &settings->wallpaper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,22 +56,23 @@ static bool testXfconfWallpaperPropKey([[maybe_unused]] void* data, const char*
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
static void detectGTKFromSettings(FFGTKResult* result) {
|
||||
static const char* themeName = nullptr;
|
||||
static const char* iconsName = nullptr;
|
||||
static const char* fontName = nullptr;
|
||||
static const char* cursorTheme = nullptr;
|
||||
static int cursorSize = 0;
|
||||
static const char* wallpaper = nullptr;
|
||||
static FFGTKSettings gtkSettings;
|
||||
|
||||
static bool init = false;
|
||||
static void initGTKSettings(void* storage) {
|
||||
FFGTKSettings* settings = storage;
|
||||
|
||||
if (init) {
|
||||
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize, wallpaper);
|
||||
return;
|
||||
}
|
||||
ffStrbufInit(&settings->theme);
|
||||
ffStrbufInit(&settings->icons);
|
||||
ffStrbufInit(&settings->font);
|
||||
ffStrbufInit(&settings->cursor);
|
||||
ffStrbufInit(&settings->wallpaper);
|
||||
|
||||
init = true;
|
||||
const char* themeName = nullptr;
|
||||
const char* iconsName = nullptr;
|
||||
const char* fontName = nullptr;
|
||||
const char* cursorTheme = nullptr;
|
||||
int cursorSize = 0;
|
||||
const char* wallpaper = nullptr;
|
||||
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer();
|
||||
|
||||
@@ -98,14 +112,14 @@ static void detectGTKFromSettings(FFGTKResult* result) {
|
||||
wallpaper = ffSettingsGetGnome("/org/gnome/desktop/background/picture-uri", "org.gnome.desktop.background", nullptr, "picture-uri", FF_VARIANT_TYPE_STRING).strValue;
|
||||
} else if (
|
||||
ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_ENLIGHTENMENT)) {
|
||||
ffEnlightenmentSettings settings = {};
|
||||
if (ffSettingsGetEnlightenmentProperty(&settings)) {
|
||||
themeName = settings.theme;
|
||||
iconsName = settings.icon_theme;
|
||||
fontName = settings.font;
|
||||
cursorTheme = settings.use_e_cursor ? "Enlightenment" : "Application";
|
||||
cursorSize = settings.cursor_size;
|
||||
wallpaper = settings.desktop_default_background;
|
||||
ffEnlightenmentSettings enlightenmentSettings = {};
|
||||
if (ffSettingsGetEnlightenmentProperty(&enlightenmentSettings)) {
|
||||
themeName = enlightenmentSettings.theme;
|
||||
iconsName = enlightenmentSettings.icon_theme;
|
||||
fontName = enlightenmentSettings.font;
|
||||
cursorTheme = enlightenmentSettings.use_e_cursor ? "Enlightenment" : "Application";
|
||||
cursorSize = enlightenmentSettings.cursor_size;
|
||||
wallpaper = enlightenmentSettings.desktop_default_background;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -121,9 +135,34 @@ static void detectGTKFromSettings(FFGTKResult* result) {
|
||||
cursorSize = ffSettingsGetDConf("/org/gnome/desktop/interface/cursor-size", FF_VARIANT_TYPE_INT).intValue;
|
||||
}
|
||||
|
||||
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize, wallpaper);
|
||||
// The strings above are owned by `settings.c`, which leaks them on purpose, so copy them into
|
||||
// the cache instead of borrowing them: this runs again on every `--dynamic-interval` round.
|
||||
ffStrbufSetS(&settings->theme, themeName);
|
||||
ffStrbufSetS(&settings->icons, iconsName);
|
||||
ffStrbufSetS(&settings->font, fontName);
|
||||
ffStrbufSetS(&settings->cursor, cursorTheme);
|
||||
ffStrbufSetS(&settings->wallpaper, wallpaper);
|
||||
settings->cursorSize = cursorSize;
|
||||
}
|
||||
|
||||
static void destroyGTKSettings(void* storage) {
|
||||
FFGTKSettings* settings = storage;
|
||||
|
||||
ffStrbufDestroy(&settings->theme);
|
||||
ffStrbufDestroy(&settings->icons);
|
||||
ffStrbufDestroy(&settings->font);
|
||||
ffStrbufDestroy(&settings->cursor);
|
||||
ffStrbufDestroy(&settings->wallpaper);
|
||||
settings->cursorSize = 0;
|
||||
}
|
||||
|
||||
static FFcacheEntry ffCacheEntryGTKSettings = {
|
||||
.name = "gtk-settings",
|
||||
.storage = >kSettings,
|
||||
.init = initGTKSettings,
|
||||
.destroy = destroyGTKSettings,
|
||||
};
|
||||
|
||||
static void detectGTKFromConfigFile(const char* filename, FFGTKResult* result) {
|
||||
ffParsePropFileValues(filename, 5, (FFpropquery[]) { { "gtk-theme-name =", &result->theme }, { "gtk-icon-theme-name =", &result->icons }, { "gtk-font-name =", &result->font }, { "gtk-cursor-theme-name =", &result->cursor }, { "gtk-cursor-theme-size =", &result->cursorSize } });
|
||||
}
|
||||
@@ -172,7 +211,7 @@ static void detectGTKFromConfigDir(FFstrbuf* configDir, const char* version, FFG
|
||||
static void detectGTK(const char* version, FFGTKResult* result) {
|
||||
// Mate, Cinnamon, GNOME, Unity, Budgie use dconf to save theme config
|
||||
// On other DEs, this will do nothing
|
||||
detectGTKFromSettings(result);
|
||||
applyGTKSettings(result, ffCacheGet(&ffCacheEntryGTKSettings));
|
||||
if (allPropertiesSet(result)) {
|
||||
return;
|
||||
}
|
||||
@@ -189,20 +228,51 @@ static void detectGTK(const char* version, FFGTKResult* result) {
|
||||
}
|
||||
}
|
||||
|
||||
#define FF_DETECT_GTK_IMPL(version) \
|
||||
static FFGTKResult result; \
|
||||
static bool init = false; \
|
||||
if (init) \
|
||||
return &result; \
|
||||
init = true; \
|
||||
ffStrbufInit(&result.theme); \
|
||||
ffStrbufInit(&result.icons); \
|
||||
ffStrbufInit(&result.font); \
|
||||
ffStrbufInit(&result.cursor); \
|
||||
ffStrbufInit(&result.cursorSize); \
|
||||
ffStrbufInit(&result.wallpaper); \
|
||||
detectGTK(#version, &result); \
|
||||
return &result;
|
||||
static void initGTKResult(const char* version, FFGTKResult* result) {
|
||||
ffStrbufInit(&result->theme);
|
||||
ffStrbufInit(&result->icons);
|
||||
ffStrbufInit(&result->font);
|
||||
ffStrbufInit(&result->cursor);
|
||||
ffStrbufInit(&result->cursorSize);
|
||||
ffStrbufInit(&result->wallpaper);
|
||||
detectGTK(version, result);
|
||||
}
|
||||
|
||||
static void destroyGTKResult(void* storage) {
|
||||
FFGTKResult* result = storage;
|
||||
|
||||
ffStrbufDestroy(&result->theme);
|
||||
ffStrbufDestroy(&result->icons);
|
||||
ffStrbufDestroy(&result->font);
|
||||
ffStrbufDestroy(&result->cursor);
|
||||
ffStrbufDestroy(&result->cursorSize);
|
||||
ffStrbufDestroy(&result->wallpaper);
|
||||
}
|
||||
|
||||
static void initGTK2Result(void* storage) {
|
||||
initGTKResult("2", storage);
|
||||
}
|
||||
|
||||
static void initGTK3Result(void* storage) {
|
||||
initGTKResult("3", storage);
|
||||
}
|
||||
|
||||
static void initGTK4Result(void* storage) {
|
||||
initGTKResult("4", storage);
|
||||
}
|
||||
|
||||
// Each version gets its own result and its own entry, so a refresh drops all three (each one is
|
||||
// then rebuilt on demand, in the same lazy order as a single-shot run). They share the single
|
||||
// `gtk-settings` entry above, which keeps a round at one settings query instead of three.
|
||||
#define FF_DETECT_GTK_IMPL(version) \
|
||||
static FFGTKResult result; \
|
||||
static FFcacheEntry entry = { \
|
||||
.name = "gtk" #version, \
|
||||
.storage = &result, \
|
||||
.init = initGTK##version##Result, \
|
||||
.destroy = destroyGTKResult, \
|
||||
}; \
|
||||
return ffCacheGet(&entry);
|
||||
|
||||
const FFGTKResult* ffDetectGTK2(void) {
|
||||
FF_DETECT_GTK_IMPL(2)
|
||||
@@ -216,4 +286,4 @@ const FFGTKResult* ffDetectGTK4(void) {
|
||||
FF_DETECT_GTK_IMPL(4)
|
||||
}
|
||||
|
||||
#undef FF_CALCULATE_GTK_IMPL
|
||||
#undef FF_DETECT_GTK_IMPL
|
||||
|
||||
+36
-21
@@ -1,7 +1,7 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/thread.h"
|
||||
#include "common/strutil.h"
|
||||
#include "common/FFcache.h"
|
||||
#include "detection/gtk_qt/gtk_qt.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
|
||||
@@ -172,38 +172,53 @@ static void detectKvantum(FFQtResult* result) {
|
||||
});
|
||||
}
|
||||
|
||||
const FFQtResult* ffDetectQt(void) {
|
||||
static FFQtResult result;
|
||||
static FFQtResult result;
|
||||
|
||||
static bool init = false;
|
||||
if (init) {
|
||||
return &result;
|
||||
}
|
||||
init = true;
|
||||
static void initQtResult(void* storage) {
|
||||
FFQtResult* qt = storage;
|
||||
|
||||
ffStrbufInit(&result.widgetStyle);
|
||||
ffStrbufInit(&result.colorScheme);
|
||||
ffStrbufInit(&result.icons);
|
||||
ffStrbufInit(&result.font);
|
||||
ffStrbufInit(&result.wallpaper);
|
||||
ffStrbufInit(&qt->widgetStyle);
|
||||
ffStrbufInit(&qt->colorScheme);
|
||||
ffStrbufInit(&qt->icons);
|
||||
ffStrbufInit(&qt->font);
|
||||
ffStrbufInit(&qt->wallpaper);
|
||||
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer();
|
||||
|
||||
if (ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA)) {
|
||||
detectPlasma(&result);
|
||||
detectPlasma(qt);
|
||||
} else if (ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT)) {
|
||||
detectLXQt(&result);
|
||||
detectLXQt(qt);
|
||||
} else {
|
||||
const char* qPlatformTheme = getenv("QT_QPA_PLATFORMTHEME");
|
||||
if (qPlatformTheme && (ffStrEquals(qPlatformTheme, "qt5ct") || ffStrEquals(qPlatformTheme, "qt6ct"))) {
|
||||
detectQtCt(qPlatformTheme[2], &result);
|
||||
detectQtCt(qPlatformTheme[2], qt);
|
||||
}
|
||||
}
|
||||
|
||||
if (ffStrbufEqualS(&result.widgetStyle, "kvantum") || ffStrbufEqualS(&result.widgetStyle, "kvantum-dark")) {
|
||||
ffStrbufClear(&result.widgetStyle);
|
||||
detectKvantum(&result);
|
||||
if (ffStrbufEqualS(&qt->widgetStyle, "kvantum") || ffStrbufEqualS(&qt->widgetStyle, "kvantum-dark")) {
|
||||
ffStrbufClear(&qt->widgetStyle);
|
||||
detectKvantum(qt);
|
||||
}
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
static void destroyQtResult(void* storage) {
|
||||
FFQtResult* qt = storage;
|
||||
|
||||
ffStrbufDestroy(&qt->widgetStyle);
|
||||
ffStrbufDestroy(&qt->colorScheme);
|
||||
ffStrbufDestroy(&qt->icons);
|
||||
ffStrbufDestroy(&qt->font);
|
||||
ffStrbufDestroy(&qt->wallpaper);
|
||||
}
|
||||
|
||||
static FFcacheEntry ffCacheEntryQt = {
|
||||
.name = "qt",
|
||||
.storage = &result,
|
||||
.init = initQtResult,
|
||||
.destroy = destroyQtResult,
|
||||
};
|
||||
|
||||
const FFQtResult* ffDetectQt(void) {
|
||||
return ffCacheGet(&ffCacheEntryQt);
|
||||
}
|
||||
|
||||
@@ -1,19 +1,53 @@
|
||||
#include "media.h"
|
||||
#include "common/FFcache.h"
|
||||
#include "common/io.h"
|
||||
|
||||
void ffDetectMediaImpl(FFMediaResult* media, bool saveCover);
|
||||
|
||||
static FFMediaResult result;
|
||||
|
||||
// The cover file of this run, if there is one. It is tracked here rather than in `result` because
|
||||
// the cached result is dropped between `--dynamic-interval` rounds, while the file has to stay on
|
||||
// disk for the whole run: the `kitty-direct` logo type lets the terminal open it by path, and the
|
||||
// logo is replayed from the line cache on every round.
|
||||
static FFstrbuf coverFile;
|
||||
static bool coverFileRegistered = false;
|
||||
|
||||
static void removeMediaCoverFile(void) {
|
||||
if (result.cover.length > 0) {
|
||||
ffRemoveFile(result.cover.chars);
|
||||
ffStrbufDestroy(&result.cover);
|
||||
if (coverFile.length > 0) {
|
||||
ffRemoveFile(coverFile.chars);
|
||||
ffStrbufDestroy(&coverFile);
|
||||
}
|
||||
}
|
||||
|
||||
static void destroyMediaResult(void* storage) {
|
||||
FFMediaResult* media = storage;
|
||||
|
||||
ffStrbufDestroy(&media->error);
|
||||
ffStrbufDestroy(&media->playerId);
|
||||
ffStrbufDestroy(&media->player);
|
||||
ffStrbufDestroy(&media->song);
|
||||
ffStrbufDestroy(&media->artist);
|
||||
ffStrbufDestroy(&media->album);
|
||||
ffStrbufDestroy(&media->url);
|
||||
ffStrbufDestroy(&media->status);
|
||||
ffStrbufDestroy(&media->cover);
|
||||
media->length = 0;
|
||||
media->position = 0;
|
||||
media->removeCoverAfterUse = false;
|
||||
}
|
||||
|
||||
// `saveCover` asks for a side effect and is not part of the cache identity, so the entry cannot be
|
||||
// initialized through `init(void*)`: the first caller of a generation decides, and the callers that
|
||||
// follow reuse its result, as they did when the result was cached for the whole run.
|
||||
static FFcacheEntry ffCacheEntryMedia = {
|
||||
.name = "media",
|
||||
.storage = &result,
|
||||
.destroy = destroyMediaResult,
|
||||
};
|
||||
|
||||
const FFMediaResult* ffDetectMedia(bool saveCover) {
|
||||
if (result.error.chars == nullptr) {
|
||||
if (ffCacheBeginInit(&ffCacheEntryMedia)) {
|
||||
ffStrbufInit(&result.error);
|
||||
ffStrbufInit(&result.playerId);
|
||||
ffStrbufInit(&result.player);
|
||||
@@ -37,7 +71,11 @@ const FFMediaResult* ffDetectMedia(bool saveCover) {
|
||||
ffStrbufTrimRightSpace(&result.player);
|
||||
|
||||
if (saveCover && result.removeCoverAfterUse) {
|
||||
atexit(removeMediaCoverFile);
|
||||
ffStrbufSet(&coverFile, &result.cover);
|
||||
if (!coverFileRegistered) {
|
||||
coverFileRegistered = true;
|
||||
atexit(removeMediaCoverFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+43
-16
@@ -1,21 +1,48 @@
|
||||
#include "os.h"
|
||||
#include "common/FFcache.h"
|
||||
|
||||
void ffDetectOSImpl(FFOSResult* os);
|
||||
|
||||
const FFOSResult* ffDetectOS(void) {
|
||||
static FFOSResult result;
|
||||
if (result.name.chars == nullptr) {
|
||||
ffStrbufInit(&result.name);
|
||||
ffStrbufInit(&result.prettyName);
|
||||
ffStrbufInit(&result.id);
|
||||
ffStrbufInit(&result.version);
|
||||
ffStrbufInit(&result.versionID);
|
||||
ffStrbufInit(&result.codename);
|
||||
ffStrbufInit(&result.buildID);
|
||||
ffStrbufInit(&result.idLike);
|
||||
ffStrbufInit(&result.variant);
|
||||
ffStrbufInit(&result.variantID);
|
||||
ffDetectOSImpl(&result);
|
||||
}
|
||||
return &result;
|
||||
static FFOSResult result;
|
||||
|
||||
static void initOSResult(void* storage) {
|
||||
FFOSResult* os = storage;
|
||||
|
||||
ffStrbufInit(&os->name);
|
||||
ffStrbufInit(&os->prettyName);
|
||||
ffStrbufInit(&os->id);
|
||||
ffStrbufInit(&os->version);
|
||||
ffStrbufInit(&os->versionID);
|
||||
ffStrbufInit(&os->codename);
|
||||
ffStrbufInit(&os->buildID);
|
||||
ffStrbufInit(&os->idLike);
|
||||
ffStrbufInit(&os->variant);
|
||||
ffStrbufInit(&os->variantID);
|
||||
ffDetectOSImpl(os);
|
||||
}
|
||||
|
||||
static void destroyOSResult(void* storage) {
|
||||
FFOSResult* os = storage;
|
||||
|
||||
ffStrbufDestroy(&os->name);
|
||||
ffStrbufDestroy(&os->prettyName);
|
||||
ffStrbufDestroy(&os->id);
|
||||
ffStrbufDestroy(&os->version);
|
||||
ffStrbufDestroy(&os->versionID);
|
||||
ffStrbufDestroy(&os->codename);
|
||||
ffStrbufDestroy(&os->buildID);
|
||||
ffStrbufDestroy(&os->idLike);
|
||||
ffStrbufDestroy(&os->variant);
|
||||
ffStrbufDestroy(&os->variantID);
|
||||
}
|
||||
|
||||
static FFcacheEntry ffCacheEntryOS = {
|
||||
.name = "os",
|
||||
.storage = &result,
|
||||
.init = initOSResult,
|
||||
.destroy = destroyOSResult,
|
||||
};
|
||||
|
||||
const FFOSResult* ffDetectOS(void) {
|
||||
return ffCacheGet(&ffCacheEntryOS);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "terminalshell.h"
|
||||
#include "common/FFcache.h"
|
||||
#include "common/io.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/processing.h"
|
||||
@@ -376,22 +377,43 @@ static void setTerminalInfoDetails(FFTerminalResult* result) {
|
||||
#define FF_EXE_PATH_LEN 260
|
||||
#endif
|
||||
|
||||
const FFShellResult* ffDetectShell() {
|
||||
static FFShellResult result;
|
||||
static bool init = false;
|
||||
if (init) {
|
||||
return &result;
|
||||
}
|
||||
init = true;
|
||||
static FFShellResult shellResult;
|
||||
|
||||
ffStrbufInit(&result.processName);
|
||||
ffStrbufInitA(&result.exe, FF_EXE_PATH_LEN);
|
||||
result.exeName = result.exe.chars;
|
||||
ffStrbufInit(&result.exePath);
|
||||
ffStrbufInit(&result.version);
|
||||
result.pid = 0;
|
||||
result.ppid = 0;
|
||||
result.tty = -1;
|
||||
static void destroyShellResult(void* storage) {
|
||||
FFShellResult* result = storage;
|
||||
|
||||
ffStrbufDestroy(&result->processName);
|
||||
ffStrbufDestroy(&result->exe);
|
||||
result->exeName = result->exe.chars; // `exeName` points into `exe`, which is empty again
|
||||
ffStrbufDestroy(&result->exePath);
|
||||
ffStrbufDestroy(&result->prettyName);
|
||||
ffStrbufDestroy(&result->version);
|
||||
result->pid = 0;
|
||||
result->ppid = 0;
|
||||
result->tty = -1;
|
||||
}
|
||||
|
||||
static FFcacheEntry ffCacheEntryShell = {
|
||||
.name = "shell",
|
||||
.storage = &shellResult,
|
||||
.destroy = destroyShellResult,
|
||||
};
|
||||
|
||||
const FFShellResult* ffDetectShell() {
|
||||
FFShellResult* result = &shellResult;
|
||||
|
||||
if (!ffCacheBeginInit(&ffCacheEntryShell)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ffStrbufInit(&result->processName);
|
||||
ffStrbufInitA(&result->exe, FF_EXE_PATH_LEN);
|
||||
result->exeName = result->exe.chars;
|
||||
ffStrbufInit(&result->exePath);
|
||||
ffStrbufInit(&result->version);
|
||||
result->pid = 0;
|
||||
result->ppid = 0;
|
||||
result->tty = -1;
|
||||
|
||||
pid_t ppid = getppid();
|
||||
|
||||
@@ -401,49 +423,70 @@ const FFShellResult* ffDetectShell() {
|
||||
ffProcessGetBasicInfoLinux(ppid, &_, &ppid, nullptr);
|
||||
}
|
||||
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
getUserShellFromEnv(&result);
|
||||
ppid = getShellInfo(result, ppid);
|
||||
getUserShellFromEnv(result);
|
||||
|
||||
if (result.processName.length > 0) {
|
||||
setShellInfoDetails(&result);
|
||||
if (result->processName.length > 0) {
|
||||
setShellInfoDetails(result);
|
||||
if (instance.config.general.detectVersion) {
|
||||
fftsGetShellVersion(result.exePath.length > 0 ? &result.exePath : &result.exe, result.exeName, &result.version);
|
||||
fftsGetShellVersion(result->exePath.length > 0 ? &result->exePath : &result->exe, result->exeName, &result->version);
|
||||
}
|
||||
}
|
||||
|
||||
return &result;
|
||||
return result;
|
||||
}
|
||||
|
||||
const FFTerminalResult* ffDetectTerminal() {
|
||||
static FFTerminalResult result;
|
||||
static bool init = false;
|
||||
if (init) {
|
||||
return &result;
|
||||
}
|
||||
init = true;
|
||||
static FFTerminalResult terminalResult;
|
||||
|
||||
ffStrbufInit(&result.processName);
|
||||
ffStrbufInitA(&result.exe, FF_EXE_PATH_LEN);
|
||||
result.exeName = result.exe.chars;
|
||||
ffStrbufInit(&result.exePath);
|
||||
ffStrbufInit(&result.version);
|
||||
ffStrbufInitS(&result.tty, ttyname(STDOUT_FILENO));
|
||||
result.pid = 0;
|
||||
result.ppid = 0;
|
||||
static void destroyTerminalResult(void* storage) {
|
||||
FFTerminalResult* result = storage;
|
||||
|
||||
ffStrbufDestroy(&result->processName);
|
||||
ffStrbufDestroy(&result->exe);
|
||||
result->exeName = result->exe.chars; // `exeName` points into `exe`, which is empty again
|
||||
ffStrbufDestroy(&result->exePath);
|
||||
ffStrbufDestroy(&result->prettyName);
|
||||
ffStrbufDestroy(&result->version);
|
||||
ffStrbufDestroy(&result->tty);
|
||||
result->pid = 0;
|
||||
result->ppid = 0;
|
||||
}
|
||||
|
||||
static FFcacheEntry ffCacheEntryTerminal = {
|
||||
.name = "terminal",
|
||||
.storage = &terminalResult,
|
||||
.destroy = destroyTerminalResult,
|
||||
};
|
||||
|
||||
const FFTerminalResult* ffDetectTerminal() {
|
||||
FFTerminalResult* result = &terminalResult;
|
||||
|
||||
if (!ffCacheBeginInit(&ffCacheEntryTerminal)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ffStrbufInit(&result->processName);
|
||||
ffStrbufInitA(&result->exe, FF_EXE_PATH_LEN);
|
||||
result->exeName = result->exe.chars;
|
||||
ffStrbufInit(&result->exePath);
|
||||
ffStrbufInit(&result->version);
|
||||
ffStrbufInitS(&result->tty, ttyname(STDOUT_FILENO));
|
||||
result->pid = 0;
|
||||
result->ppid = 0;
|
||||
|
||||
pid_t ppid = (pid_t) ffDetectShell()->ppid;
|
||||
|
||||
if (ppid) {
|
||||
ppid = getTerminalInfo(&result, ppid);
|
||||
ppid = getTerminalInfo(result, ppid);
|
||||
}
|
||||
getTerminalFromEnv(&result);
|
||||
getTerminalFromEnv(result);
|
||||
|
||||
if (result.processName.length > 0) {
|
||||
setTerminalInfoDetails(&result);
|
||||
if (result->processName.length > 0) {
|
||||
setTerminalInfoDetails(result);
|
||||
if (instance.config.general.detectVersion) {
|
||||
fftsGetTerminalVersion(&result.processName, result.exePath.length > 0 ? &result.exePath : &result.exe, &result.version);
|
||||
fftsGetTerminalVersion(&result->processName, result->exePath.length > 0 ? &result->exePath : &result->exe, &result->version);
|
||||
}
|
||||
}
|
||||
|
||||
return &result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "terminalshell.h"
|
||||
#include "common/FFcache.h"
|
||||
#include "common/io.h"
|
||||
#include "common/processing.h"
|
||||
#include "common/thread.h"
|
||||
@@ -293,27 +294,48 @@ static void setTerminalInfoDetails(FFTerminalResult* result) {
|
||||
}
|
||||
}
|
||||
|
||||
const FFShellResult* ffDetectShell(void) {
|
||||
static FFShellResult result;
|
||||
static bool init = false;
|
||||
if (init) {
|
||||
return &result;
|
||||
}
|
||||
init = true;
|
||||
static FFShellResult shellResult;
|
||||
|
||||
ffStrbufInit(&result.processName);
|
||||
ffStrbufInitA(&result.exe, MAX_PATH);
|
||||
result.exeName = "";
|
||||
ffStrbufInit(&result.exePath);
|
||||
ffStrbufInit(&result.prettyName);
|
||||
ffStrbufInit(&result.version);
|
||||
result.pid = 0;
|
||||
result.ppid = 0;
|
||||
result.tty = -1;
|
||||
static void destroyShellResult(void* storage) {
|
||||
FFShellResult* result = storage;
|
||||
|
||||
ffStrbufDestroy(&result->processName);
|
||||
ffStrbufDestroy(&result->exe);
|
||||
result->exeName = ""; // The `exe` buffer is empty again, so nothing points into it
|
||||
ffStrbufDestroy(&result->exePath);
|
||||
ffStrbufDestroy(&result->prettyName);
|
||||
ffStrbufDestroy(&result->version);
|
||||
result->pid = 0;
|
||||
result->ppid = 0;
|
||||
result->tty = -1;
|
||||
}
|
||||
|
||||
static FFcacheEntry ffCacheEntryShell = {
|
||||
.name = "shell",
|
||||
.storage = &shellResult,
|
||||
.destroy = destroyShellResult,
|
||||
};
|
||||
|
||||
const FFShellResult* ffDetectShell(void) {
|
||||
FFShellResult* result = &shellResult;
|
||||
|
||||
if (!ffCacheBeginInit(&ffCacheEntryShell)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ffStrbufInit(&result->processName);
|
||||
ffStrbufInitA(&result->exe, MAX_PATH);
|
||||
result->exeName = "";
|
||||
ffStrbufInit(&result->exePath);
|
||||
ffStrbufInit(&result->prettyName);
|
||||
ffStrbufInit(&result->version);
|
||||
result->pid = 0;
|
||||
result->ppid = 0;
|
||||
result->tty = -1;
|
||||
|
||||
uint32_t ppid;
|
||||
if (!ffProcessGetInfoWindows(0, &ppid, nullptr, nullptr, nullptr, nullptr, nullptr)) {
|
||||
return &result;
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* ignoreParent = getenv("FFTS_IGNORE_PARENT");
|
||||
@@ -321,60 +343,81 @@ const FFShellResult* ffDetectShell(void) {
|
||||
ffProcessGetInfoWindows(ppid, &ppid, nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
ppid = getShellInfo(result, ppid);
|
||||
|
||||
if (result.processName.length > 0) {
|
||||
setShellInfoDetails(&result);
|
||||
if (result->processName.length > 0) {
|
||||
setShellInfoDetails(result);
|
||||
char tmp[MAX_PATH];
|
||||
strcpy(tmp, result.exeName);
|
||||
strcpy(tmp, result->exeName);
|
||||
char* ext = strrchr(tmp, '.');
|
||||
if (ext) {
|
||||
*ext = '\0';
|
||||
}
|
||||
if (instance.config.general.detectVersion) {
|
||||
fftsGetShellVersion(result.exePath.length > 0 ? &result.exePath : &result.exe, tmp, &result.version);
|
||||
fftsGetShellVersion(result->exePath.length > 0 ? &result->exePath : &result->exe, tmp, &result->version);
|
||||
}
|
||||
}
|
||||
|
||||
return &result;
|
||||
return result;
|
||||
}
|
||||
|
||||
const FFTerminalResult* ffDetectTerminal(void) {
|
||||
static FFTerminalResult result;
|
||||
static bool init = false;
|
||||
if (init) {
|
||||
return &result;
|
||||
}
|
||||
init = true;
|
||||
static FFTerminalResult terminalResult;
|
||||
|
||||
ffStrbufInit(&result.processName);
|
||||
ffStrbufInitA(&result.exe, MAX_PATH);
|
||||
result.exeName = "";
|
||||
ffStrbufInit(&result.exePath);
|
||||
ffStrbufInit(&result.prettyName);
|
||||
ffStrbufInit(&result.version);
|
||||
ffStrbufInit(&result.tty);
|
||||
result.pid = 0;
|
||||
result.ppid = 0;
|
||||
static void destroyTerminalResult(void* storage) {
|
||||
FFTerminalResult* result = storage;
|
||||
|
||||
ffStrbufDestroy(&result->processName);
|
||||
ffStrbufDestroy(&result->exe);
|
||||
result->exeName = ""; // The `exe` buffer is empty again, so nothing points into it
|
||||
ffStrbufDestroy(&result->exePath);
|
||||
ffStrbufDestroy(&result->prettyName);
|
||||
ffStrbufDestroy(&result->version);
|
||||
ffStrbufDestroy(&result->tty);
|
||||
result->pid = 0;
|
||||
result->ppid = 0;
|
||||
}
|
||||
|
||||
static FFcacheEntry ffCacheEntryTerminal = {
|
||||
.name = "terminal",
|
||||
.storage = &terminalResult,
|
||||
.destroy = destroyTerminalResult,
|
||||
};
|
||||
|
||||
const FFTerminalResult* ffDetectTerminal(void) {
|
||||
FFTerminalResult* result = &terminalResult;
|
||||
|
||||
if (!ffCacheBeginInit(&ffCacheEntryTerminal)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ffStrbufInit(&result->processName);
|
||||
ffStrbufInitA(&result->exe, MAX_PATH);
|
||||
result->exeName = "";
|
||||
ffStrbufInit(&result->exePath);
|
||||
ffStrbufInit(&result->prettyName);
|
||||
ffStrbufInit(&result->version);
|
||||
ffStrbufInit(&result->tty);
|
||||
result->pid = 0;
|
||||
result->ppid = 0;
|
||||
|
||||
uint32_t ppid = ffDetectShell()->ppid;
|
||||
if (ppid) {
|
||||
getTerminalInfo(&result, ppid);
|
||||
getTerminalInfo(result, ppid);
|
||||
}
|
||||
|
||||
if (result.processName.length == 0) {
|
||||
getTerminalFromEnv(&result);
|
||||
if (result->processName.length == 0) {
|
||||
getTerminalFromEnv(result);
|
||||
}
|
||||
if (result.processName.length == 0) {
|
||||
detectDefaultTerminal(&result);
|
||||
if (result->processName.length == 0) {
|
||||
detectDefaultTerminal(result);
|
||||
}
|
||||
|
||||
if (result.processName.length > 0) {
|
||||
setTerminalInfoDetails(&result);
|
||||
if (result->processName.length > 0) {
|
||||
setTerminalInfoDetails(result);
|
||||
if (instance.config.general.detectVersion) {
|
||||
fftsGetTerminalVersion(&result.processName, result.exePath.length > 0 ? &result.exePath : &result.exe, &result.version);
|
||||
fftsGetTerminalVersion(&result->processName, result->exePath.length > 0 ? &result->exePath : &result->exe, &result->version);
|
||||
}
|
||||
}
|
||||
|
||||
return &result;
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user