Merge pull request #291 from CarterLi/dev

Windows: improve Win32 API compatibility
This commit is contained in:
Linus Dierheimer
2022-10-12 16:00:45 +02:00
committed by GitHub
24 changed files with 491 additions and 434 deletions
+28 -13
View File
@@ -23,6 +23,17 @@ if(MSYS)
enable_language(CXX)
endif()
#############################
# Compile time dependencies #
#############################
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
find_package(PkgConfig REQUIRED)
include(CheckIncludeFile)
#####################
# Configure options #
#####################
@@ -52,21 +63,11 @@ cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR MSYS" OFF)
cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR MSYS" OFF)
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND AND NOT ANDROID" OFF)
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
#############################
# Compile time dependencies #
#############################
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
find_package(PkgConfig REQUIRED)
include(CheckIncludeFile)
####################
# Compiler options #
####################
@@ -76,6 +77,15 @@ if(NOT CMAKE_BUILD_TYPE)
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
if(ENABLE_THREADS)
if(CMAKE_USE_PTHREADS_INIT)
message(STATUS "Threads type: pthread")
else()
message(STATUS "Threads type: Win32 thread")
endif()
else()
message(STATUS "Threads type: disabled")
endif()
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion")
@@ -355,8 +365,8 @@ if(MSYS)
src/detection/font/font_windows.cpp
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalshell/terminalshell_windows.cpp
src/detection/terminalfont/terminalfont_linux.c
src/detection/packages/packages_linux.c
src/detection/terminalfont/terminalfont_windows.c
src/detection/packages/packages_windows.c
src/detection/kernel/kernel_windows.cpp
src/detection/localip/localip_windows.c
@@ -482,6 +492,11 @@ ff_lib_enable(OPENCL OpenCL)
ff_lib_enable(LIBCJSON libcjson)
ff_lib_enable(FREETYPE freetype2)
if(ENABLE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS)
target_link_libraries(libfastfetch PRIVATE Threads::Threads)
endif()
if(APPLE)
target_link_libraries(libfastfetch
PRIVATE "-framework CoreFoundation"
@@ -501,6 +516,7 @@ elseif(MSYS)
PRIVATE "opengl32"
PRIVATE "gdi32"
PRIVATE "iphlpapi"
PRIVATE "ws2_32"
)
endif()
@@ -511,7 +527,6 @@ target_include_directories(libfastfetch
target_link_libraries(libfastfetch
PRIVATE ${CMAKE_DL_LIBS}
PRIVATE Threads::Threads
)
######################
+2 -1
View File
@@ -21,9 +21,10 @@ There are some premade config files in [`presets`](presets), including the ones
## Dependencies
Fastfetch dynamically loads needed libraries if they are available. Therefore its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and `libpthread`. They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions, so you probably don't have to worry about it.
Fastfetch dynamically loads needed libraries if they are available. Therefore its only hard dependencies are `libc` (any implementation of the c standard library), `libdl`. They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions, so you probably don't have to worry about it.
The following libraries are used if present at runtime:
* [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html): For multithreading support, which may improve performance
* [`libpci`](https://github.com/pciutils/pciutils): GPU output.
* [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output.
* [`libxcb-randr`](https://xcb.freedesktop.org/),
+21 -69
View File
@@ -1,6 +1,7 @@
#include "fastfetch.h"
#include "common/caching.h"
#include "common/parsing.h"
#include "common/thread.h"
#include "detection/qt.h"
#include "detection/gtk.h"
#include "detection/displayserver/displayserver.h"
@@ -9,7 +10,6 @@
#include <unistd.h>
#include <sys/stat.h>
#include <signal.h>
#include <pthread.h>
static bool strbufEqualsAdapter(const void* first, const void* second)
{
@@ -259,87 +259,39 @@ void ffInitInstance(FFinstance* instance)
defaultConfig(instance);
}
#if !defined(__ANDROID__) && !defined(_WIN32) && !defined(__MSYS__)
#ifdef FF_HAVE_THREADS
static void* connectDisplayServerThreadMain(void* instance)
{
ffConnectDisplayServer((FFinstance*)instance);
return NULL;
}
FF_THREAD_ENTRY_DECL_WRAPPER(ffConnectDisplayServer, FFinstance*)
#if !defined(__APPLE__)
#if !(defined(__APPLE__) || defined(__MSYS__) || defined(_WIN32))
static void* detectPlasmaThreadMain(void* instance)
{
ffDetectQt((FFinstance*)instance);
return NULL;
}
#define FF_DETECT_QT_GTK 1
static void* detectGTK2ThreadMain(void* instance)
{
ffDetectGTK2((FFinstance*)instance);
return NULL;
}
FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectQt, FFinstance*)
FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK2, FFinstance*)
FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK3, FFinstance*)
FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK4, FFinstance*)
static void* detectGTK3ThreadMain(void* instance)
{
ffDetectGTK3((FFinstance*)instance);
return NULL;
}
#endif //!(defined(__APPLE__) || defined(__MSYS__) || defined(_WIN32))
static void* detectGTK4ThreadMain(void* instance)
{
ffDetectGTK4((FFinstance*)instance);
return NULL;
}
static void* startThreadsThreadMain(void* instance)
{
pthread_t dsThread;
pthread_create(&dsThread, NULL, connectDisplayServerThreadMain, instance);
pthread_detach(dsThread);
pthread_t gtk2Thread;
pthread_create(&gtk2Thread, NULL, detectGTK2ThreadMain, instance);
pthread_detach(gtk2Thread);
pthread_t gtk3Thread;
pthread_create(&gtk3Thread, NULL, detectGTK3ThreadMain, instance);
pthread_detach(gtk3Thread);
pthread_t gtk4Thread;
pthread_create(&gtk4Thread, NULL, detectGTK4ThreadMain, instance);
pthread_detach(gtk4Thread);
pthread_t plasmaThread;
pthread_create(&plasmaThread, NULL, detectPlasmaThreadMain, instance);
pthread_detach(plasmaThread);
return NULL;
}
#endif //FF_HAVE_THREADS
void startDetectionThreads(FFinstance* instance)
{
pthread_t startThreadsThread;
pthread_create(&startThreadsThread, NULL, startThreadsThreadMain, instance);
pthread_detach(startThreadsThread);
}
#ifdef FF_HAVE_THREADS
ffThreadCreateAndDetach(ffConnectDisplayServerThreadMain, instance);
#else // !__APPLE__
void startDetectionThreads(FFinstance* instance)
{
pthread_t startThreadsThread;
pthread_create(&startThreadsThread, NULL, connectDisplayServerThreadMain, instance);
pthread_detach(startThreadsThread);
}
#endif // __APPLE__
#ifdef FF_DETECT_QT_GTK
ffThreadCreateAndDetach(ffDetectQtThreadMain, instance);
ffThreadCreateAndDetach(ffDetectGTK2ThreadMain, instance);
ffThreadCreateAndDetach(ffDetectGTK3ThreadMain, instance);
ffThreadCreateAndDetach(ffDetectGTK4ThreadMain, instance);
#endif
#else // !__ANDROID__
void startDetectionThreads(FFinstance* instance)
{
#else
FF_UNUSED(instance);
#endif
}
#endif // __ANDROID__
static volatile bool ffDisableLinewrap = true;
static volatile bool ffHideCursor = true;
+48 -18
View File
@@ -1,13 +1,43 @@
#if defined(_WIN32) || defined(__MSYS__)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <synchapi.h>
static BOOL WINAPI initWsaData(PINIT_ONCE once, PVOID param, PVOID* context)
{
(void)once;
(void)param;
static WSADATA wsaData;
*context = &wsaData;
return WSAStartup(MAKEWORD(2, 2), &wsaData) == 0;
}
//Types of winsock2 are full of mess. Disable warnings for them and keep clean for posix
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#else
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
#define closesocket close
#endif
//Must be included after <winsock2.h>
#include "fastfetch.h"
#include "common/networking.h"
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout)
FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout)
{
#if defined(_WIN32) || defined(__MSYS__)
static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
WSADATA* pData;
if(!InitOnceExecuteOnce(&once, initWsaData, NULL, (LPVOID*) &pData))
return INVALID_SOCKET;
#endif
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
@@ -16,13 +46,13 @@ int ffNetworkingSendHttpRequest(const char* host, const char* path, const char*
struct addrinfo* addr;
if(getaddrinfo(host, "80", &hints, &addr) != 0)
return -1;
return INVALID_SOCKET;
int sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if(sockfd == -1)
FFSockType sockfd = (FFSockType)socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if(sockfd == INVALID_SOCKET)
{
freeaddrinfo(addr);
return -1;
return INVALID_SOCKET;
}
if(timeout > 0)
@@ -35,9 +65,9 @@ int ffNetworkingSendHttpRequest(const char* host, const char* path, const char*
if(connect(sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
{
close(sockfd);
closesocket(sockfd);
freeaddrinfo(addr);
return -1;
return INVALID_SOCKET;
}
freeaddrinfo(addr);
@@ -55,14 +85,14 @@ int ffNetworkingSendHttpRequest(const char* host, const char* path, const char*
if(send(sockfd, command.chars, command.length, 0) == -1)
{
ffStrbufDestroy(&command);
close(sockfd);
return -1;
closesocket(sockfd);
return INVALID_SOCKET;
}
ffStrbufDestroy(&command);
return sockfd;
}
bool ffNetworkingRecvHttpResponse(int sockfd, FFstrbuf* buffer)
bool ffNetworkingRecvHttpResponse(FFSockType sockfd, FFstrbuf* buffer)
{
ssize_t received = recv(sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
@@ -72,14 +102,14 @@ bool ffNetworkingRecvHttpResponse(int sockfd, FFstrbuf* buffer)
buffer->chars[buffer->length] = '\0';
}
close(sockfd);
closesocket(sockfd);
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
}
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer)
{
int sockfd = ffNetworkingSendHttpRequest(host, path, headers, timeout);
if(sockfd > 0)
FFSockType sockfd = ffNetworkingSendHttpRequest(host, path, headers, timeout);
if(sockfd != INVALID_SOCKET)
return ffNetworkingRecvHttpResponse(sockfd, buffer);
return false;
}
+12 -2
View File
@@ -5,8 +5,18 @@
#include "util/FFstrbuf.h"
int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout);
bool ffNetworkingRecvHttpResponse(int sock, FFstrbuf* buffer);
#if defined(_WIN32) || defined(__MSYS__)
typedef uintptr_t FFSockType; //SOCKET, unsigned
#ifndef INVALID_SOCKET //Don't conflict with <winsock2.h>
#define INVALID_SOCKET ((uintptr_t)~0)
#endif
#else
typedef int FFSockType; // signed
#define INVALID_SOCKET (-1)
#endif
FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout);
bool ffNetworkingRecvHttpResponse(FFSockType sockfd, FFstrbuf* buffer);
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer);
#endif
+1 -1
View File
@@ -3,7 +3,7 @@
#ifndef FF_INCLUDED_common_properties
#define FF_INCLUDED_common_properties
#include "util/FFstrbuf.h"
#include "fastfetch.h"
typedef struct FFpropquery
{
+8 -8
View File
@@ -2,8 +2,8 @@
#include "common/settings.h"
#include "common/library.h"
#include "common/io.h"
#include "common/thread.h"
#include <pthread.h>
#include <string.h>
typedef enum FFInitState
@@ -15,18 +15,18 @@ typedef enum FFInitState
#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \
static dataObject data; \
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
static FFInitState initState = FF_INITSTATE_UNINITIALIZED; \
pthread_mutex_lock(&mutex); \
ffThreadMutexLock(&mutex); \
if(initState != FF_INITSTATE_UNINITIALIZED) {\
pthread_mutex_unlock(&mutex); \
ffThreadMutexUnlock(&mutex); \
return initState == FF_INITSTATE_SUCCESSFUL ? &data : NULL; \
} \
initState = FF_INITSTATE_SUCCESSFUL; \
void* libraryHandle = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL); \
if(libraryHandle == NULL) { \
initState = FF_INITSTATE_FAILED; \
pthread_mutex_unlock(&mutex); \
ffThreadMutexUnlock(&mutex); \
return NULL; \
} \
@@ -35,20 +35,20 @@ typedef enum FFInitState
if(data.ff ## symbolName == NULL) { \
dlclose(libraryHandle); \
initState = FF_INITSTATE_FAILED; \
pthread_mutex_unlock(&mutex); \
ffThreadMutexUnlock(&mutex); \
return NULL; \
}
#define FF_LIBRARY_DATA_LOAD_RETURN \
initState = FF_INITSTATE_SUCCESSFUL; \
pthread_mutex_unlock(&mutex); \
ffThreadMutexUnlock(&mutex); \
return &data;
#define FF_LIBRARY_DATA_LOAD_ERROR \
{ \
dlclose(libraryHandle); \
initState = FF_INITSTATE_FAILED; \
pthread_mutex_unlock(&mutex); \
ffThreadMutexUnlock(&mutex); \
return NULL; \
}
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#ifndef FF_INCLUDED_common_thread
#define FF_INCLUDED_common_thread
#include "fastfetch.h"
#ifdef FF_HAVE_THREADS
#if defined(_WIN32)
#include <handleapi.h>
#include <synchapi.h>
#include <process.h> // Win32 <process.h> isn't available on MSYS2
#define FF_THREAD_MUTEX_INITIALIZER SRWLOCK_INIT
typedef SRWLOCK FFThreadMutex;
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { AcquireSRWLockExclusive(mutex); }
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { ReleaseSRWLockExclusive(mutex); }
static inline void ffThreadCreateAndDetach(__stdcall unsigned (* func)(void*), void* data) {
uintptr_t newThread = _beginthreadex(func, 0, data, NULL, 0, NULL);
if(newThread != 0)
CloseHandle((HANDLE)newThread);
}
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; }
#else
#include <pthread.h>
#define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t FFThreadMutex;
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { pthread_mutex_lock(mutex); }
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { pthread_mutex_unlock(mutex); }
static inline void ffThreadCreateAndDetach(void* (* func)(void*), void* data) {
pthread_t newThread;
if(pthread_create(&newThread, NULL, func, data) == 0)
pthread_detach(newThread);
}
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static void* fn ## ThreadMain (void* data) { fn((paramType)data); return NULL; }
#endif
#else //FF_HAVE_THREADS
#define FF_THREAD_MUTEX_INITIALIZER 0
typedef char FFThreadMutex;
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { FF_UNUSED(mutex) }
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { FF_UNUSED(mutex) }
#endif //FF_HAVE_THREADS
#endif
+5 -5
View File
@@ -1,21 +1,21 @@
#include "fastfetch.h"
#include "detection/datetime.h"
#include "common/thread.h"
#include <time.h>
#include <pthread.h>
const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance)
{
FF_UNUSED(instance); //We may need it later for additional configuration
static FFDateTimeResult result;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static bool init = false;
pthread_mutex_lock(&mutex);
ffThreadMutexLock(&mutex);
if (init)
{
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
@@ -68,6 +68,6 @@ const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance)
ffStrbufInitA(&result.secondPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.secondPretty.length = (uint32_t) strftime(result.secondPretty.chars, ffStrbufGetFree(&result.secondPretty), "%S", tm);
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
+1
View File
@@ -1,5 +1,6 @@
#include "disk.h"
#include <sys/statvfs.h>
#import <Foundation/Foundation.h>
void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result);
+4 -4
View File
@@ -6,7 +6,7 @@
#ifdef FF_HAVE_WAYLAND
#include "common/library.h"
#include "common/io.h"
#include <pthread.h>
#include "common/thread.h"
#include <wayland-client.h>
#include <sys/socket.h>
@@ -56,12 +56,12 @@ static void waylandOutputModeListener(void* data, struct wl_output* output, uint
if(!(flags & WL_OUTPUT_MODE_CURRENT) || width <= 0 || height <= 0)
return;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mutex);
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
ffThreadMutexLock(&mutex);
FFResolutionResult* result = ffListAdd(wldata->results);
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
result->width = (uint32_t) width;
result->height = (uint32_t) height;
+9 -10
View File
@@ -1,11 +1,10 @@
#include "fastfetch.h"
#include "detection/gtk.h"
#include "common/properties.h"
#include "common/thread.h"
#include "common/settings.h"
#include "detection/displayserver/displayserver.h"
#include <pthread.h>
static inline bool allPropertiesSet(FFGTKResult* result)
{
return
@@ -34,7 +33,7 @@ static inline void applyGTKSettings(FFGTKResult* result, const char* themeName,
static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* result)
{
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static const char* themeName = NULL;
static const char* iconsName = NULL;
@@ -44,11 +43,11 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul
static bool init = false;
pthread_mutex_lock(&mutex);
ffThreadMutexLock(&mutex);
if(init)
{
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize);
return;
}
@@ -90,7 +89,7 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul
cursorSize = ffSettingsGet(instance, "/org/gnome/desktop/interface/cursor-size", "org.gnome.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue;
}
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize);
}
@@ -168,12 +167,12 @@ static void detectGTK(const FFinstance* instance, const char* version, FFGTKResu
}
#define FF_DETECT_GTK_IMPL(version) \
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
static FFGTKResult result; \
static bool init = false; \
pthread_mutex_lock(&mutex); \
ffThreadMutexLock(&mutex); \
if(init){ \
pthread_mutex_unlock(&mutex);\
ffThreadMutexUnlock(&mutex);\
return &result; \
} \
init = true; \
@@ -183,7 +182,7 @@ static void detectGTK(const FFinstance* instance, const char* version, FFGTKResu
ffStrbufInit(&result.cursor); \
ffStrbufInit(&result.cursorSize); \
detectGTK(instance, #version, &result); \
pthread_mutex_unlock(&mutex); \
ffThreadMutexUnlock(&mutex); \
return &result;
const FFGTKResult* ffDetectGTK2(const FFinstance* instance)
+5 -5
View File
@@ -3,21 +3,21 @@
#ifndef FF_INCLUDED_detection_internal
#define FF_INCLUDED_detection_internal
#include "pthread.h"
#include "common/thread.h"
#define FF_DETECTION_INTERNAL_GUARD(ResultType, ...) \
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
static ResultType result; \
static bool init = false; \
pthread_mutex_lock(&mutex); \
ffThreadMutexLock(&mutex); \
if(init) \
{ \
pthread_mutex_unlock(&mutex); \
ffThreadMutexUnlock(&mutex); \
return &result; \
} \
init = true; \
__VA_ARGS__; \
pthread_mutex_unlock(&mutex); \
ffThreadMutexUnlock(&mutex); \
return &result; \
#endif
+1 -1
View File
@@ -1,8 +1,8 @@
#include "fastfetch.h"
#include "detection/media/media.h"
#include "common/thread.h"
#include <string.h>
#include <pthread.h>
#define FF_DBUS_MPRIS_PREFIX "org.mpris.MediaPlayer2."
#define FF_DBUS_TIMEOUT_MILLISECONDS 35
+5 -5
View File
@@ -1,11 +1,11 @@
#include "fastfetch.h"
#include "detection/qt.h"
#include "common/properties.h"
#include "common/thread.h"
#include "detection/displayserver/displayserver.h"
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
static inline bool allValuesSet(const FFQtResult* result)
{
@@ -135,12 +135,12 @@ const FFQtResult* ffDetectQt(const FFinstance* instance)
{
static FFQtResult result;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static bool init = false;
pthread_mutex_lock(&mutex);
ffThreadMutexLock(&mutex);
if(init)
{
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
@@ -157,6 +157,6 @@ const FFQtResult* ffDetectQt(const FFinstance* instance)
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "LXQt") == 0)
detectLXQt(instance, &result);
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
+7 -7
View File
@@ -1,9 +1,9 @@
#include "fastfetch.h"
#include "common/io.h"
#include "common/thread.h"
#include "temps_linux.h"
#include <string.h>
#include <pthread.h>
#include <dirent.h>
static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value)
@@ -38,13 +38,13 @@ static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value)
const FFTempsResult* ffDetectTemps(const FFinstance* instance)
{
static FFTempsResult result;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static bool init = false;
pthread_mutex_lock(&mutex);
ffThreadMutexLock(&mutex);
if(init)
{
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
@@ -52,7 +52,7 @@ const FFTempsResult* ffDetectTemps(const FFinstance* instance)
if(!instance->config.allowSlowOperations)
{
ffListInitA(&result.values, sizeof(FFTempValue), 0);
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
@@ -68,7 +68,7 @@ const FFTempsResult* ffDetectTemps(const FFinstance* instance)
if(dirp == NULL)
{
ffStrbufDestroy(&baseDir);
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
@@ -97,6 +97,6 @@ const FFTempsResult* ffDetectTemps(const FFinstance* instance)
closedir(dirp);
ffStrbufDestroy(&baseDir);
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
+187
View File
@@ -64,6 +64,185 @@ static void detectTTY(FFTerminalFontResult* terminalFont)
ffStrbufDestroy(&fontName);
}
#if defined(_WIN32) || defined(__MSYS__) || defined(__linux__)
#ifdef FF_HAVE_LIBCJSON
#include "common/library.h"
#include "common/processing.h"
#include <cjson/cJSON.h>
#include <stdlib.h>
typedef struct CJSONData
{
FF_LIBRARY_SYMBOL(cJSON_Parse)
FF_LIBRARY_SYMBOL(cJSON_IsObject)
FF_LIBRARY_SYMBOL(cJSON_GetObjectItemCaseSensitive)
FF_LIBRARY_SYMBOL(cJSON_IsString)
FF_LIBRARY_SYMBOL(cJSON_GetStringValue)
FF_LIBRARY_SYMBOL(cJSON_IsNumber)
FF_LIBRARY_SYMBOL(cJSON_GetNumberValue)
FF_LIBRARY_SYMBOL(cJSON_IsArray)
FF_LIBRARY_SYMBOL(cJSON_Delete)
} CJSONData;
static const char* detectWTProfile(CJSONData* cjsonData, cJSON* profile, FFstrbuf* name, int* size)
{
if(!cjsonData->ffcJSON_IsObject(profile))
return "cJSON_IsObject(profile) returns false";
cJSON* font = cjsonData->ffcJSON_GetObjectItemCaseSensitive(profile, "font");
if(!cjsonData->ffcJSON_IsObject(font))
return "cJSON_IsObject(font) returns false";
if(name->length == 0)
{
cJSON* pface = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "face");
if(cjsonData->ffcJSON_IsString(pface))
ffStrbufAppendS(name, cjsonData->ffcJSON_GetStringValue(pface));
}
if(*size < 0)
{
cJSON* psize = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "size");
if(cjsonData->ffcJSON_IsNumber(psize))
*size = (int)cjsonData->ffcJSON_GetNumberValue(psize);
}
return NULL;
}
static const char* detectFromWTImpl(const FFinstance* instance, FFstrbuf* content, FFstrbuf* name, int* size)
{
CJSONData cjsonData;
FF_LIBRARY_LOAD(libcjson, &instance->config.libcJSON, "dlopen libcjson"FF_LIBRARY_EXTENSION" failed", "libcjson"FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_Parse)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsObject)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetObjectItemCaseSensitive)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsString)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetStringValue)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsNumber)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetNumberValue)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsArray)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_Delete)
const char* error = NULL;
cJSON* root = cjsonData.ffcJSON_Parse(content->chars);
if(!cjsonData.ffcJSON_IsObject(root))
{
error = "cJSON_Parse() failed";
goto exit;
}
cJSON* profiles = cjsonData.ffcJSON_GetObjectItemCaseSensitive(root, "profiles");
if(!cjsonData.ffcJSON_IsObject(profiles))
{
error = "cJSON_GetObjectItemCaseSensitive(root, \"profiles\") failed";
goto exit;
}
FFstrbuf wtProfileId;
ffStrbufInitS(&wtProfileId, getenv("WT_PROFILE_ID"));
ffStrbufTrim(&wtProfileId, '\'');
if(wtProfileId.length > 0)
{
cJSON* list = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "list");
if(cjsonData.ffcJSON_IsArray(list))
{
cJSON* profile;
cJSON_ArrayForEach(profile, list)
{
if(!cjsonData.ffcJSON_IsObject(profile))
continue;
cJSON* guid = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profile, "guid");
if(!cjsonData.ffcJSON_IsString(guid))
continue;
if(ffStrbufCompS(&wtProfileId, cjsonData.ffcJSON_GetStringValue(guid)) == 0)
{
detectWTProfile(&cjsonData, profile, name, size);
break;
}
}
}
}
ffStrbufDestroy(&wtProfileId);
cJSON* defaults = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "defaults");
detectWTProfile(&cjsonData, defaults, name, size);
if(name->length == 0)
ffStrbufSetS(name, "Cascadia Mono");
if(*size < 0)
*size = 12;
exit:
cjsonData.ffcJSON_Delete(root);
dlclose(libcjson);
return error;
}
static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont)
{
//https://learn.microsoft.com/en-us/windows/terminal/install#settings-json-file
FFstrbuf json;
ffStrbufInit(&json);
const char* error;
error = ffProcessAppendStdOut(&json, (char* const[]) {
"cmd.exe",
"/c",
//print the file content directly, so we don't need to handle the difference of Windows and POSIX path
"if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json "
"( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json ) "
"else if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json "
"( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json ) "
"else if exist \"%LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json\" "
"( type %LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json ) "
"else ( call )",
NULL
});
if(error)
{
ffStrbufAppendS(&terminalFont->error, error);
ffStrbufDestroy(&json);
return;
}
ffStrbufTrimRight(&json, '\n');
if(json.length == 0)
{
ffStrbufAppendS(&terminalFont->error, "Cannot find file \"settings.json\"");
ffStrbufDestroy(&json);
return;
}
FFstrbuf name;
ffStrbufInit(&name);
int size = -1;
error = detectFromWTImpl(instance, &json, &name, &size);
ffStrbufDestroy(&json);
if(error)
ffStrbufAppendS(&terminalFont->error, error);
else
{
char sizeStr[16];
snprintf(sizeStr, sizeof(sizeStr), "%d", size);
ffFontInitValues(&terminalFont->font, name.chars, sizeStr);
}
ffStrbufDestroy(&name);
}
#else
static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont)
{
FF_UNUSED(instance, terminalFont);
ffStrbufAppendS(&terminalFont->error, "fastfetch is built without libcjson support");
}
#endif
#endif //defined(_WIN32) || defined(__MSYS__) || defined(__linux__)
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont);
const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance)
@@ -79,6 +258,14 @@ const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance)
detectAlacritty(instance, &result);
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty"))
detectTTY(&result);
#if defined(_WIN32) || defined(__MSYS__) || defined(__linux__)
//Used by both Linux (WSL) and Windows
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0 ||
ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WindowsTerminal.exe") == 0)
detectFromWindowsTeriminal(instance, &result);
#endif
else
ffDetectTerminalFontPlatform(instance, terminalShell, &result);
@@ -140,259 +140,6 @@ static void detectXFCETerminal(const FFinstance* instance, FFTerminalFontResult*
ffStrbufDestroy(&useSysFont);
}
#ifdef FF_HAVE_LIBCJSON
#include "common/library.h"
#include "common/processing.h"
#include <cjson/cJSON.h>
#include <stdlib.h>
typedef struct CJSONData
{
FF_LIBRARY_SYMBOL(cJSON_Parse)
FF_LIBRARY_SYMBOL(cJSON_IsObject)
FF_LIBRARY_SYMBOL(cJSON_GetObjectItemCaseSensitive)
FF_LIBRARY_SYMBOL(cJSON_IsString)
FF_LIBRARY_SYMBOL(cJSON_GetStringValue)
FF_LIBRARY_SYMBOL(cJSON_IsNumber)
FF_LIBRARY_SYMBOL(cJSON_GetNumberValue)
FF_LIBRARY_SYMBOL(cJSON_IsArray)
FF_LIBRARY_SYMBOL(cJSON_Delete)
} CJSONData;
static const char* detectWTProfile(CJSONData* cjsonData, cJSON* profile, FFstrbuf* name, int* size)
{
if(!cjsonData->ffcJSON_IsObject(profile))
return "cJSON_IsObject(profile) returns false";
cJSON* font = cjsonData->ffcJSON_GetObjectItemCaseSensitive(profile, "font");
if(!cjsonData->ffcJSON_IsObject(font))
return "cJSON_IsObject(font) returns false";
if(name->length == 0)
{
cJSON* pface = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "face");
if(cjsonData->ffcJSON_IsString(pface))
ffStrbufAppendS(name, cjsonData->ffcJSON_GetStringValue(pface));
}
if(*size < 0)
{
cJSON* psize = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "size");
if(cjsonData->ffcJSON_IsNumber(psize))
*size = (int)cjsonData->ffcJSON_GetNumberValue(psize);
}
return NULL;
}
static const char* detectFromWTImpl(const FFinstance* instance, FFstrbuf* content, FFstrbuf* name, int* size)
{
CJSONData cjsonData;
FF_LIBRARY_LOAD(libcjson, &instance->config.libcJSON, "dlopen libcjson"FF_LIBRARY_EXTENSION" failed", "libcjson"FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_Parse)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsObject)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetObjectItemCaseSensitive)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsString)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetStringValue)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsNumber)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetNumberValue)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsArray)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_Delete)
const char* error = NULL;
cJSON* root = cjsonData.ffcJSON_Parse(content->chars);
if(!cjsonData.ffcJSON_IsObject(root))
{
error = "cJSON_Parse() failed";
goto exit;
}
cJSON* profiles = cjsonData.ffcJSON_GetObjectItemCaseSensitive(root, "profiles");
if(!cjsonData.ffcJSON_IsObject(profiles))
{
error = "cJSON_GetObjectItemCaseSensitive(root, \"profiles\") failed";
goto exit;
}
FFstrbuf wtProfileId;
ffStrbufInitS(&wtProfileId, getenv("WT_PROFILE_ID"));
ffStrbufTrim(&wtProfileId, '\'');
if(wtProfileId.length > 0)
{
cJSON* list = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "list");
if(cjsonData.ffcJSON_IsArray(list))
{
cJSON* profile;
cJSON_ArrayForEach(profile, list)
{
if(!cjsonData.ffcJSON_IsObject(profile))
continue;
cJSON* guid = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profile, "guid");
if(!cjsonData.ffcJSON_IsString(guid))
continue;
if(ffStrbufCompS(&wtProfileId, cjsonData.ffcJSON_GetStringValue(guid)) == 0)
{
detectWTProfile(&cjsonData, profile, name, size);
break;
}
}
}
}
ffStrbufDestroy(&wtProfileId);
cJSON* defaults = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "defaults");
detectWTProfile(&cjsonData, defaults, name, size);
if(name->length == 0)
ffStrbufSetS(name, "Cascadia Mono");
if(*size < 0)
*size = 12;
exit:
cjsonData.ffcJSON_Delete(root);
dlclose(libcjson);
return error;
}
static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont)
{
//https://learn.microsoft.com/en-us/windows/terminal/install#settings-json-file
FFstrbuf json;
ffStrbufInit(&json);
const char* error;
error = ffProcessAppendStdOut(&json, (char* const[]) {
"cmd.exe",
"/c",
//print the file content directly, so we don't need to handle the difference of Windows and POSIX path
"if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json "
"( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json ) "
"else if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json "
"( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json ) "
"else if exist \"%LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json\" "
"( type %LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json ) "
"else ( call )",
NULL
});
if(error)
{
ffStrbufAppendS(&terminalFont->error, error);
ffStrbufDestroy(&json);
return;
}
ffStrbufTrimRight(&json, '\n');
if(json.length == 0)
{
ffStrbufAppendS(&terminalFont->error, "Cannot find file \"settings.json\"");
ffStrbufDestroy(&json);
return;
}
FFstrbuf name;
ffStrbufInit(&name);
int size = -1;
error = detectFromWTImpl(instance, &json, &name, &size);
ffStrbufDestroy(&json);
if(error)
ffStrbufAppendS(&terminalFont->error, error);
else
{
char sizeStr[16];
snprintf(sizeStr, sizeof(sizeStr), "%d", size);
ffFontInitValues(&terminalFont->font, name.chars, sizeStr);
}
ffStrbufDestroy(&name);
}
#else
static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont)
{
FF_UNUSED(instance, terminalFont);
ffStrbufAppendS(&terminalFont->error, "fastfetch is built without libcjson support");
}
#endif
#if defined(_WIN32) || defined(__MSYS__)
// TODO: move to a separate file
static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont)
{
FFstrbuf fontName;
ffStrbufInit(&fontName);
FFstrbuf fontSize;
ffStrbufInit(&fontSize);
ffParsePropFileHomeValues(instance, ".minttyrc", 2, (FFpropquery[]) {
{"Font=", &fontName},
{"FontHeight=", &fontSize}
});
if(fontName.length == 0)
ffStrbufAppendS(&fontName, "Lucida Console");
if(fontSize.length == 0)
ffStrbufAppendC(&fontSize, '9');
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
ffStrbufDestroy(&fontName);
ffStrbufDestroy(&fontSize);
}
#define WIN32_LEAN_AND_MEAN 1
#include <Windows.h>
static void detectConhost(const FFinstance* instance, FFTerminalFontResult* terminalFont)
{
FF_UNUSED(instance);
//Current font of conhost doesn't seem to be detectable, we detect default font instead
HKEY hKey;
if(RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW() failed");
return;
}
DWORD bufSize;
wchar_t fontNameW[64];
bufSize = sizeof(fontNameW);
if(RegQueryValueExW(hKey, L"FaceName", NULL, NULL, (LPBYTE)fontNameW, &bufSize) != ERROR_SUCCESS)
{
ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(FaceName) failed");
goto exit;
}
fontNameW[bufSize] = '\0';
char fontNameA[128];
int fontNameALen = WideCharToMultiByte(CP_UTF8, 0, fontNameW, (int)(bufSize / 2), fontNameA, sizeof(fontNameA), NULL, NULL);
fontNameA[fontNameALen] = '\0';
uint32_t fontSizeNum = 0;
bufSize = sizeof(fontSizeNum);
if(RegQueryValueExW(hKey, L"fontSize", NULL, NULL, (LPBYTE)&fontSizeNum, &bufSize) != ERROR_SUCCESS)
{
ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(fontSize) failed");
goto exit;
}
char fontSize[16];
snprintf(fontSize, sizeof(fontSize), "%u", (fontSizeNum >> 16));
ffFontInitValues(&terminalFont->font, fontNameA, fontSize);
exit:
RegCloseKey(hKey);
}
#endif //defined(_WIN32) || defined(__MSYS__)
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
{
if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "konsole") == 0)
@@ -405,14 +152,4 @@ void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalSh
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);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0 ||
ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WindowsTerminal.exe") == 0)
detectFromWindowsTeriminal(instance, terminalFont);
#if defined(_WIN32) || defined(__MSYS__)
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "mintty") == 0)
detectMintty(instance, terminalFont);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "conhost.exe") == 0)
detectConhost(instance, terminalFont);
#endif
}
@@ -0,0 +1,82 @@
#include "common/properties.h"
#include "detection/terminalshell/terminalshell.h"
#include "terminalfont.h"
#define WIN32_LEAN_AND_MEAN 1
#include <Windows.h>
static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont)
{
FFstrbuf fontName;
ffStrbufInit(&fontName);
FFstrbuf fontSize;
ffStrbufInit(&fontSize);
ffParsePropFileHomeValues(instance, ".minttyrc", 2, (FFpropquery[]) {
{"Font=", &fontName},
{"FontHeight=", &fontSize}
});
if(fontName.length == 0)
ffStrbufAppendS(&fontName, "Lucida Console");
if(fontSize.length == 0)
ffStrbufAppendC(&fontSize, '9');
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
ffStrbufDestroy(&fontName);
ffStrbufDestroy(&fontSize);
}
static void detectConhost(const FFinstance* instance, FFTerminalFontResult* terminalFont)
{
FF_UNUSED(instance);
//Current font of conhost doesn't seem to be detectable, we detect default font instead
HKEY hKey;
if(RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW() failed");
return;
}
DWORD bufSize;
wchar_t fontNameW[64];
bufSize = sizeof(fontNameW);
if(RegQueryValueExW(hKey, L"FaceName", NULL, NULL, (LPBYTE)fontNameW, &bufSize) != ERROR_SUCCESS)
{
ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(FaceName) failed");
goto exit;
}
fontNameW[bufSize] = '\0';
char fontNameA[128];
int fontNameALen = WideCharToMultiByte(CP_UTF8, 0, fontNameW, (int)(bufSize / 2), fontNameA, sizeof(fontNameA), NULL, NULL);
fontNameA[fontNameALen] = '\0';
uint32_t fontSizeNum = 0;
bufSize = sizeof(fontSizeNum);
if(RegQueryValueExW(hKey, L"fontSize", NULL, NULL, (LPBYTE)&fontSizeNum, &bufSize) != ERROR_SUCCESS)
{
ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(fontSize) failed");
goto exit;
}
char fontSize[16];
snprintf(fontSize, sizeof(fontSize), "%u", (fontSizeNum >> 16));
ffFontInitValues(&terminalFont->font, fontNameA, fontSize);
exit:
RegCloseKey(hKey);
}
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
{
if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "mintty") == 0)
detectMintty(instance, terminalFont);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "conhost.exe") == 0)
detectConhost(instance, terminalFont);
}
@@ -3,13 +3,13 @@
#include "common/io.h"
#include "common/parsing.h"
#include "common/processing.h"
#include "common/thread.h"
#include "terminalshell.h"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#ifdef __APPLE__
#include <libproc.h>
@@ -318,13 +318,13 @@ const FFTerminalShellResult*
{
FF_UNUSED(instance);
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static FFTerminalShellResult result;
static bool init = false;
pthread_mutex_lock(&mutex);
ffThreadMutexLock(&mutex);
if(init)
{
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
@@ -361,6 +361,6 @@ const FFTerminalShellResult*
else
ffStrbufInitCopy(&result.terminalPrettyName, &result.terminalProcessName);
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
+8 -7
View File
@@ -1,16 +1,17 @@
#include "fastfetch.h"
#include "detection/title.h"
#include "common/thread.h"
#include <limits.h>
#include <unistd.h>
#include <pthread.h>
#include <netdb.h>
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 64
#endif
#ifdef __linux__
#include <netdb.h>
static void detectFQDN(FFTitleResult* title)
{
struct addrinfo hints = {0};
@@ -37,12 +38,12 @@ const FFTitleResult* ffDetectTitle(const FFinstance* instance)
{
static FFTitleResult result;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static bool init = false;
pthread_mutex_lock(&mutex);
ffThreadMutexLock(&mutex);
if(init)
{
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
@@ -54,12 +55,12 @@ const FFTitleResult* ffDetectTitle(const FFinstance* instance)
ffStrbufAppendS(&result.hostname, instance->state.utsname.nodename);
ffStrbufInitA(&result.fqdn, HOST_NAME_MAX);
#ifdef __linux
#ifdef __linux__
detectFQDN(&result);
#endif
if(result.fqdn.length == 0)
ffStrbufAppend(&result.fqdn, &result.hostname);
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
+5 -6
View File
@@ -1,9 +1,8 @@
#include "fastfetch.h"
#include "common/thread.h"
#include "detection/vulkan.h"
#include "detection/gpu/gpu.h"
#include <pthread.h>
#ifdef FF_HAVE_VULKAN
#include "common/library.h"
#include "common/io.h"
@@ -217,13 +216,13 @@ static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* resu
const FFVulkanResult* ffDetectVulkan(const FFinstance* instance)
{
static FFVulkanResult result;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static bool init = false;
pthread_mutex_lock(&mutex);
ffThreadMutexLock(&mutex);
if(init)
{
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
@@ -240,6 +239,6 @@ const FFVulkanResult* ffDetectVulkan(const FFinstance* instance)
result.error = "fastfetch was compiled without vulkan support";
#endif
pthread_mutex_unlock(&mutex);
ffThreadMutexUnlock(&mutex);
return &result;
}
+2 -2
View File
@@ -5,7 +5,7 @@
#define FF_PUBLICIP_MODULE_NAME "Public IP"
#define FF_PUBLICIP_NUM_FORMAT_ARGS 1
static int sockfd;
static FFSockType sockfd;
void ffPreparePublicIp(FFinstance* instance)
{
@@ -39,7 +39,7 @@ void ffPrintPublicIp(FFinstance* instance)
if(sockfd == 0)
ffPreparePublicIp(instance);
if(sockfd < 0)
if(sockfd == INVALID_SOCKET)
{
ffPrintError(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP, "Failed to connect to an IP detection server");
return;
+2 -2
View File
@@ -5,7 +5,7 @@
#define FF_WEATHER_MODULE_NAME "Weather"
#define FF_WEATHER_NUM_FORMAT_ARGS 1
static int sockfd;
static FFSockType sockfd;
void ffPrepareWeather(FFinstance* instance)
{
@@ -21,7 +21,7 @@ void ffPrintWeather(FFinstance* instance)
if(sockfd == 0)
ffPrepareWeather(instance);
if(sockfd < 0)
if(sockfd == INVALID_SOCKET)
{
ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather, "Failed to connect to 'wttr.in'");
return;