diff --git a/presets/devinfo b/presets/devinfo index 475c503bb..cbfd43092 100644 --- a/presets/devinfo +++ b/presets/devinfo @@ -1,3 +1,4 @@ --disable-linewrap false --multithreading false --show-errors true +--recache diff --git a/src/common/detectGTK.c b/src/common/detectGTK.c index 7c1475f6e..957517b5b 100644 --- a/src/common/detectGTK.c +++ b/src/common/detectGTK.c @@ -1,6 +1,5 @@ #include "fastfetch.h" -#include #include static inline bool allPropertiesSet(FFGTKResult* result) diff --git a/src/common/settings.c b/src/common/settings.c index 81565bd30..ba3f073df 100644 --- a/src/common/settings.c +++ b/src/common/settings.c @@ -1,50 +1,57 @@ #include "fastfetch.h" -#include #include -typedef void* DynamicLibrary; - -#define FF_VARIANT_NULL ((FFvariant){.strValue = NULL}) - -#define FF_LIBRARY_LOAD(libraryNameUser, libraryNameDefault, mutex, returnValue) ({ \ - void* addr = dlopen(libraryNameUser.length == 0 ? libraryNameDefault : libraryNameUser.chars, RTLD_LAZY); \ - if(addr == NULL) { \ - pthread_mutex_unlock(&mutex); \ - return returnValue; \ - } \ - addr; \ -}) - -#define FF_LIBRARY_ERROR_RETURN(library, mutex, returnValue) { \ - pthread_mutex_unlock(&mutex); \ - dlclose(library); \ - return returnValue; \ -} - -#define FF_LIBRARY_DEFINE_SYMBOL_FIELD(symbolName) __typeof__(&symbolName) ff ## symbolName - -#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, mutex, returnValue) ({ \ - void* fn = dlsym(library, symbolName); \ - if(fn == NULL) \ - FF_LIBRARY_ERROR_RETURN(library, mutex, returnValue); \ - fn; \ -}) - -#define FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(object, library, symbolName, mutex, returnValue) \ - object.ff ## symbolName = FF_LIBRARY_LOAD_SYMBOL(library, #symbolName, mutex, returnValue) - #ifdef FF_HAVE_GIO #include +#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, libraryName, userLibraryName) \ + static dataObject data; \ + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \ + static FFInitState initState = FF_INITSTATE_UNINITIALIZED; \ + pthread_mutex_lock(&mutex); \ + if(initState != FF_INITSTATE_UNINITIALIZED) {\ + pthread_mutex_unlock(&mutex); \ + return initState == FF_INITSTATE_SUCCESSFUL ? &data : NULL; \ + } \ + initState = FF_INITSTATE_SUCCESSFUL; \ + void* libraryHandle = dlopen(userLibraryName.length == 0 ? libraryName : userLibraryName.chars, RTLD_LAZY); \ + if(dlerror() != NULL || libraryHandle == NULL) { \ + initState = FF_INITSTATE_FAILED; \ + pthread_mutex_unlock(&mutex); \ + return NULL; \ + } \ + +#define FF_LIBRARY_DATA_LOAD_SYMBOL(symbolName) \ + data.ff ## symbolName = dlsym(libraryHandle, #symbolName); \ + if(dlerror() != NULL || data.ff ## symbolName == NULL) { \ + dlclose(libraryHandle); \ + initState = FF_INITSTATE_FAILED; \ + pthread_mutex_unlock(&mutex); \ + return NULL; \ + } + +#define FF_LIBRARY_DATA_LOAD_RETURN \ + initState = FF_INITSTATE_SUCCESSFUL; \ + pthread_mutex_unlock(&mutex); \ + return &data; + +#define FF_LIBRARY_DATA_LOAD_ERROR \ + { \ + dlclose(libraryHandle); \ + initState = FF_INITSTATE_FAILED; \ + pthread_mutex_unlock(&mutex); \ + return NULL; \ + } + typedef struct GVariantGetters { - FF_LIBRARY_DEFINE_SYMBOL_FIELD(g_variant_get_string); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(g_variant_get_boolean); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(g_variant_get_int32); + FF_LIBRARY_SYMBOL(g_variant_get_string) + FF_LIBRARY_SYMBOL(g_variant_get_boolean) + FF_LIBRARY_SYMBOL(g_variant_get_int32) } GVariantGetters; -static FFvariant getGVariantValue(GVariant* variant, FFvarianttype type, GVariantGetters* variantGetters) +static FFvariant getGVariantValue(GVariant* variant, FFvarianttype type, const GVariantGetters* variantGetters) { if(variant == NULL) return FF_VARIANT_NULL; @@ -60,26 +67,53 @@ static FFvariant getGVariantValue(GVariant* variant, FFvarianttype type, GVarian typedef struct GSettingsData { + FF_LIBRARY_SYMBOL(g_settings_schema_source_lookup) + FF_LIBRARY_SYMBOL(g_settings_schema_has_key) + FF_LIBRARY_SYMBOL(g_settings_new_full) + FF_LIBRARY_SYMBOL(g_settings_get_value) + FF_LIBRARY_SYMBOL(g_settings_get_user_value) + FF_LIBRARY_SYMBOL(g_settings_get_default_value) + FF_LIBRARY_SYMBOL(g_settings_schema_source_get_default) GSettingsSchemaSource* schemaSource; - FF_LIBRARY_DEFINE_SYMBOL_FIELD(g_settings_schema_source_lookup); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(g_settings_schema_has_key); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(g_settings_new_full); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(g_settings_get_value); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(g_settings_get_user_value); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(g_settings_get_default_value); GVariantGetters variantGetters; } GSettingsData; -static FFvariant getGSettingsValue(GSettingsData* data, const char* schemaName, const char* path, const char* key, FFvarianttype type) +static const GSettingsData* getGSettingsData(FFinstance* instance) { - if(data->schemaSource == NULL) + FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, "libgio-2.0.so", instance->config.libGIO) + + FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_lookup) + FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_has_key) + FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_new_full) + FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_get_value) + FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_get_user_value) + FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_get_default_value) + FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_get_default) + + #define data data.variantGetters + FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_string) + FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_boolean) + FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_int32) + #undef data + + data.schemaSource = data.ffg_settings_schema_source_get_default(); + if(data.schemaSource == NULL) + FF_LIBRARY_DATA_LOAD_ERROR + + FF_LIBRARY_DATA_LOAD_RETURN +} + +FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type) +{ + const GSettingsData* data = getGSettingsData(instance); + if(data == NULL) return FF_VARIANT_NULL; GSettingsSchema* schema = data->ffg_settings_schema_source_lookup(data->schemaSource, schemaName, true); if(schema == NULL) return FF_VARIANT_NULL; - if(data->ffg_settings_schema_has_key(schema, key) == 0) + if(data->ffg_settings_schema_has_key(schema, key) == false) return FF_VARIANT_NULL; GSettings* settings = data->ffg_settings_new_full(schema, NULL, path); @@ -97,45 +131,6 @@ static FFvariant getGSettingsValue(GSettingsData* data, const char* schemaName, variant = data->ffg_settings_get_default_value(settings, key); return getGVariantValue(variant, type, &data->variantGetters); } - -FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type) -{ - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - static bool init = false; - - static GSettingsData data; - - pthread_mutex_lock(&mutex); - - if(init) - { - pthread_mutex_unlock(&mutex); - return getGSettingsValue(&data, schemaName, path, key, type); - } - init = true; - - data.schemaSource = NULL; //error indicator - - DynamicLibrary library = FF_LIBRARY_LOAD(instance->config.libGIO, "libgio-2.0.so", mutex, FF_VARIANT_NULL); - - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, g_settings_schema_source_lookup, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, g_settings_schema_has_key, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, g_settings_new_full, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, g_settings_get_value, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, g_settings_get_user_value, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, g_settings_get_default_value, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data.variantGetters, library, g_variant_get_string, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data.variantGetters, library, g_variant_get_boolean, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data.variantGetters, library, g_variant_get_int32, mutex, FF_VARIANT_NULL); - - GSettingsSchemaSource*(*ffg_settings_schema_source_get_default)(void) = FF_LIBRARY_LOAD_SYMBOL(library, "g_settings_schema_source_get_default", mutex, FF_VARIANT_NULL); - if((data.schemaSource = ffg_settings_schema_source_get_default()) == NULL) - FF_LIBRARY_ERROR_RETURN(library, mutex, FF_VARIANT_NULL); - - pthread_mutex_unlock(&mutex); - return getGSettingsValue(&data, schemaName, path, key, type); -} - #else //FF_HAVE_GIO FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type) { @@ -149,14 +144,36 @@ FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, c typedef struct DConfData { - FF_LIBRARY_DEFINE_SYMBOL_FIELD(dconf_client_read_full); + FF_LIBRARY_SYMBOL(dconf_client_read_full) + FF_LIBRARY_SYMBOL(dconf_client_new) GVariantGetters variantGetters; DConfClient* client; } DConfData; -static FFvariant getDConfValue(DConfData* data, const char* key, FFvarianttype type) +static const DConfData* getDConfData(FFinstance* instance) { - if(data->client == NULL) + FF_LIBRARY_DATA_LOAD_INIT(DConfData, "libdconf.so", instance->config.libDConf) + + FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_read_full) + FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new) + + #define data data.variantGetters + FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_string) + FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_boolean) + FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_int32) + #undef data + + data.client = data.ffdconf_client_new(); + if(data.client == NULL) + FF_LIBRARY_DATA_LOAD_ERROR + + FF_LIBRARY_DATA_LOAD_RETURN +} + +FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type) +{ + const DConfData* data = getDConfData(instance); + if(data == NULL) return FF_VARIANT_NULL; GVariant* variant = data->ffdconf_client_read_full(data->client, key, DCONF_READ_FLAGS_NONE, NULL); @@ -170,40 +187,6 @@ static FFvariant getDConfValue(DConfData* data, const char* key, FFvarianttype t variant = data->ffdconf_client_read_full(data->client, key, DCONF_READ_DEFAULT_VALUE, NULL); return getGVariantValue(variant, type, &data->variantGetters); } - -FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type) -{ - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - static bool init = false; - - static DConfData data; - - pthread_mutex_lock(&mutex); - - if(init) - { - pthread_mutex_unlock(&mutex); - return getDConfValue(&data, key, type); - } - init = true; - - data.client = NULL; //error indicator - - DynamicLibrary library = FF_LIBRARY_LOAD(instance->config.libDConf, "libdconf.so", mutex, FF_VARIANT_NULL); - - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, dconf_client_read_full, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data.variantGetters, library, g_variant_get_string, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data.variantGetters, library, g_variant_get_boolean, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data.variantGetters, library, g_variant_get_int32, mutex, FF_VARIANT_NULL); - - DConfClient*(*ffdconf_client_new)(void) = FF_LIBRARY_LOAD_SYMBOL(library, "dconf_client_new", mutex, FF_VARIANT_NULL); - if((data.client = ffdconf_client_new()) == NULL) - FF_LIBRARY_ERROR_RETURN(library, mutex, FF_VARIANT_NULL); - - pthread_mutex_unlock(&mutex); - return getDConfValue(&data, key, type); -} - #else //FF_HAVE_DCONF FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type) { @@ -229,17 +212,35 @@ FFvariant ffSettingsGet(FFinstance* instance, const char* dconfKey, const char* typedef struct XFConfData { - bool init; - FF_LIBRARY_DEFINE_SYMBOL_FIELD(xfconf_channel_get); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(xfconf_channel_has_property); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(xfconf_channel_get_string); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(xfconf_channel_get_bool); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(xfconf_channel_get_int); + FF_LIBRARY_SYMBOL(xfconf_channel_get) + FF_LIBRARY_SYMBOL(xfconf_channel_has_property) + FF_LIBRARY_SYMBOL(xfconf_channel_get_string) + FF_LIBRARY_SYMBOL(xfconf_channel_get_bool) + FF_LIBRARY_SYMBOL(xfconf_channel_get_int) + FF_LIBRARY_SYMBOL(xfconf_init) } XFConfData; -static FFvariant getXFConfValue(XFConfData* data, const char* channelName, const char* propertyName, FFvarianttype type) +static const XFConfData* getXFConfData(FFinstance* instance) { - if(!data->init) + FF_LIBRARY_DATA_LOAD_INIT(XFConfData, "libxfconf-0.so", instance->config.libXFConf) + + FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get) + FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_has_property) + FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get_string) + FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get_bool) + FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get_int) + FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_init) + + if(data.ffxfconf_init(NULL) == FALSE) + FF_LIBRARY_DATA_LOAD_ERROR + + FF_LIBRARY_DATA_LOAD_RETURN +} + +FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type) +{ + const XFConfData* data = getXFConfData(instance); + if(data == NULL) return FF_VARIANT_NULL; XfconfChannel* channel = data->ffxfconf_channel_get(channelName); // Never fails according to documentation but rather returns an empty channel @@ -258,41 +259,6 @@ static FFvariant getXFConfValue(XFConfData* data, const char* channelName, const return FF_VARIANT_NULL; } - -FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type) -{ - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - static bool init = false; - - static XFConfData data; - - pthread_mutex_lock(&mutex); - - if(init) - { - pthread_mutex_unlock(&mutex); - return getXFConfValue(&data, channelName, propertyName, type); - } - init = true; - - data.init = false; //error indicator - - DynamicLibrary library = FF_LIBRARY_LOAD(instance->config.libXFConf, "libxfconf-0.so", mutex, FF_VARIANT_NULL); - - - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, xfconf_channel_get, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, xfconf_channel_has_property, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, xfconf_channel_get_string, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, xfconf_channel_get_bool, mutex, FF_VARIANT_NULL); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, xfconf_channel_get_int, mutex, FF_VARIANT_NULL); - - gboolean(*ffxfconf_init)(GError **) = FF_LIBRARY_LOAD_SYMBOL(library, "xfconf_init", mutex, FF_VARIANT_NULL); - if((data.init = ffxfconf_init(NULL)) == FALSE) - FF_LIBRARY_ERROR_RETURN(library, mutex, FF_VARIANT_NULL); - - pthread_mutex_unlock(&mutex); - return getXFConfValue(&data, channelName, propertyName, type); -} #else //FF_HAVE_XFCONF FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type) { @@ -301,82 +267,6 @@ FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, con } #endif //FF_HAVE_XFCONF -#ifdef FF_HAVE_RPM -#include -#include -#include -#include - -typedef struct LibrpmData -{ - FF_LIBRARY_DEFINE_SYMBOL_FIELD(rpmReadConfigFiles); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(rpmtsCreate); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(rpmtsInitIterator); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(rpmdbGetIteratorCount); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(rpmdbFreeIterator); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(rpmtsFree); - FF_LIBRARY_DEFINE_SYMBOL_FIELD(rpmlogSetMask); -} LibrpmData; - -uint32_t getRpmPackageCount(LibrpmData* data) { - // Don't print any error messages - data->ffrpmlogSetMask(RPMLOG_MASK(RPMLOG_EMERG)); - - uint32_t count = 0; - rpmts ts = NULL; - rpmdbMatchIterator mi = NULL; - - if (data->ffrpmReadConfigFiles(NULL, NULL)) goto exit; - if (!(ts = data->ffrpmtsCreate())) goto exit; - if (!(mi = data->ffrpmtsInitIterator(ts, RPMDBI_LABEL, NULL, 0))) goto exit; - count = data->ffrpmdbGetIteratorCount(mi); - -exit: - if (mi) data->ffrpmdbFreeIterator(mi); - if (ts) data->ffrpmtsFree(ts); - return count; -} - -uint32_t ffSettingsGetRpmPackageCount(FFinstance* instance) -{ - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - static bool init = false; - - static LibrpmData data; - - pthread_mutex_lock(&mutex); - - if(init) - { - pthread_mutex_unlock(&mutex); - return getRpmPackageCount(&data); - } - init = true; - - // As `data` is a static variable, it's already zero inited. - // data.ffrpmtsCreate = NULL; - - DynamicLibrary library = FF_LIBRARY_LOAD(instance->config.librpm, "librpm.so", mutex, 0); - - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, rpmReadConfigFiles, mutex, 0); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, rpmtsCreate, mutex, 0); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, rpmtsInitIterator, mutex, 0); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, rpmdbGetIteratorCount, mutex, 0); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, rpmdbFreeIterator, mutex, 0); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, rpmtsFree, mutex, 0); - FF_LIBRARY_LOAD_SYMBOL_TO_OBJECT(data, library, rpmlogSetMask, mutex, 0); - - pthread_mutex_unlock(&mutex); - return getRpmPackageCount(&data); -} -#else //FF_HAVE_RPM -uint32_t ffSettingsGetRpmPackageCount(FFinstance* instance) -{ - FF_UNUSED(instance); - return 0; -} -#endif //FF_HAVE_RPM - #ifdef __ANDROID__ #include void ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) { diff --git a/src/fastfetch.h b/src/fastfetch.h index b95906cc6..3e28c228b 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -12,6 +12,7 @@ #include #include #include +#include #include "fastfetch_config.h" @@ -247,6 +248,8 @@ typedef union FFvariant }; } FFvariant; +#define FF_VARIANT_NULL ((FFvariant){.strValue = NULL}) + typedef struct FFfont { FFstrbuf pretty; @@ -261,6 +264,33 @@ typedef struct FFpropquery FFstrbuf* buffer; } FFpropquery; +typedef enum FFInitState +{ + FF_INITSTATE_UNINITIALIZED = 0, + FF_INITSTATE_SUCCESSFUL = 1, + FF_INITSTATE_FAILED = 2 +} FFInitState; + +#define FF_LIBRARY_SYMBOL(symbolName) \ + __typeof__(&symbolName) ff ## symbolName; + + +#define FF_LIBRARY_LOAD(libraryObjectName, libraryName, userLibraryName, returnValue) \ + void* libraryObjectName = dlopen(userLibraryName.length == 0 ? libraryName : userLibraryName.chars, RTLD_LAZY); \ + if(dlerror() != NULL || libraryObjectName == NULL) \ + return returnValue; + +#define FF_LIBRARY_LOAD_SYMBOL_ADRESS(library, symbolMapping, symbolName, returnValue) \ + symbolMapping = dlsym(library, #symbolName); \ + if(dlerror() != NULL || symbolMapping == NULL) \ + { \ + dlclose(library); \ + return returnValue; \ + } + +#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \ + __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADRESS(library, ff ## symbolName, symbolName, returnValue); + /*************************/ /* Common util functions */ /*************************/ diff --git a/src/modules/gpu.c b/src/modules/gpu.c index ca65f0394..9c404061e 100644 --- a/src/modules/gpu.c +++ b/src/modules/gpu.c @@ -14,7 +14,6 @@ void ffPrintGPU(FFinstance* instance) #else -#include #include static void printGPU(FFinstance* instance, struct pci_access* pacc, struct pci_dev* dev, FFcache* cache, uint8_t counter, char*(*ffpci_lookup_name)(struct pci_access*, char*, int, int, ...)) @@ -59,66 +58,19 @@ static void printGPU(FFinstance* instance, struct pci_access* pacc, struct pci_d ffStrbufDestroy(&namePretty); } -void ffPrintGPU(FFinstance* instance) +static const char* printGPUs(FFinstance* instance) { if(ffPrintFromCache(instance, FF_GPU_MODULE_NAME, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS)) - return; + return NULL; - const char* pciLibName = instance->config.libPCI.length == 0 ? "libpci.so" : instance->config.libPCI.chars; - void* pci = dlopen(pciLibName, RTLD_LAZY); - if(pci == NULL) - { - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlopen(\"%s\", RTLD_LAZY) == NULL", pciLibName); - return; - } + FF_LIBRARY_LOAD(pci, "libpci.so", instance->config.libPCI, "gpu: dlopen of libpci failed") - struct pci_access*(*ffpci_alloc)() = dlsym(pci, "pci_alloc"); - if(ffpci_alloc == NULL) - { - dlclose(pci); - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_alloc\") == NULL"); - return; - } - - void(*ffpci_init)(struct pci_access*) = dlsym(pci, "pci_init"); - if(ffpci_init == NULL) - { - dlclose(pci); - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_init\") == NULL"); - return; - } - - void(*ffpci_scan_bus)(struct pci_access*) = dlsym(pci, "pci_scan_bus"); - if(ffpci_scan_bus == NULL) - { - dlclose(pci); - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_init\") == NULL"); - return; - } - - int(*ffpci_fill_info)(struct pci_dev*, int) = dlsym(pci, "pci_fill_info"); - if(ffpci_fill_info == NULL) - { - dlclose(pci); - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_fill_info\") == NULL"); - return; - } - - char*(*ffpci_lookup_name)(struct pci_access*, char*, int, int, ...) = dlsym(pci, "pci_lookup_name"); - if(ffpci_lookup_name == NULL) - { - dlclose(pci); - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_lookup_name\") == NULL"); - return; - } - - void(*ffpci_cleanup)(struct pci_access*) = dlsym(pci, "pci_cleanup"); - if(ffpci_cleanup == NULL) - { - dlclose(pci); - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_cleanup\") == NULL"); - return; - } + FF_LIBRARY_LOAD_SYMBOL(pci, pci_alloc, "gpu: dlsym of pci_alloc failed") + FF_LIBRARY_LOAD_SYMBOL(pci, pci_init, "gpu: dlsym of pci_init failed") + FF_LIBRARY_LOAD_SYMBOL(pci, pci_scan_bus, "gpu: dlsym of pci_scan_bus failed") + FF_LIBRARY_LOAD_SYMBOL(pci, pci_fill_info, "gpu: dlsym of pci_fill_info failed") + FF_LIBRARY_LOAD_SYMBOL(pci, pci_lookup_name, "gpu: dlsym of pci_lookup_name failed") + FF_LIBRARY_LOAD_SYMBOL(pci, pci_cleanup, "gpu: dlsym of pci_cleanup failed") struct pci_access *pacc = ffpci_alloc(); ffpci_init(pacc); @@ -146,13 +98,18 @@ void ffPrintGPU(FFinstance* instance) for(uint32_t i = 0; i < devices.length; i++) printGPU(instance, pacc, *(struct pci_dev**)ffListGet(&devices, i), &cache, devices.length == 1 ? 0 : i + 1, ffpci_lookup_name); - if(devices.length == 0) - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "No GPU found"); - ffCacheClose(&cache); ffListDestroy(&devices); ffpci_cleanup(pacc); dlclose(pci); + return devices.length > 0 ? NULL : "No GPU found"; +} + +void ffPrintGPU(FFinstance* instance) +{ + const char* error = printGPUs(instance); + if(error != NULL) + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, error); } #endif diff --git a/src/modules/packages.c b/src/modules/packages.c index 93d2b0a9e..08de71977 100644 --- a/src/modules/packages.c +++ b/src/modules/packages.c @@ -6,6 +6,44 @@ #define FF_PACKAGES_MODULE_NAME "Packages" #define FF_PACKAGES_NUM_FORMAT_ARGS 8 +#ifdef FF_HAVE_RPM +#include +#include +#include +#include + +static uint32_t getRpmPackageCount(FFinstance* instance) +{ + FF_LIBRARY_LOAD(rpm, "librpm.so", instance->config.librpm, 0); + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmReadConfigFiles, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsCreate, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsInitIterator, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmdbGetIteratorCount, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmdbFreeIterator, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsFree, 0) + FF_LIBRARY_LOAD_SYMBOL(rpm, rpmlogSetMask, 0) + + // Don't print any error messages + ffrpmlogSetMask(RPMLOG_MASK(RPMLOG_EMERG)); + + uint32_t count = 0; + rpmts ts = NULL; + rpmdbMatchIterator mi = NULL; + + if (ffrpmReadConfigFiles(NULL, NULL)) goto exit; + if (!(ts = ffrpmtsCreate())) goto exit; + if (!(mi = ffrpmtsInitIterator(ts, RPMDBI_LABEL, NULL, 0))) goto exit; + count = ffrpmdbGetIteratorCount(mi); + +exit: + if (mi) ffrpmdbFreeIterator(mi); + if (ts) ffrpmtsFree(ts); + dlclose(rpm); + return count; +} + +#endif + static uint32_t getNumElements(const char* dirname, unsigned char type) { DIR* dirp = opendir(dirname); @@ -58,11 +96,16 @@ void ffPrintPackages(FFinstance* instance) uint32_t pacman = getNumElements("/var/lib/pacman/local", DT_DIR); uint32_t dpkg = getNumStrings("/var/lib/dpkg/status", "Status: "); -#if __ANDROID__ - dpkg += getNumStrings("/data/data/com.termux/files/usr/var/lib/dpkg/status", "Status: "); -#endif + #if __ANDROID__ + dpkg += getNumStrings("/data/data/com.termux/files/usr/var/lib/dpkg/status", "Status: "); + #endif + + #ifdef FF_HAVE_RPM + uint32_t rpm = getRpmPackageCount(instance); + #else + uint32_t rpm = 0; + #endif - uint32_t rpm = ffSettingsGetRpmPackageCount(instance); uint32_t xbps = getNumElements("/var/db/xbps", DT_REG); uint32_t flatpak = getNumElements("/var/lib/flatpak/app", DT_DIR); uint32_t snap = getNumElements("/snap", DT_DIR); diff --git a/src/modules/resolution.c b/src/modules/resolution.c index 8f2b349f5..b2393adc3 100644 --- a/src/modules/resolution.c +++ b/src/modules/resolution.c @@ -1,25 +1,12 @@ #include "fastfetch.h" #include -#include #include #include #define FF_RESOLUTION_MODULE_NAME "Resolution" #define FF_RESOLUTION_NUM_FORMAT_ARGS 3 -typedef void* DynamicLibrary; - -#define FF_LIBRARY_LOAD(libraryNameUser, libraryNameDefault) dlopen(libraryNameUser.length == 0 ? libraryNameDefault : libraryNameUser.chars, RTLD_LAZY); \ - if(dlerror() != NULL) \ - return false; - -#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName) dlsym(library, symbolName); \ - if(dlerror() != NULL) { \ - dlclose(library); \ - return false; \ - } - typedef struct ResolutionResult { int width; @@ -157,10 +144,9 @@ static void x11AddScreenAsResult(FFlist* results, Screen* screen, int refreshRat static bool printResolutionX11Backend(FFinstance* instance) { - DynamicLibrary x11 = FF_LIBRARY_LOAD(instance->config.libX11, "libX11.so"); - - Display*(*ffXOpenDisplay)(const char*) = FF_LIBRARY_LOAD_SYMBOL(x11, "XOpenDisplay"); - int(*ffXCloseDisplay)(Display*) = FF_LIBRARY_LOAD_SYMBOL(x11, "XCloseDisplay"); + FF_LIBRARY_LOAD(x11, "libX11.so", instance->config.libX11, false) + FF_LIBRARY_LOAD_SYMBOL(x11, XOpenDisplay, false) + FF_LIBRARY_LOAD_SYMBOL(x11, XCloseDisplay, false) Display* display = ffXOpenDisplay(x11); if(display == NULL) @@ -188,17 +174,18 @@ static bool printResolutionX11Backend(FFinstance* instance) typedef struct XrandrData { - XRRScreenConfiguration*(*ffXRRGetScreenInfo)(Display* display, Window window); - short(*ffXRRConfigCurrentRate)(XRRScreenConfiguration* config); - XRRMonitorInfo*(*ffXRRGetMonitors)(Display* display, Window window, Bool getActive, int* nmonitors); - XRRScreenResources*(*ffXRRGetScreenResources)(Display* display, Window window); - XRROutputInfo*(*ffXRRGetOutputInfo)(Display* display, XRRScreenResources* resources, RROutput output); - XRRCrtcInfo*(*ffXRRGetCrtcInfo)(Display* display, XRRScreenResources* resources, RRCrtc crtc); - void(*ffXRRFreeCrtcInfo)(XRRCrtcInfo* crtcInfo); - void(*ffXRRFreeOutputInfo)(XRROutputInfo* outputInfo); - void(*ffXRRFreeScreenResources)(XRRScreenResources* resources); - void(*ffXRRFreeMonitors)(XRRMonitorInfo* monitors); - void(*ffXRRFreeScreenConfigInfo)(XRRScreenConfiguration* config); + FF_LIBRARY_SYMBOL(XRRGetScreenInfo) + FF_LIBRARY_SYMBOL(XRRConfigCurrentConfiguration) + FF_LIBRARY_SYMBOL(XRRConfigCurrentRate) + FF_LIBRARY_SYMBOL(XRRGetMonitors) + FF_LIBRARY_SYMBOL(XRRGetScreenResources) + FF_LIBRARY_SYMBOL(XRRGetOutputInfo) + FF_LIBRARY_SYMBOL(XRRGetCrtcInfo) + FF_LIBRARY_SYMBOL(XRRFreeCrtcInfo) + FF_LIBRARY_SYMBOL(XRRFreeOutputInfo) + FF_LIBRARY_SYMBOL(XRRFreeScreenResources) + FF_LIBRARY_SYMBOL(XRRFreeMonitors) + FF_LIBRARY_SYMBOL(XRRFreeScreenConfigInfo) //Init once Display* display; @@ -331,24 +318,24 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen) static bool printResolutionXrandrBackend(FFinstance* instance) { - DynamicLibrary xrandr = FF_LIBRARY_LOAD(instance->config.libXrandr, "libXrandr.so"); + FF_LIBRARY_LOAD(xrandr, "libXrandr.so", instance->config.libXrandr, false); - Display*(*ffXOpenDisplay)(const char*) = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XOpenDisplay"); - int(*ffXCloseDisplay)(Display*) = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XCloseDisplay"); + FF_LIBRARY_LOAD_SYMBOL(xrandr, XOpenDisplay, false) + FF_LIBRARY_LOAD_SYMBOL(xrandr, XCloseDisplay, false) XrandrData data; - data.ffXRRGetScreenInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRGetScreenInfo"); - data.ffXRRConfigCurrentRate = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRConfigCurrentRate"); - data.ffXRRGetMonitors = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRGetMonitors"); - data.ffXRRGetScreenResources = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRGetScreenResources"); - data.ffXRRGetOutputInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRGetOutputInfo"); - data.ffXRRGetCrtcInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRGetCrtcInfo"); - data.ffXRRFreeCrtcInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRFreeCrtcInfo"); - data.ffXRRFreeOutputInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRFreeOutputInfo"); - data.ffXRRFreeScreenResources = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRFreeScreenResources"); - data.ffXRRFreeMonitors = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRFreeMonitors"); - data.ffXRRFreeScreenConfigInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRFreeScreenConfigInfo"); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRGetScreenInfo, XRRGetScreenInfo, false) + FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRConfigCurrentRate, XRRConfigCurrentRate, false); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRGetMonitors, XRRGetMonitors, false); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRGetScreenResources, XRRGetScreenResources, false); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRGetOutputInfo, XRRGetOutputInfo, false); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRGetCrtcInfo, XRRGetCrtcInfo, false); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeCrtcInfo, XRRFreeCrtcInfo, false); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeOutputInfo, XRRFreeOutputInfo, false); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeScreenResources, XRRFreeScreenResources, false); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeMonitors, XRRFreeMonitors, false); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeScreenConfigInfo, XRRFreeScreenConfigInfo, false); data.display = ffXOpenDisplay(NULL); if(data.display == NULL) @@ -376,9 +363,9 @@ typedef struct WaylandData { FFinstance* instance; FFlist results; - struct wl_proxy*(*ffwl_proxy_marshal_constructor_versioned)(struct wl_proxy*, uint32_t, const struct wl_interface*, uint32_t, ...); - int(*ffwl_proxy_add_listener)(struct wl_proxy*, void (**)(void), void *data); - void(*ffwl_proxy_destroy)(struct wl_proxy*); + FF_LIBRARY_SYMBOL(wl_proxy_marshal_constructor_versioned) + FF_LIBRARY_SYMBOL(wl_proxy_add_listener) + FF_LIBRARY_SYMBOL(wl_proxy_destroy) const struct wl_interface* ffwl_output_interface; struct wl_output_listener output_listener; } WaylandData; @@ -453,21 +440,21 @@ static bool printResolutionWaylandBackend(FFinstance* instance) if(sessionType != NULL && strcasecmp(sessionType, "wayland") != 0) return false; - DynamicLibrary wayland = FF_LIBRARY_LOAD(instance->config.libWayland, "libwayland-client.so"); + FF_LIBRARY_LOAD(wayland, "libwayland-client.so", instance->config.libWayland, false); - struct wl_display*(*ffwl_display_connect)(const char*) = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_display_connect"); - int(*ffwl_display_dispatch)(struct wl_display*) = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_display_dispatch"); - void(*ffwl_display_roundtrip)(struct wl_display*) = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_display_roundtrip"); - struct wl_proxy*(*ffwl_proxy_marshal_constructor)(struct wl_proxy*, uint32_t, const struct wl_interface*, ...) = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_proxy_marshal_constructor"); - const struct wl_interface* ffwl_registry_interface = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_registry_interface"); - void(*ffwl_display_disconnect)(struct wl_display*) = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_display_disconnect"); + FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_connect, false) + FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_dispatch, false) + FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_roundtrip, false) + FF_LIBRARY_LOAD_SYMBOL(wayland, wl_proxy_marshal_constructor, false) + FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_disconnect, false) + FF_LIBRARY_LOAD_SYMBOL(wayland, wl_registry_interface, false) WaylandData data; - data.ffwl_proxy_marshal_constructor_versioned = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_proxy_marshal_constructor_versioned"); - data.ffwl_proxy_add_listener = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_proxy_add_listener"); - data.ffwl_output_interface = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_output_interface"); - data.ffwl_proxy_destroy = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_proxy_destroy"); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_marshal_constructor_versioned, wl_proxy_marshal_constructor_versioned, false) + FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_add_listener, wl_proxy_add_listener, false) + FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_output_interface, wl_output_interface, false) + FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_destroy, wl_proxy_destroy, false) struct wl_display* display = ffwl_display_connect(NULL); if(display == NULL)