summaryrefslogtreecommitdiffstats
path: root/src/common/impl/init.c
diff options
context:
space:
mode:
authorsumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
committersumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
commit76424950e373d3b04ac3dd13019151bfba3e8423 (patch)
tree4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/common/impl/init.c
Add the files
Diffstat (limited to 'src/common/impl/init.c')
-rw-r--r--src/common/impl/init.c300
1 files changed, 300 insertions, 0 deletions
diff --git a/src/common/impl/init.c b/src/common/impl/init.c
new file mode 100644
index 0000000..f0fc0a2
--- /dev/null
+++ b/src/common/impl/init.c
@@ -0,0 +1,300 @@
+#include "fastfetch.h"
+#include "common/init.h"
+#include "common/parsing.h"
+#include "common/thread.h"
+#include "common/textModifier.h"
+#include "detection/displayserver/displayserver.h"
+#include "detection/terminaltheme/terminaltheme.h"
+#include "logo/logo.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <locale.h>
+#ifdef _WIN32
+ #include <windows.h>
+ #include "common/windows/unicode.h"
+#else
+ #include <signal.h>
+#endif
+
+FFinstance instance; // Global singleton
+
+static void initState(FFstate* state) {
+ state->logoWidth = 0;
+ state->logoHeight = 0;
+ state->keysHeight = 0;
+ state->terminalLightTheme = false;
+ state->titleFqdn = false;
+
+ ffPlatformInit(&state->platform);
+ state->dynamicInterval = 0;
+
+ #if !FF_MODULE_DISABLE_TERMINALTHEME
+ {
+ // don't enable bright color if the terminal is in light mode
+ FFTerminalThemeResult result;
+ if (ffDetectTerminalTheme(&result, true /* forceEnv for performance */) && !result.bg.dark) {
+ state->terminalLightTheme = true;
+ }
+ }
+ #endif
+}
+
+static void defaultConfig(void) {
+ ffOptionsInitLogo(&instance.config.logo);
+ ffOptionsInitGeneral(&instance.config.general);
+ ffOptionsInitDisplay(&instance.config.display);
+}
+
+void ffInitInstance(void) {
+#ifdef _WIN32
+ // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendat>
+ setlocale(LC_ALL, ".UTF8");
+#else
+ // Never use `setlocale(LC_ALL, "")`
+ setlocale(LC_TIME, "");
+#endif
+
+ defaultConfig();
+ initState(&instance.state);
+}
+
+static volatile bool ffDisableLinewrap = false;
+static volatile bool ffHideCursor = false;
+#ifdef _WIN32
+static volatile UINT oldCp = CP_UTF8;
+#endif
+
+static void resetConsole(void) {
+ if (ffDisableLinewrap) {
+ fputs("\033[?7h", stdout);
+ }
+
+ if (ffHideCursor) {
+ fputs("\033[?25h", stdout);
+ }
+
+ if (instance.state.dynamicInterval > 0) {
+ fputs("\033[?1049l", stdout); // Disable alternate buffer
+ }
+
+#if defined(_WIN32)
+ fflush(stdout);
+
+ if (oldCp != CP_UTF8) {
+ SetConsoleOutputCP(oldCp);
+ }
+#endif
+}
+
+#ifdef _WIN32
+BOOL WINAPI consoleHandler(FF_A_UNUSED DWORD signal) {
+ resetConsole();
+ exit(0);
+}
+#else
+static void exitSignalHandler(FF_A_UNUSED int signal) {
+ resetConsole();
+ exit(0);
+}
+#endif
+
+void ffStart(void) {
+ ffDisableLinewrap = instance.config.display.disableLinewrap && !instance.config.display.pipe;
+ ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe;
+
+#ifdef _WIN32
+ SetErrorMode(SEM_FAILCRITICALERRORS);
+ if (instance.config.display.noBuffer) {
+ setvbuf(stdout, NULL, _IONBF, 0);
+ } else {
+ setvbuf(stdout, NULL, _IOFBF, 4096);
+ }
+ SetConsoleCtrlHandler(consoleHandler, TRUE);
+ HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
+ DWORD mode = 0;
+ if (GetConsoleMode(hStdout, &mode)) {
+ SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
+ oldCp = GetConsoleOutputCP();
+ if (oldCp != CP_UTF8) {
+ SetConsoleOutputCP(CP_UTF8);
+ }
+ }
+#else
+ if (instance.config.display.noBuffer) {
+ setvbuf(stdout, NULL, _IONBF, 0);
+ }
+ struct sigaction action;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ action.sa_handler = exitSignalHandler;
+ sigaction(SIGINT, &action, NULL);
+ sigaction(SIGTERM, &action, NULL);
+ sigaction(SIGQUIT, &action, NULL);
+ sigset_t newmask;
+ sigemptyset(&newmask);
+ sigaddset(&newmask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &newmask, NULL);
+#endif
+
+ // reset everything to default before we start printing
+ if (!instance.config.display.pipe) {
+ fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
+ }
+
+ if (ffHideCursor) {
+ fputs("\033[?25l", stdout);
+ }
+
+ if (ffDisableLinewrap) {
+ fputs("\033[?7l", stdout);
+ }
+
+ if (instance.state.dynamicInterval > 0) {
+ fputs("\033[?1049h\033[H", stdout); // Enable alternate buffer
+ fflush(stdout);
+ }
+}
+
+void ffFinish(void) {
+ resetConsole();
+}
+
+static void destroyConfig(void) {
+ ffOptionsDestroyLogo(&instance.config.logo);
+ ffOptionsDestroyGeneral(&instance.config.general);
+ ffOptionsDestroyDisplay(&instance.config.display);
+}
+
+static void destroyState(void) {
+ ffPlatformDestroy(&instance.state.platform);
+}
+
+void ffDestroyInstance(void) {
+ destroyConfig();
+ destroyState();
+}
+
+#if FF_HAVE_LUA
+ #include <lua.h>
+#endif
+#if FF_HAVE_QUICKJS
+ #include <quickjs.h>
+ #define FF_STR_INDIR(x) #x
+ #define FF_STR(x) FF_STR_INDIR(x)
+#endif
+
+// Must be in a file compiled with the libfastfetch target, because the FF_HAVE* macros are not defined for the executable targets
+void ffListFeatures(void) {
+ fputs(
+#if FF_HAVE_THREADS
+ "threads\n"
+#endif
+#if FF_HAVE_VULKAN
+ "vulkan\n"
+#endif
+#if FF_HAVE_WAYLAND
+ "wayland\n"
+#endif
+#if FF_HAVE_XCB_RANDR
+ "xcb-randr\n"
+#endif
+#if FF_HAVE_XRANDR
+ "xrandr\n"
+#endif
+#if FF_HAVE_DRM
+ "drm\n"
+#endif
+#if FF_HAVE_DRM_AMDGPU
+ "drm_amdgpu\n"
+#endif
+#if FF_HAVE_GIO
+ "gio\n"
+#endif
+#if FF_HAVE_DCONF
+ "dconf\n"
+#endif
+#if FF_HAVE_EET
+ "eet\n"
+#endif
+#if FF_HAVE_DBUS
+ "dbus\n"
+#endif
+#if FF_HAVE_IMAGEMAGICK7
+ "imagemagick7\n"
+#endif
+#if FF_HAVE_IMAGEMAGICK6
+ "imagemagick6\n"
+#endif
+#if FF_HAVE_CHAFA
+ "chafa\n"
+#endif
+#if FF_HAVE_ZLIB
+ "zlib\n"
+#endif
+#if FF_HAVE_SQLITE3
+ "sqlite3\n"
+#endif
+#if FF_HAVE_RPM
+ "rpm\n"
+#endif
+#if FF_HAVE_EGL
+ "egl\n"
+#endif
+#if FF_HAVE_GLX
+ "glx\n"
+#endif
+#if FF_HAVE_OPENCL
+ "opencl\n"
+#endif
+#if FF_HAVE_FREETYPE
+ "freetype\n"
+#endif
+#if FF_HAVE_PULSE
+ "libpulse\n"
+#endif
+#if FF_HAVE_DDCUTIL
+ "libddcutil\n"
+#endif
+#if FF_HAVE_ELF || __sun || (__FreeBSD__ && !__DragonFly__) || __OpenBSD__ || __NetBSD__
+ "libelf\n"
+#endif
+#if FF_HAVE_LIBZFS
+ "libzfs\n"
+#endif
+#if FF_HAVE_VA
+ "va\n"
+#endif
+#if FF_HAVE_VDPAU
+ "vdpau\n"
+#endif
+#if FF_USE_SYSTEM_YYJSON
+ "System yyjson\n"
+#endif
+#if FF_HAVE_LINUX_VIDEODEV2
+ "linux/videodev2\n"
+#endif
+#if FF_HAVE_EMBEDDED_PCIIDS
+ "Embedded pciids\n"
+#endif
+#if FF_ENABLE_WCWIDTH
+ "Embedded wcwidth\n"
+#endif
+#if FF_HAVE_WINRT
+ "WinRT headers\n"
+#endif
+#if FF_WIN81_COMPAT
+ "Windows 8.1 Compatibility\n"
+#endif
+#if FF_APPLE_MEMSIZE_USABLE
+ "Apple memsize_usable\n"
+#endif
+#if FF_HAVE_LUA
+ LUA_VERSION "\n"
+#endif
+#if FF_HAVE_QUICKJS
+ "QuickJS " FF_STR(QJS_VERSION_MAJOR) "." FF_STR(QJS_VERSION_MINOR) "." FF_STR(QJS_VERSION_PATCH) QJS_VERSION_SUFFIX "\n"
+#endif
+ "",
+ stdout);
+}