diff --git a/src/common/detectGTK.c b/src/common/detectGTK.c index dd3c69d93..cb09b25e4 100644 --- a/src/common/detectGTK.c +++ b/src/common/detectGTK.c @@ -171,84 +171,22 @@ static void detectGTK(FFinstance* instance, const char* version, const char* env return; } - //From DIR: XDG_CONFIG_HOME + //From config dirs - const char* xdgConfigHome = getenv("XDG_CONFIG_HOME"); - ffStrbufSetS(&buffer, xdgConfigHome); - detectGTKFromConfigDir(&buffer, version, result); - if(allPropertiesSet(result)) + //We need to do this because we use multiple threads on configDirs + FFstrbuf baseDirCopy; + ffStrbufInitA(&baseDirCopy, 64); + + for(uint32_t i = 0; i < instance->state.configDirs.length; i++) { - ffStrbufDestroy(&buffer); - return; - } - - //From DIRs: XDG_CONFIG_DIRS - - ffStrbufSetS(&buffer, getenv("XDG_CONFIG_DIRS")); - lastIndex = 0; - while (lastIndex < buffer.length) - { - uint32_t colonIndex = ffStrbufFirstIndexAfterC(&buffer, lastIndex, ':'); - buffer.chars[colonIndex] = '\0'; - - FFstrbuf configDir; - ffStrbufInitA(&configDir, 64); - ffStrbufAppendS(&configDir, buffer.chars + lastIndex); - - detectGTKFromConfigDir(&configDir, version, result); - - ffStrbufDestroy(&configDir); - + FFstrbuf* baseDir = (FFstrbuf*) ffListGet(&instance->state.configDirs, i); + ffStrbufSet(&baseDirCopy, baseDir); + detectGTKFromConfigDir(&baseDirCopy, version, result); if(allPropertiesSet(result)) - { - ffStrbufDestroy(&buffer); - return; - } - - lastIndex = colonIndex + 1; + break; } - //From DIR: ~/.config/ - - ffStrbufSetS(&buffer, instance->state.passwd->pw_dir); - lastIndex = buffer.length; - - ffStrbufAppendS(&buffer, "/.config"); - if(ffStrbufCompS(&buffer, xdgConfigHome) != 0) - { - detectGTKFromConfigDir(&buffer, version, result); - if(allPropertiesSet(result)) - { - ffStrbufDestroy(&buffer); - return; - } - } - - //From DIR: ~/ - - ffStrbufSubstrBefore(&buffer, lastIndex); - detectGTKFromConfigDir(&buffer, version, result); - if(allPropertiesSet(result)) - { - ffStrbufDestroy(&buffer); - return; - } - - //From DIR: /etc/xdg/ - - ffStrbufSetS(&buffer, "/etc/xdg"); - detectGTKFromConfigDir(&buffer, version, result); - if(allPropertiesSet(result)) - { - ffStrbufDestroy(&buffer); - return; - } - - //From DIR: /etc/ - - ffStrbufSetS(&buffer, "/etc"); - detectGTKFromConfigDir(&buffer, version, result); - + ffStrbufDestroy(&baseDirCopy); ffStrbufDestroy(&buffer); } diff --git a/src/common/detectPlasma.c b/src/common/detectPlasma.c index 13e7ac079..abae61ce3 100644 --- a/src/common/detectPlasma.c +++ b/src/common/detectPlasma.c @@ -11,35 +11,11 @@ typedef enum PlasmaCategory PLASMA_CATEGORY_OTHER } PlasmaCategory; -const FFPlasmaResult* ffDetectPlasma(FFinstance* instance) +static bool detectFromConfigFile(const FFstrbuf* filename, FFPlasmaResult* result) { - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - static FFPlasmaResult result; - static bool init = false; - pthread_mutex_lock(&mutex); - if(init) - { - pthread_mutex_unlock(&mutex); - return &result; - } - init = true; - - ffStrbufInit(&result.widgetStyle); - ffStrbufInit(&result.colorScheme); - ffStrbufInit(&result.icons); - ffStrbufInit(&result.font); - - FF_STRBUF_CREATE(kdeglobalsFile); - ffStrbufAppendS(&kdeglobalsFile, instance->state.passwd->pw_dir); - ffStrbufAppendS(&kdeglobalsFile, "/.config/kdeglobals"); - - FILE* kdeglobals = fopen(kdeglobalsFile.chars, "r"); + FILE* kdeglobals = fopen(filename->chars, "r"); if(kdeglobals == NULL) - { - ffStrbufDestroy(&kdeglobalsFile); - pthread_mutex_unlock(&mutex); - return &result; - } + return false; char* line = NULL; size_t len = 0; @@ -67,34 +43,86 @@ const FFPlasmaResult* ffDetectPlasma(FFinstance* instance) if(category == PLASMA_CATEGORY_KDE) { - sscanf(line, "widgetStyle=%[^\n]", result.widgetStyle.chars); - sscanf(line, "widgetStyle=\"%[^\"]+", result.widgetStyle.chars); + sscanf(line, "widgetStyle=%[^\n]", result->widgetStyle.chars); + sscanf(line, "widgetStyle=\"%[^\"]+", result->widgetStyle.chars); } else if(category == PLASMA_CATEGORY_GENERAL) { - sscanf(line, "ColorScheme=%[^\n]", result.colorScheme.chars); - sscanf(line, "ColorScheme=\"%[^\"]+", result.colorScheme.chars); + sscanf(line, "ColorScheme=%[^\n]", result->colorScheme.chars); + sscanf(line, "ColorScheme=\"%[^\"]+", result->colorScheme.chars); - sscanf(line, "font=%[^\n]", result.font.chars); - sscanf(line, "font=\"%[^\"]+", result.font.chars); + sscanf(line, "font=%[^\n]", result->font.chars); + sscanf(line, "font=\"%[^\"]+", result->font.chars); } else if(category == PLASMA_CATEGORY_ICONS) { - sscanf(line, "Theme=%[^\n]", result.icons.chars); - sscanf(line, "Theme=\"%[^\"]+", result.icons.chars); + sscanf(line, "Theme=%[^\n]", result->icons.chars); + sscanf(line, "Theme=\"%[^\"]+", result->icons.chars); } } - ffStrbufRecalculateLength(&result.widgetStyle); - ffStrbufRecalculateLength(&result.colorScheme); - ffStrbufRecalculateLength(&result.icons); - ffStrbufRecalculateLength(&result.font); + ffStrbufRecalculateLength(&result->widgetStyle); + ffStrbufRecalculateLength(&result->colorScheme); + ffStrbufRecalculateLength(&result->icons); + ffStrbufRecalculateLength(&result->font); if(line != NULL) free(line); fclose(kdeglobals); - ffStrbufDestroy(&kdeglobalsFile); + + return true; +} + +const FFPlasmaResult* ffDetectPlasma(FFinstance* instance) +{ + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static FFPlasmaResult result; + static bool init = false; + pthread_mutex_lock(&mutex); + if(init) + { + pthread_mutex_unlock(&mutex); + return &result; + } + init = true; + + ffStrbufInit(&result.widgetStyle); + ffStrbufInit(&result.colorScheme); + ffStrbufInit(&result.icons); + ffStrbufInit(&result.font); + + bool foundAFile = false; + + //We need to do this because we use multiple threads on configDirs + FFstrbuf baseDirCopy; + ffStrbufInitA(&baseDirCopy, 64); + + for(uint32_t i = 0; i < instance->state.configDirs.length; i++) + { + FFstrbuf* baseDir = (FFstrbuf*) ffListGet(&instance->state.configDirs, i); + + ffStrbufSet(&baseDirCopy, baseDir); + ffStrbufAppendS(&baseDirCopy, "/kdeglobals"); + + if(detectFromConfigFile(&baseDirCopy, &result)) + foundAFile = true; + + if( + result.widgetStyle.length > 0 && + result.colorScheme.length > 0 && + result.icons.length > 0 && + result.font.length > 0 + ) break; + } + + ffStrbufDestroy(&baseDirCopy); + + if(!foundAFile) + { + pthread_mutex_unlock(&mutex); + return &result; + } //In Plasma the default value is never set in the config file, but the whole key-value is discarded. ///We must set these values by our self if the file exists (it always does here) @@ -111,6 +139,5 @@ const FFPlasmaResult* ffDetectPlasma(FFinstance* instance) ffStrbufAppendS(&result.font, "Noto Sans, 10"); pthread_mutex_unlock(&mutex); - return &result; } diff --git a/src/common/init.c b/src/common/init.c index 8c7d78f49..dbebfbd46 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -2,12 +2,76 @@ #include +static bool strbufEqualsAdapter(const void* first, const void* second) +{ + return ffStrbufComp(second, first) == 0; +} + +static void initConfigDirs(FFstate* state) +{ + ffListInit(&state->configDirs, sizeof(FFstrbuf)); + + const char* xdgConfigHome = getenv("XDG_CONFIG_HOME"); + if(xdgConfigHome != NULL) + { + FFstrbuf* buffer = (FFstrbuf*) ffListAdd(&state->configDirs); + ffStrbufInitA(buffer, 64); + ffStrbufAppendS(buffer, xdgConfigHome); + ffStrbufTrimRight(buffer, '/'); + } + + FFstrbuf xdgConfigDirs; + ffStrbufInitAS(&xdgConfigDirs, 64, getenv("XDG_CONFIG_DIRS")); + uint32_t lastIndex = 0; + while (lastIndex < xdgConfigDirs.length) + { + uint32_t colonIndex = ffStrbufFirstIndexAfterC(&xdgConfigDirs, lastIndex, ':'); + xdgConfigDirs.chars[colonIndex] = '\0'; + + FFstrbuf* buffer = (FFstrbuf*) ffListAdd(&state->configDirs); + ffStrbufInitA(buffer, 64); + ffStrbufAppendS(buffer, xdgConfigDirs.chars + lastIndex); + ffStrbufTrimRight(buffer, '/'); + + lastIndex = colonIndex + 1; + } + + #define FF_ENSURE_ONLY_ONCE_IN_LIST(element) \ + if(ffListFirstIndexComp(&state->configDirs, element, strbufEqualsAdapter) < state->configDirs.length - 1) \ + --state->configDirs.length; + + FFstrbuf* userConfigHome = ffListAdd(&state->configDirs); + ffStrbufInitA(userConfigHome, 64); + ffStrbufAppendS(userConfigHome, state->passwd->pw_dir); + ffStrbufAppendS(userConfigHome, "/.config"); + FF_ENSURE_ONLY_ONCE_IN_LIST(userConfigHome) + + FFstrbuf* userHome = ffListAdd(&state->configDirs); + ffStrbufInitA(userHome, 64); + ffStrbufAppendS(userHome, state->passwd->pw_dir); + FF_ENSURE_ONLY_ONCE_IN_LIST(userHome) + + FFstrbuf* systemConfigHome = ffListAdd(&state->configDirs); + ffStrbufInitA(systemConfigHome, 64); + ffStrbufAppendS(systemConfigHome, "/etc/xdg"); + FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfigHome) + + FFstrbuf* systemConfig = ffListAdd(&state->configDirs); + ffStrbufInitA(systemConfig, 64); + ffStrbufAppendS(systemConfig, "/etc"); + FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfig) + + #undef FF_ENSURE_ONLY_ONCE_IN_LIST +} + static void initState(FFstate* state) { state->current_row = 0; state->passwd = getpwuid(getuid()); uname(&state->utsname); sysinfo(&state->sysinfo); + + initConfigDirs(state); } static void defaultConfig(FFconfig* config) diff --git a/src/common/io.c b/src/common/io.c index ebb929e8d..7e0fcf12f 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -364,6 +364,32 @@ bool ffParsePropFileHome(FFinstance* instance, const char* relativeFile, const c return result; } +bool ffParsePropFileConfig(FFinstance* instance, const char* relativeFile, const char* regex, char* buffer) +{ + bool foundAFile = false; + + for(uint32_t i = 0; i < instance->state.configDirs.length; i++) + { + FFstrbuf* baseDir = (FFstrbuf*) ffListGet(&instance->state.configDirs, i); + uint32_t baseDirLength = baseDir->length; + + if(*relativeFile != '/') + ffStrbufAppendC(baseDir, '/'); + + ffStrbufAppendS(baseDir, relativeFile); + + if(ffParsePropFile(baseDir->chars, regex, buffer)) + foundAFile = true; + + ffStrbufSubstrBefore(baseDir, baseDirLength); + + if(*buffer != '\0') + return foundAFile; + } + + return foundAFile; +} + bool ffWriteFDContent(int fd, const FFstrbuf* content) { return write(fd, content->chars, content->length) != -1; diff --git a/src/fastfetch.c b/src/fastfetch.c index 900cc0568..774d83214 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -894,52 +894,36 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con static void parseDefaultConfigFile(FFinstance* instance, FFdata* data) { - FFstrbuf filename; - ffStrbufInitA(&filename, 64); + FFstrbuf* filename = ffListGet(&instance->state.configDirs, 0); + uint32_t filenameLength = filename->length; - const char* xdgConfig = getenv("XDG_CONFIG_HOME"); - if(xdgConfig == NULL) + mkdir(filename->chars, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH); //I hope everybody has a config folder but whow knews + + ffStrbufAppendS(filename, "/fastfetch/"); + mkdir(filename->chars, S_IRWXU | S_IRGRP | S_IROTH); + + ffStrbufAppendS(filename, "config.conf"); + + if(access(filename->chars, F_OK) != 0) { - ffStrbufAppendS(&filename, instance->state.passwd->pw_dir); - ffStrbufAppendS(&filename, "/.config"); + FILE* file = fopen(filename->chars, "w"); + if(file != NULL) + { + fputs(FASTFETCH_DEFAULT_CONFIG, file); + fclose(file); + } } else { - ffStrbufAppendS(&filename, xdgConfig); - } - mkdir(filename.chars, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH); //I hope everybody has a config folder but whow knews - - ffStrbufAppendS(&filename, "/fastfetch/"); - mkdir(filename.chars, S_IRWXU | S_IRGRP | S_IROTH); - - ffStrbufAppendS(&filename, "config.conf"); - - if(access(filename.chars, F_OK) != 0) - { - FILE* file = fopen(filename.chars, "w"); - if(file == NULL) + FILE* file = fopen(filename->chars, "r"); + if(file != NULL) { - ffStrbufDestroy(&filename); - return; + parseConfigFile(instance, data, file); + fclose(file); } - - fputs(FASTFETCH_DEFAULT_CONFIG, file); - fclose(file); - } - else - { - FILE* file = fopen(filename.chars, "r"); - if(file == NULL) - { - ffStrbufDestroy(&filename); - return; - } - - parseConfigFile(instance, data, file); - fclose(file); } - ffStrbufDestroy(&filename); + ffStrbufSubstrBefore(filename, filenameLength); } static void parseArguments(FFinstance* instance, FFdata* data, int argc, const char** argv) diff --git a/src/fastfetch.h b/src/fastfetch.h index 114738e36..f55a5da36 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -159,6 +159,8 @@ typedef struct FFstate struct passwd* passwd; struct utsname utsname; struct sysinfo sysinfo; + + FFlist configDirs; } FFstate; typedef struct FFinstance @@ -242,6 +244,7 @@ void ffWriteFileContent(const char* fileName, const FFstrbuf* buffer); // They return true if the file was found, independently if regex was found bool ffParsePropFile(const char* file, const char* regex, char* buffer); bool ffParsePropFileHome(FFinstance* instance, const char* relativeFile, const char* regex, char* buffer); +bool ffParsePropFileConfig(FFinstance* instance, const char* relativeFile, const char* regex, char* buffer); //common/processing.c void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]); diff --git a/src/modules/terminalfont.c b/src/modules/terminalfont.c index 8436cdd3a..df910dd4e 100644 --- a/src/modules/terminalfont.c +++ b/src/modules/terminalfont.c @@ -35,7 +35,7 @@ static void printTerminalFont(FFinstance* instance, const char* font) static void printKonsole(FFinstance* instance) { char profile[128]; - ffParsePropFileHome(instance, ".config/konsolerc", "DefaultProfile=%[^\n]", profile); + ffParsePropFileConfig(instance, "konsolerc", "DefaultProfile=%[^\n]", profile); if(profile[0] == '\0') { ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, FF_TERMFONT_NUM_FORMAT_ARGS, "Couldn't find \"DefaultProfile=%[^\n]\" in \".config/konsolerc\""); @@ -59,7 +59,7 @@ static void printKonsole(FFinstance* instance) static void printXFCE4Terminal(FFinstance* instance) { char font[128]; - ffParsePropFileHome(instance, ".config/xfce4/terminal/terminalrc", "FontName=%[^\n]", font); + ffParsePropFileConfig(instance, "xfce4/terminal/terminalrc", "FontName=%[^\n]", font); if(font[0] == '\0') { ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, FF_TERMFONT_NUM_FORMAT_ARGS, "Couldn't find \"FontName=%%[^\\n]\" in \".config/xfce4/terminal/terminalrc\""); diff --git a/src/modules/wmtheme.c b/src/modules/wmtheme.c index 99a9cfed6..bc6859926 100644 --- a/src/modules/wmtheme.c +++ b/src/modules/wmtheme.c @@ -22,7 +22,7 @@ static void printWMTheme(FFinstance* instance, const char* theme) static void printKWin(FFinstance* instance) { char theme[256]; - bool fileFound = ffParsePropFileHome(instance, ".config/kwinrc", "theme=%s", theme); + bool fileFound = ffParsePropFileConfig(instance, "kwinrc", "theme=%s", theme); if(*theme == '\0') { diff --git a/src/util/FFlist.c b/src/util/FFlist.c index 1af070eb3..7c3b64253 100644 --- a/src/util/FFlist.c +++ b/src/util/FFlist.c @@ -33,6 +33,17 @@ void* ffListAdd(FFlist* list) return adress; } +uint32_t ffListFirstIndexComp(FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*)) +{ + for(uint32_t i = 0; i < list->length; i++) + { + if(compFunc(ffListGet(list, i), compElement)) + return i; + } + + return list->length; +} + void ffListDestroy(FFlist* list) { free(list->data); diff --git a/src/util/FFlist.h b/src/util/FFlist.h index 73f85efe2..3a0ab4f8d 100644 --- a/src/util/FFlist.h +++ b/src/util/FFlist.h @@ -3,6 +3,7 @@ #ifndef FF_INCLUDED_FFLIST #define FF_INCLUDED_FFLIST +#include #include #define FF_LIST_DEFAULT_ALLOC 16 @@ -22,6 +23,8 @@ void* ffListGet(FFlist* list, uint32_t index); void* ffListAdd(FFlist* list); +uint32_t ffListFirstIndexComp(FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*)); + void ffListDestroy(FFlist* list); #endif diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index 2bb1420a8..6d7b2d13c 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -256,7 +256,7 @@ void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file) int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp) { - return ffStrbufCompNS(strbuf, comp->length, comp->chars); + return ffStrbufCompS(strbuf, comp->chars); } int ffStrbufCompS(const FFstrbuf* strbuf, const char* comp) @@ -264,14 +264,9 @@ int ffStrbufCompS(const FFstrbuf* strbuf, const char* comp) return strcmp(strbuf->chars, comp); } -int ffStrbufCompNS(const FFstrbuf* strbuf, uint32_t length, const char* comp) -{ - return strncasecmp(strbuf->chars, comp, length); -} - int ffStrbufIgnCaseComp(const FFstrbuf* strbuf, const FFstrbuf* comp) { - return ffStrbufIgnCaseCompNS(strbuf, comp->length, comp->chars); + return ffStrbufIgnCaseCompS(strbuf, comp->chars); } int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, const char* comp) @@ -279,11 +274,6 @@ int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, const char* comp) return strcasecmp(strbuf->chars, comp); } -int ffStrbufIgnCaseCompNS(const FFstrbuf* strbuf, uint32_t length, const char* comp) -{ - return strncasecmp(strbuf->chars, comp, length); -} - void ffStrbufTrimLeft(FFstrbuf* strbuf, char c) { uint32_t index = 0; diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 2bf6af8ea..5a8985427 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -58,11 +58,9 @@ void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file); int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp); int ffStrbufCompS(const FFstrbuf* strbuf, const char* comp); -int ffStrbufCompNS(const FFstrbuf* strbuf, uint32_t length, const char* comp); int ffStrbufIgnCaseComp(const FFstrbuf* strbuf, const FFstrbuf* comp); int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, const char* comp); -int ffStrbufIgnCaseCompNS(const FFstrbuf* strbuf, uint32_t length, const char* comp); void ffStrbufTrimLeft(FFstrbuf* strbuf, char c); void ffStrbufTrimRight(FFstrbuf* strbuf, char c);