From 2689a20889e3fb8c7c54aa79a8a5f5ef43953048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 10:39:11 +0800 Subject: [PATCH 1/8] Uptime: support Windows --- CMakeLists.txt | 3 +++ src/detection/uptime/uptime.h | 10 ++++++++++ src/detection/uptime/uptime_apple.c | 19 +++++++++++++++++++ src/detection/uptime/uptime_linux.c | 11 +++++++++++ src/detection/uptime/uptime_windows.c | 10 ++++++++++ src/modules/uptime.c | 25 ++----------------------- 6 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 src/detection/uptime/uptime.h create mode 100644 src/detection/uptime/uptime_apple.c create mode 100644 src/detection/uptime/uptime_linux.c create mode 100644 src/detection/uptime/uptime_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 1eac66074..2a3117707 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -316,6 +316,7 @@ if(LINUX OR ANDROID OR BSD) src/detection/temps/temps_linux.c src/detection/opengl/opengl_linux.c src/detection/processes/processes_linux.c + src/detection/uptime/uptime_linux.c src/detection/poweradapter/poweradapter_nosupport.c ) @@ -370,6 +371,7 @@ if(MSYS) src/detection/packages/packages_windows.c src/detection/kernel/kernel_windows.cpp src/detection/localip/localip_windows.c + src/detection/uptime/uptime_windows.c src/util/windows/wmi.cpp src/detection/poweradapter/poweradapter_nosupport.c @@ -398,6 +400,7 @@ if(APPLE) src/detection/font/font_apple.m src/detection/opengl/opengl_apple.c src/detection/processes/processes_apple.c + src/detection/uptime/uptime_apple.c src/detection/bios/bios_nosupport.c src/detection/board/board_nosupport.c diff --git a/src/detection/uptime/uptime.h b/src/detection/uptime/uptime.h new file mode 100644 index 000000000..a44d4cecc --- /dev/null +++ b/src/detection/uptime/uptime.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_uptime_uptime +#define FF_INCLUDED_detection_uptime_uptime + +#include "fastfetch.h" + +uint64_t ffDetectUptime(const FFinstance* instance); + +#endif diff --git a/src/detection/uptime/uptime_apple.c b/src/detection/uptime/uptime_apple.c new file mode 100644 index 000000000..c32496ef3 --- /dev/null +++ b/src/detection/uptime/uptime_apple.c @@ -0,0 +1,19 @@ +#include "uptime.h" + +#include +#include + +uint64_t ffDetectUptime(const FFinstance* instance) +{ + FF_UNUSED(instance) + struct timeval bootTime; + size_t bootTimeSize = sizeof(bootTime); + if(sysctl( + (int[]) {CTL_KERN, KERN_BOOTTIME}, 2, + &bootTime, &bootTimeSize, + NULL, 0 + ) == 0) + return (uint64_t) difftime(time(NULL), bootTime.tv_sec); + + return 0; +} diff --git a/src/detection/uptime/uptime_linux.c b/src/detection/uptime/uptime_linux.c new file mode 100644 index 000000000..e58fa6505 --- /dev/null +++ b/src/detection/uptime/uptime_linux.c @@ -0,0 +1,11 @@ +#include "uptime.h" + +uint64_t ffDetectUptime(const FFinstance* instance) +{ + #if FF_HAVE_SYSINFO_H + return (uint64_t) instance->state.sysinfo.uptime; + #else + FF_UNUSED(instance) + return 0; + #endif +} diff --git a/src/detection/uptime/uptime_windows.c b/src/detection/uptime/uptime_windows.c new file mode 100644 index 000000000..8909ad596 --- /dev/null +++ b/src/detection/uptime/uptime_windows.c @@ -0,0 +1,10 @@ +#include "uptime.h" + +#define WIN32_LEAN_AND_MEAN +#include + +uint64_t ffDetectUptime(const FFinstance* instance) +{ + FF_UNUSED(instance) + return GetTickCount64() / 1000; +} diff --git a/src/modules/uptime.c b/src/modules/uptime.c index 9cbd9f9f8..cf371778d 100644 --- a/src/modules/uptime.c +++ b/src/modules/uptime.c @@ -1,34 +1,13 @@ #include "fastfetch.h" #include "common/printing.h" - -#if __APPLE__ - #include "time.h" - #include "sys/sysctl.h" -#endif +#include "detection/uptime/uptime.h" #define FF_UPTIME_MODULE_NAME "Uptime" #define FF_UPTIME_NUM_FORMAT_ARGS 4 void ffPrintUptime(FFinstance* instance) { - uint64_t uptime; - - #if FF_HAVE_SYSINFO_H - uptime = (uint64_t) instance->state.sysinfo.uptime; - #elif __APPLE__ - struct timeval bootTime; - size_t bootTimeSize = sizeof(bootTime); - if(sysctl( - (int[]) {CTL_KERN, KERN_BOOTTIME}, 2, - &bootTime, &bootTimeSize, - NULL, 0 - ) == 0) - uptime = (uint64_t) difftime(time(NULL), bootTime.tv_sec); - else - uptime = 0; - #else - uptime = 0; - #endif + uint64_t uptime = ffDetectUptime(instance); if(uptime == 0) { From b33e042cd43542d2f383c1686068760b8a66633d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 17:00:36 +0800 Subject: [PATCH 2/8] Library: support Windows --- src/common/library.c | 10 ++++++---- src/common/library.h | 13 ++++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/common/library.c b/src/common/library.c index c131a3862..554cc9f39 100644 --- a/src/common/library.c +++ b/src/common/library.c @@ -10,10 +10,12 @@ #endif #endif -#ifdef __SANITIZE_ADDRESS__ - #define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE -#else - #define FF_DLOPEN_FLAGS RTLD_LAZY +#ifndef FF_DLOPEN_FLAGS + #ifdef __SANITIZE_ADDRESS__ + #define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE + #else + #define FF_DLOPEN_FLAGS RTLD_LAZY + #endif #endif static void* libraryLoad(const char* path, int maxVersion) diff --git a/src/common/library.h b/src/common/library.h index 885cd32dc..fd12c0b05 100644 --- a/src/common/library.h +++ b/src/common/library.h @@ -3,7 +3,18 @@ #ifndef FF_INCLUDED_common_library #define FF_INCLUDED_common_library -#include +#include "fastfetch.h" +#include "util/FFcheckmacros.h" + +#if defined(_WIN32) //We don't force MSYS using LoadLibrary because dlopen also searches $LD_LIBRARY_PATH + #include + #define FF_DLOPEN_FLAGS 0 + FF_C_NODISCARD static inline void* dlopen(const char* path, int mode) { FF_UNUSED(mode); return LoadLibraryA(path); } + FF_C_NODISCARD static inline void* dlsym(void* handle, const char* symbol) { return GetProcAddress((HMODULE)handle, symbol); } + static inline int dlclose(void* handle) { return !FreeLibrary((HMODULE)handle); } +#else + #include +#endif #if defined(_WIN32) || defined(__MSYS__) #define FF_LIBRARY_EXTENSION ".dll" From 13769e0e5297dfb3998b206dbe7e0642123d38af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 17:57:59 +0800 Subject: [PATCH 3/8] Disk: removes unnecessary `#include`s --- src/modules/disk.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/modules/disk.c b/src/modules/disk.c index 07903c496..1a2c97be8 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -3,8 +3,6 @@ #include "common/parsing.h" #include "detection/disk/disk.h" -#include - #define FF_DISK_MODULE_NAME "Disk" #define FF_DISK_NUM_FORMAT_ARGS 4 From 457c2da67d25fd44f5c0fa3f21d307f2c8533e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 17:59:37 +0800 Subject: [PATCH 4/8] Packages: silence warnings --- src/detection/packages/packages_windows.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index 994a3e333..b64374e0e 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -32,6 +32,8 @@ void ffDetectPackages(FFinstance* instance, FFPackageCounts* counts) //We have pacman and maybe others in MSYS, but not package managers for Windows if(getenv("MSYSTEM")) return ffDetectPackagesPosix(instance, counts); + #else + FF_UNUSED(instance); #endif FFstrbuf scoopPath; From 3cc661161428598e925f1903a7b1775b9c31ca30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 18:12:54 +0800 Subject: [PATCH 5/8] Windows: support native Windows --- .gitignore | 1 + CMakeLists.txt | 50 ++++++++++------ src/common/format.c | 8 ++- src/common/init.c | 50 +++++++++++++--- src/common/io.c | 20 ++++++- src/common/properties.c | 3 + src/detection/os/os_windows.cpp | 6 +- .../terminalshell/terminalshell_windows.cpp | 2 + src/fastfetch.c | 8 +++ src/fastfetch.h | 9 ++- src/modules/locale.c | 3 + src/util/FFstrbuf.h | 5 ++ src/util/windows/getline.c | 58 ++++++++++++++++++ src/util/windows/getline.h | 11 ++++ src/util/windows/pwd.c | 17 ++++++ src/util/windows/pwd.h | 22 +++++++ src/util/windows/utsname.c | 59 +++++++++++++++++++ src/util/windows/utsname.h | 19 ++++++ src/util/windows/wmi.cpp | 13 ++-- 19 files changed, 319 insertions(+), 45 deletions(-) create mode 100644 src/util/windows/getline.c create mode 100644 src/util/windows/getline.h create mode 100644 src/util/windows/pwd.c create mode 100644 src/util/windows/pwd.h create mode 100644 src/util/windows/utsname.c create mode 100644 src/util/windows/utsname.h diff --git a/.gitignore b/.gitignore index f604d255a..94a0919c6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ **/.cache/ **/.kdev4/ **/.DS_Store +/.vs cscope.* tags fastfetch.kdev4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a3117707..2b4f41f36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,11 +15,11 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*") set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*") set(BSD TRUE CACHE BOOL "..." FORCE) -elseif(NOT APPLE AND NOT ANDROID AND NOT MSYS) +elseif(NOT APPLE AND NOT ANDROID AND NOT MSYS AND NOT WIN32) message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") endif() -if(MSYS) +if(MSYS OR WIN32) enable_language(CXX) endif() @@ -27,7 +27,7 @@ endif() # Compile time dependencies # ############################# -set(THREADS_PREFER_PTHREAD_FLAG ON) +set(THREADS_PREFER_PTHREAD_FLAG NOT WIN32) find_package(Threads) find_package(PkgConfig REQUIRED) @@ -41,7 +41,7 @@ include(CheckIncludeFile) include(CMakeDependentOption) cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR MSYS" OFF) +cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR MSYS OR WIN32" OFF) cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF) @@ -60,8 +60,8 @@ cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENAB cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD" OFF) 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_OPENCL "Enable opencl" ON "LINUX OR BSD OR MSYS OR WIN32" OFF) +cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR MSYS OR WIN32" 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) @@ -78,10 +78,10 @@ endif() message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") if(ENABLE_THREADS) - if(CMAKE_USE_PTHREADS_INIT) - message(STATUS "Threads type: pthread") - else() + if(CMAKE_USE_WIN32_THREADS_INIT) message(STATUS "Threads type: Win32 thread") + elseif(CMAKE_USE_PTHREADS_INIT) + message(STATUS "Threads type: pthread") endif() else() message(STATUS "Threads type: disabled") @@ -90,7 +90,7 @@ endif() set(CMAKE_C_STANDARD 11) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion") -if(MSYS) +if(MSYS OR WIN32) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -fno-exceptions -fno-rtti") endif() @@ -102,7 +102,7 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX}) endif() set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer") -if(NOT MSYS) +if(NOT MSYS AND NOT WIN32) set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined") endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}") @@ -344,9 +344,8 @@ if(LINUX OR BSD) ) endif() -if(MSYS) +if(MSYS OR WIN32) list(APPEND LIBFASTFETCH_SRC - src/common/processing_linux.c src/detection/host/host_windows.cpp src/detection/bios/bios_windows.cpp src/detection/board/board_windows.cpp @@ -364,9 +363,7 @@ if(MSYS) src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/memory/memory_windows.cpp src/detection/font/font_windows.cpp - src/detection/terminalshell/terminalshell_linux.c src/detection/terminalshell/terminalshell_windows.cpp - src/detection/packages/packages_linux.c src/detection/terminalfont/terminalfont_windows.c src/detection/packages/packages_windows.c src/detection/kernel/kernel_windows.cpp @@ -379,6 +376,23 @@ if(MSYS) ) endif() +if(MSYS) + list(APPEND LIBFASTFETCH_SRC + src/common/processing_linux.c + src/detection/terminalshell/terminalshell_linux.c + src/detection/packages/packages_linux.c + ) +endif() + +if(WIN32) + list(APPEND LIBFASTFETCH_SRC + src/common/processing_windows.c + src/util/windows/getline.c + src/util/windows/pwd.c + src/util/windows/utsname.c + ) +endif() + if(APPLE) list(APPEND LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage_apple.c @@ -497,7 +511,9 @@ ff_lib_enable(FREETYPE freetype2) if(ENABLE_THREADS) target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS) - target_link_libraries(libfastfetch PRIVATE Threads::Threads) + if(CMAKE_USE_PTHREADS_INIT) #Threads::Threads is not set for WIN32 + target_link_libraries(libfastfetch PRIVATE Threads::Threads) + endif() endif() if(APPLE) @@ -510,7 +526,7 @@ if(APPLE) PRIVATE "-framework Cocoa" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" ) -elseif(MSYS) +elseif(MSYS OR WIN32) target_link_libraries(libfastfetch PRIVATE "wbemuuid" PRIVATE "ole32" diff --git a/src/common/format.c b/src/common/format.c index 688ae3887..19d5d289d 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -2,16 +2,18 @@ #include "common/format.h" #include "common/parsing.h" +#include + void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg) { if(formatarg->type == FF_FORMAT_ARG_TYPE_INT) ffStrbufAppendF(buffer, "%i", *(int*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT) - ffStrbufAppendF(buffer, "%u", *(uint32_t*)formatarg->value); + ffStrbufAppendF(buffer, "%" PRIu32, *(uint32_t*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT16) - ffStrbufAppendF(buffer, "%hu", *(uint16_t*)formatarg->value); + ffStrbufAppendF(buffer, "%" PRIu16, *(uint16_t*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT8) - ffStrbufAppendF(buffer, "%hhu", *(uint8_t*)formatarg->value); + ffStrbufAppendF(buffer, "%" PRIu8, *(uint8_t*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRING) ffStrbufAppendS(buffer, (const char*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRBUF) diff --git a/src/common/init.c b/src/common/init.c index f9001f12f..00b3c687a 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -9,7 +9,12 @@ #include #include #include -#include +#ifdef _WIN32 + #include + #include +#else + #include +#endif static bool strbufEqualsAdapter(const void* first, const void* second) { @@ -101,18 +106,35 @@ static void initCacheDir(FFstate* state) else ffStrbufEnsureEndsWithC(&state->cacheDir, '/'); - mkdir(state->cacheDir.chars, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH); //I hope everybody has a cache folder, but who knows + mkdir(state->cacheDir.chars + #ifndef WIN32 + , S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH + #endif + ); //I hope everybody has a cache folder, but who knows ffStrbufAppendS(&state->cacheDir, "fastfetch/"); - mkdir(state->cacheDir.chars, S_IRWXU | S_IRGRP | S_IROTH); + mkdir(state->cacheDir.chars + #ifndef WIN32 + , S_IRWXU | S_IRGRP | S_IROTH + #endif + ); } static void initState(FFstate* state) { + #ifdef WIN32 + //https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support + setlocale(LC_ALL, ".UTF8"); + #endif + state->logoWidth = 0; state->logoHeight = 0; state->keysHeight = 0; - state->passwd = getpwuid(getuid()); + #ifndef WIN32 + state->passwd = getpwuid(getuid()); + #else + state->passwd = ffGetPasswd(); + #endif uname(&state->utsname); #if FF_HAVE_SYSINFO_H @@ -305,12 +327,24 @@ static void resetConsole() fputs("\033[?25h", stdout); } +#ifdef _WIN32 +BOOL WINAPI consoleHandler(DWORD signal) +{ + if(signal == CTRL_C_EVENT) + { + resetConsole(); + return TRUE; + } + return false; +} +#else static void exitSignalHandler(int signal) { FF_UNUSED(signal); resetConsole(); exit(0); } +#endif void ffStart(FFinstance* instance) { @@ -320,12 +354,14 @@ void ffStart(FFinstance* instance) ffDisableLinewrap = instance->config.disableLinewrap && !instance->config.pipe; ffHideCursor = instance->config.hideCursor && !instance->config.pipe; - struct sigaction action = {}; - action.sa_handler = exitSignalHandler; - + #ifdef _WIN32 + SetConsoleCtrlHandler(consoleHandler, TRUE); + #else + struct sigaction action = { .sa_handler = exitSignalHandler }; sigaction(SIGINT, &action, NULL); sigaction(SIGTERM, &action, NULL); sigaction(SIGQUIT, &action, NULL); + #endif //We do the cache validation here, so we can skip it if --recache is given if(!instance->config.recache) diff --git a/src/common/io.c b/src/common/io.c index 1b3ccddf9..0f59205fe 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -4,8 +4,11 @@ #include #include #include -#include -#include + +#ifndef WIN32 + #include + #include +#endif static void createSubfolders(const char* fileName) { @@ -16,7 +19,13 @@ static void createSubfolders(const char* fileName) { ffStrbufAppendC(&path, *fileName); if(*fileName == '/') - mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH); + { + mkdir(path.chars + #ifndef WIN32 + , S_IRWXU | S_IRGRP | S_IROTH + #endif + ); + } ++fileName; } @@ -151,6 +160,7 @@ bool ffFileExists(const char* fileName, mode_t mode) void ffGetTerminalResponse(const char* request, const char* format, ...) { + #ifndef WIN32 struct termios oldTerm, newTerm; if(tcgetattr(STDIN_FILENO, &oldTerm) == -1) return; @@ -189,4 +199,8 @@ void ffGetTerminalResponse(const char* request, const char* format, ...) va_start(args, format); vsscanf(buffer, format, args); va_end(args); + #else + //Unimplemented + FF_UNUSED(request, format); + #endif } diff --git a/src/common/properties.c b/src/common/properties.c index 8331c6b3f..064d620aa 100644 --- a/src/common/properties.c +++ b/src/common/properties.c @@ -2,6 +2,9 @@ #include "common/properties.h" #include +#ifdef _WIN32 + #include "util/windows/getline.h" +#endif static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer) { diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index 4df85791f..ccf7da36e 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -67,11 +67,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID); ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture); - #ifdef __MSYS__ - ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); - #else - ffStrbufSetS(&os->systemName, "Windows"); - #endif + ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); pclsObj->Release(); pEnumerator->Release(); diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index 8c1466974..c2e5acf04 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -125,6 +125,8 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) // When running outside of MSYS2, /proc/self/xxx doesn't exist and we must find it in Windows way if(getenv("MSYSTEM")) return ffDetectTerminalShellPosix(instance); + #else + FF_UNUSED(instance); #endif static FFTerminalShellResult result; diff --git a/src/fastfetch.c b/src/fastfetch.c index 1520a998c..d21913664 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -10,6 +10,10 @@ #include #include +#ifdef WIN32 + #include "util/windows/getline.h" +#endif + typedef struct CustomValue { bool printKey; @@ -414,6 +418,7 @@ static inline void printCommandHelp(const char* command) static inline void listAvailablePresetsFromFolder(FFstrbuf* folder, uint8_t indentation, const char* folderName) { + #ifndef _WIN32 DIR* dir = opendir(folder->chars); if(dir == NULL) return; @@ -447,6 +452,9 @@ static inline void listAvailablePresetsFromFolder(FFstrbuf* folder, uint8_t inde } closedir(dir); + #else + FF_UNUSED(folder, indentation, folderName); + #endif } static inline void listAvailablePresets(FFinstance* instance) diff --git a/src/fastfetch.h b/src/fastfetch.h index 372fb221b..afb697cbf 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -8,8 +8,13 @@ #include #include -#include -#include +#ifndef _WIN32 + #include + #include +#else + #include "util/windows/pwd.h" + #include "util/windows/utsname.h" +#endif #if FF_HAVE_SYSINFO_H #include diff --git a/src/modules/locale.c b/src/modules/locale.c index c5dd9e1a4..dc2b2b650 100644 --- a/src/modules/locale.c +++ b/src/modules/locale.c @@ -26,10 +26,13 @@ static void getLocaleFromEnv(FFstrbuf* locale) static void getLocaleFromCmd(FFstrbuf* locale) { ffStrbufAppendS(locale, setlocale(LC_ALL, NULL)); + + #ifdef LC_MESSAGES if(locale->length > 0) return; ffStrbufAppendS(locale, setlocale(LC_MESSAGES, NULL)); + #endif } void ffPrintLocale(FFinstance* instance) diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 687969606..8966b569e 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -13,6 +13,11 @@ #include #include +#ifdef _WIN32 + #include + #define strcasestr StrStrIA +#endif + #define FASTFETCH_STRBUF_DEFAULT_ALLOC 32 typedef struct FFstrbuf diff --git a/src/util/windows/getline.c b/src/util/windows/getline.c new file mode 100644 index 000000000..cb1760f78 --- /dev/null +++ b/src/util/windows/getline.c @@ -0,0 +1,58 @@ +#include "getline.h" + +#include +#include + +ssize_t getline(char **lineptr, size_t *n, FILE *stream) { + ssize_t pos = -1; + int c; + + if (lineptr == NULL || stream == NULL || n == NULL) { + errno = EINVAL; + return -1; + } + + _lock_file(stream); + + c = _getc_nolock(stream); + if (c == EOF) { + goto exit; + } + + if (*lineptr == NULL) { + *lineptr = malloc(128); + if (*lineptr == NULL) { + goto exit; + } + *n = 128; + } + + pos = 0; + while(c != EOF) { + if ((size_t)(pos + 1) >= *n) { + size_t new_size = *n + (*n >> 2); + if (new_size < 128) { + new_size = 128; + } + char *new_ptr = realloc(*lineptr, new_size); + if (new_ptr == NULL) { + pos = -1; + goto exit; + } + *n = new_size; + *lineptr = new_ptr; + } + + ((char *)(*lineptr))[pos ++] = (char)c; + if (c == '\n') { + break; + } + c = _getc_nolock(stream); + } + + (*lineptr)[pos] = '\0'; + +exit: + _unlock_file(stream); + return pos; +} diff --git a/src/util/windows/getline.h b/src/util/windows/getline.h new file mode 100644 index 000000000..e4f48a4cf --- /dev/null +++ b/src/util/windows/getline.h @@ -0,0 +1,11 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_UTIL_GETLINE +#define FASTFETCH_INCLUDED_UTIL_GETLINE + +#include +#include + +ssize_t getline(char **lineptr, size_t *n, FILE *stream); + +#endif diff --git a/src/util/windows/pwd.c b/src/util/windows/pwd.c new file mode 100644 index 000000000..a52f2689a --- /dev/null +++ b/src/util/windows/pwd.c @@ -0,0 +1,17 @@ +#include "pwd.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include + +struct passwd* ffGetPasswd() +{ + static struct passwd res; + + DWORD len = sizeof(res.pw_name); + GetUserNameA(res.pw_name, &len); + + SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, res.pw_dir); + + return &res; +} diff --git a/src/util/windows/pwd.h b/src/util/windows/pwd.h new file mode 100644 index 000000000..29d4c883b --- /dev/null +++ b/src/util/windows/pwd.h @@ -0,0 +1,22 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_UTIL_PWD +#define FASTFETCH_INCLUDED_UTIL_PWD + +#include +#include + +struct passwd +{ + char pw_name[UNLEN + 1]; /* username */ + // char *pw_passwd[1]; /* user password */ + // int pw_uid; /* user ID */ + // int pw_gid; /* group ID */ + // char *pw_gecos; /* user information */ + char pw_dir[MAX_PATH]; /* home directory */ + // char *pw_shell; /* shell program */ +}; + +struct passwd* ffGetPasswd(); + +#endif diff --git a/src/util/windows/utsname.c b/src/util/windows/utsname.c new file mode 100644 index 000000000..403f5e6fd --- /dev/null +++ b/src/util/windows/utsname.c @@ -0,0 +1,59 @@ +// https://github.com/tniessen/iperf-windows/blob/master/win32-compat/sys/utsname.c + +#define WIN32_LEAN_AND_MEAN +#include + +#include + +#include "utsname.h" + +int uname(struct utsname *name) +{ + memset(name, 0, sizeof(*name)); + + // Get Windows version info + OSVERSIONINFOA versionInfo = { + .dwOSVersionInfoSize = sizeof(OSVERSIONINFO), + }; + GetVersionExA(&versionInfo); + + // Get hardware info + SYSTEM_INFO sysInfo = {0}; + GetSystemInfo(&sysInfo); + + // Set implementation name + strcpy(name->sysname, "Windows_NT"); + sprintf(name->release, "%u.%u.%u", (unsigned)versionInfo.dwMajorVersion, (unsigned)versionInfo.dwMinorVersion, (unsigned)versionInfo.dwBuildNumber); + name->version[0] = '\0'; + + // Set hostname + DWORD bufSize = UTSNAME_MAXLENGTH - 1; + if(GetComputerNameA(name->nodename, &bufSize)) + return 1; + name->nodename[bufSize] = '\0'; + + // Set processor architecture + switch (sysInfo.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_AMD64: + strcpy(name->machine, "x86_64"); + break; + case PROCESSOR_ARCHITECTURE_IA64: + strcpy(name->machine, "ia64"); + break; + case PROCESSOR_ARCHITECTURE_INTEL: + strcpy(name->machine, "x86"); + break; + case PROCESSOR_ARCHITECTURE_ARM64: + strcpy(name->machine, "aarch64"); + break; + case PROCESSOR_ARCHITECTURE_ARM: + strcpy(name->machine, "arm"); + break; + case PROCESSOR_ARCHITECTURE_UNKNOWN: + default: + strcpy(name->machine, "unknown"); + } + + return 0; +} diff --git a/src/util/windows/utsname.h b/src/util/windows/utsname.h new file mode 100644 index 000000000..96bc53adc --- /dev/null +++ b/src/util/windows/utsname.h @@ -0,0 +1,19 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_UTSNAME_H +#define FASTFETCH_INCLUDED_UTSNAME_H + +#define UTSNAME_MAXLENGTH 256 + +struct utsname +{ + char sysname[UTSNAME_MAXLENGTH]; // name of this implementation of the operating system + char nodename[UTSNAME_MAXLENGTH]; // name of this node within an implementation - dependent communications network + char release[UTSNAME_MAXLENGTH]; // current release level of this implementation + char version[UTSNAME_MAXLENGTH]; // current version level of this release + char machine[UTSNAME_MAXLENGTH]; // name of the hardware type on which the system is running +}; + +int uname(struct utsname *name); + +#endif diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index 925d428ee..9b1a120d0 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -13,9 +13,6 @@ static void CoUninitializeWrap() static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) { - static char error[128]; - *((char**)lpContext) = error; - HRESULT hres; // Initialize COM @@ -37,7 +34,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) if (FAILED(hres)) { CoUninitialize(); - snprintf(error, sizeof(error), "Failed to initialize security. Error code = 0x%X", hres); + *((const char**)lpContext) = "Failed to initialize security"; return FALSE; } @@ -53,7 +50,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) if (FAILED(hres)) { CoUninitialize(); - snprintf(error, sizeof(error), "Failed to create IWbemLocator object. Error code = 0x%X", hres); + *((const char**)lpContext) = "Failed to create IWbemLocator object"; return FALSE; } @@ -79,7 +76,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) if (FAILED(hres)) { CoUninitialize(); - snprintf(error, sizeof(error), "Could not connect WMI server. Error code = 0x%X", hres); + *((const char**)lpContext) = "Could not connect WMI server"; return FALSE; } @@ -99,7 +96,7 @@ static BOOL CALLBACK InitHandleFunction(PINIT_ONCE, PVOID, PVOID *lpContext) { pSvc->Release(); CoUninitialize(); - snprintf(error, sizeof(error), "Could not set proxy blanket. Error code = 0x%X", hres); + *((const char**)lpContext) = "Could not set proxy blanket"; return FALSE; } @@ -134,7 +131,7 @@ IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error) if (FAILED(hres)) { if(error) - ffStrbufAppendF(error, "Query for '%ls' failed. Error code = 0x%X", queryStr, hres); + ffStrbufAppendF(error, "Query for '%ls' failed. Error code = 0x%lX", queryStr, hres); return nullptr; } From 952cacf3ffe48d58de1fa28267e22226f9450568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 18:28:43 +0800 Subject: [PATCH 6/8] ci: build with Windows native --- .github/workflows/push.yml | 68 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 76fd9ede9..6dc59f29e 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -123,8 +123,8 @@ jobs: name: fastfetch-bsd path: ./fastfetch-*.* - windows: - name: Windows + msys: + name: MSYS runs-on: windows-latest permissions: security-events: write @@ -179,6 +179,70 @@ jobs: - name: run flashfetch run: ./flashfetch + - name: upload artifacts + uses: actions/upload-artifact@v3 + with: + name: fastfetch-msys + path: | + ./*.dll + ./*.exe + + windows: + name: Windows + runs-on: windows-latest + permissions: + security-events: write + contents: read + outputs: + ffversion: ${{ steps.ffversion.outputs.ffversion }} + defaults: + run: + shell: msys2 {0} + steps: + - name: checkout repository + uses: actions/checkout@v3 + + - name: setup-msys2 + uses: msys2/setup-msys2@v2 + with: + msystem: CLANG64 + update: true + install: git mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-cjson mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd + + - name: print msys version + run: uname -a + + # https://github.com/msys2/MINGW-packages/issues/13524#event-7555720785 + - name: create OpenCL.pc + run: | + cat > /clang64/lib/pkgconfig/OpenCL.pc << EOF + prefix=/clang64 + exec_prefix=${prefix} + libdir=${exec_prefix}/lib + includedir=${prefix}/include + + Name: OpenCL + Description: Open Computing Language generic Installable Client Driver Loader + Version: 2022.09.30-1 + Libs: -L${libdir} -lOpenCL.dll + Cflags: -I${includedir} + EOF + + - name: configure project + run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . + + - name: build project + run: cmake --build . --target fastfetch --target flashfetch + + - name: copy necessary dlls + run: cp /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . + + - name: run fastfetch + run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + + - name: run flashfetch + run: ./flashfetch + - name: upload artifacts uses: actions/upload-artifact@v3 with: From 79cfa96616c63bf81ded22b59510cf67467f1e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 20:06:54 +0800 Subject: [PATCH 7/8] Processing: fix Windows impl --- src/common/processing_windows.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index f3bb64a2d..9ec6da811 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -28,12 +28,11 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) }; FFstrbuf cmdline; - ffStrbufInit(&cmdline); - for(char* const* parg = argv; *parg; ++parg) + ffStrbufInitS(&cmdline, argv[0]); + for(char* const* parg = &argv[1]; *parg; ++parg) { - if(cmdline.length > 0) - ffStrbufAppendC(&cmdline, ' '); - ffStrbufAppendF(&cmdline, "\"%s\"", * parg); + ffStrbufAppendC(&cmdline, ' '); + ffStrbufAppendS(&cmdline, *parg); } BOOL success = CreateProcessA( @@ -48,6 +47,8 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) &siStartInfo, // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION + ffStrbufDestroy(&cmdline); + CloseHandle(hChildStdoutWrite); if(!success) { @@ -55,14 +56,10 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) return "CreateProcessA() failed"; } - char str[128]; + char str[1024]; DWORD nRead; while(ReadFile(hChildStdoutRead, str, sizeof(str), &nRead, NULL) && nRead > 0) - { ffStrbufAppendNS(buffer, nRead, str); - if(nRead < sizeof(str)) - break; - } CloseHandle(hChildStdoutRead); return NULL; From 6f66b8726228b69dcd71e091aef049333272ef5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 13 Oct 2022 22:28:43 +0800 Subject: [PATCH 8/8] Windows: support --list-presets --- src/detection/packages/packages_windows.c | 2 +- src/fastfetch.c | 38 +++++++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index b64374e0e..d9712b6f7 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -15,7 +15,7 @@ static uint32_t getNumElements(const char* searchPath /* including `\*` suffix * { if(wfd.dwFileAttributes & type) counter++; - } while (FindNextFileA(hFind, &wfd) == TRUE); + } while (FindNextFileA(hFind, &wfd)); FindClose(hFind); } diff --git a/src/fastfetch.c b/src/fastfetch.c index d21913664..817dd5dba 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -7,11 +7,13 @@ #include #include #include -#include #include #ifdef WIN32 #include "util/windows/getline.h" + #include +#else + #include #endif typedef struct CustomValue @@ -434,7 +436,6 @@ static inline void listAvailablePresetsFromFolder(FFstrbuf* folder, uint8_t inde { if(entry->d_type == DT_DIR) { - if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; @@ -453,7 +454,38 @@ static inline void listAvailablePresetsFromFolder(FFstrbuf* folder, uint8_t inde closedir(dir); #else - FF_UNUSED(folder, indentation, folderName); + uint32_t folderLength = folder->length; + + if(folderName != NULL) + printf("%s/\n", folderName); + + ffStrbufAppendC(folder, '*'); + WIN32_FIND_DATAA entry; + HANDLE hFind = FindFirstFileA(folder->chars, &entry); + if(hFind == INVALID_HANDLE_VALUE) + return; + + do + { + if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if(strcmp(entry.cFileName, ".") == 0 || strcmp(entry.cFileName, "..") == 0) + continue; + + ffStrbufSubstrBefore(folder, folderLength); + ffStrbufAppendS(folder, entry.cFileName); + ffStrbufAppendC(folder, '/'); + listAvailablePresetsFromFolder(folder, (uint8_t) (indentation + 1), entry.cFileName); + ffStrbufSubstrBefore(folder, folderLength); + continue; + } + + for(uint8_t i = 0; i < indentation; i++) + fputs(" | ", stdout); + + puts(entry.cFileName); + } while (FindNextFileA(hFind, &entry)); + FindClose(hFind); #endif }