diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 0fb775db32..f70839bb64 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,27 +7,36 @@ assignees: '' --- + + # General description of bug: +* What happened: +* What should happen: +* Did it work in an older version: +* Where did you get the binary: +* Does this issue still occurs in [the latest dev build](https://github.com/fastfetch-cli/fastfetch/actions/)? -# Often helpful questions: -* Does the issue occur across multiple terminal emulators? [Y/N] -* Does the issue occur across multiple shells? (bash, zsh, fish, etc) [Y/N] +# Often helpful information: Output of `fastfetch --version`: ``` //paste here ``` -Output of `fastfetch --load-config devinfo`: +The content of the configuration file you use (if any) ``` //paste here ``` -Output of `fastfetch --load-config devinfo-verbose`: +Output of `env NO_CONFIG=1 fastfetch --load-config all --show-errors --stat --multithreading false --disable-linewrap false --hide-cursor false`: + ``` //paste here ``` @@ -37,7 +46,39 @@ Output of `fastfetch --list-features`: //paste here ``` - +## If fastfatch crashed + +Paste the stacktrace here. You may get it with: + +``` +$ gdb /path/to/fastfetch +$ run +$ bt +``` + +If you are able to identify which module crashed, the strace can be helpful too + +``` +$ strace /path/to/fastfetch --multithreading false --structure {MODULE} --pipe +``` + +If you cannot do the instructions above, please upload the core dump file: + +## If my image logo didn't show / work + + + +* The image protocol you used: +* The terminal you used: +* Upload the image file here, or paste the image URL: +* Does it work with `--logo-width {WIDTH} --logo-height {HEIGHT}`? + +## If fastfetch behaves incorrectly on shell starting + + + +* The bug is reproduceable with fresh / clean shell configuration (i.e. `fastfetch` is the single line of `.zshrc` or `~/.config/fish/config.fish`): +* Does `sleep 1` before running `fastfetch` work? diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa24564499..fcc466ccfe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,15 +13,19 @@ jobs: fail-fast: false matrix: os: [ubuntu-22.04, ubuntu-20.04] - compiler: [gcc, clang] + compiler: [gcc, clang, "musl-gcc"] enableFeatures: [ON, OFF] + exclude: + # The feature libraries are all build against glibc, so they can't be used with musl + - compiler: "musl-gcc" + enableFeatures: ON runs-on: ${{ matrix.os }} steps: - name: checkout repository uses: actions/checkout@v3 - name: install required packages - run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libcjson-dev + run: sudo apt-get update && sudo apt-get install -y musl-dev musl-tools linux-headers-generic libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev - name: configure project env: @@ -35,7 +39,7 @@ jobs: run: ctest - name: run fastfetch - run: ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all - name: run flashfetch run: ./flashfetch @@ -53,7 +57,7 @@ jobs: uses: actions/checkout@v3 - name: install required packages - run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libcjson-dev + run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev - name: Initialize CodeQL uses: github/codeql-action/init@v2 @@ -73,7 +77,7 @@ jobs: run: ./fastfetch --list-features - name: run fastfetch - run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all - name: run flashfetch run: time ./flashfetch @@ -110,7 +114,7 @@ jobs: languages: c - name: configure project - run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . + run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' . - name: build project run: cmake --build . --target package @@ -122,7 +126,7 @@ jobs: run: ./fastfetch --list-features - name: run fastfetch - run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all - name: run flashfetch run: time ./flashfetch @@ -155,7 +159,7 @@ jobs: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . cmake --build . --target package ./fastfetch --list-features - time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all time ./flashfetch ctest @@ -183,7 +187,7 @@ jobs: with: msystem: CLANG64 update: true - install: git zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-cjson + install: git zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd - name: print msys version run: uname -a @@ -203,13 +207,13 @@ jobs: uses: github/codeql-action/analyze@v2 - name: copy necessary dlls - run: cp /clang64/bin/{libcjson,OpenCL,vulkan-1}.dll . + run: cp /clang64/bin/{OpenCL,vulkan-1}.dll . - name: list features run: ./fastfetch --list-features - name: run fastfetch - run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all - name: run flashfetch run: time ./flashfetch @@ -244,7 +248,7 @@ jobs: with: msystem: CLANG32 update: true - install: git zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-opencl-icd mingw-w64-clang-i686-cjson + install: git zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-opencl-icd - name: print msys version run: uname -a @@ -264,10 +268,10 @@ jobs: uses: github/codeql-action/analyze@v2 - name: copy necessary dlls - run: cp /clang32/bin/{libcjson,OpenCL,vulkan-1}.dll . + run: cp /clang32/bin/{OpenCL,vulkan-1}.dll . - name: run fastfetch - run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all + run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all - name: run flashfetch run: time ./flashfetch diff --git a/CHANGELOG.md b/CHANGELOG.md index 35abb70380..89cfb0b402 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,63 @@ +# 2.0.0 (beta) + +Fastfetch v2 introduces a new configuration file format: JSON config. Please refer to for details. + +Changes: +* Drop the dependency of cJSON. We now use [yyjson](https://ibireme.github.io/yyjson/doc/doxygen/html/index.html) to parse JSON documents. +* Remove `--shell-version` and `--terminal-version`. They are always enabled (Terminal / Shell) +* Remove `--*-error-format`, which seems to be useless +* Remove `--display-detect-name`. Display name is always detected, and will be printed if multiple displays are detected +* Deprecate `--set` and `--set-keyless`; they may be removed in future releases. Use JSON config with Custom module instead +* Remove the special handling of Command module (it can be set once in the triditional `config.conf`). Use JSON config with Command module instead +* Change `--wm-theme-*` to `--wmtheme-*`. Affect `key` and `format` (WMTheme) +* Change `--terminal-font-*` to `--terminalfont-*`. Affect `key` and `format` (TerminalFont) +* Module `Command` uses `/bin/sh` as the default shell on systems other than Windows (Command) +* Fix M2 CPU temperature detection (CPU, macOS) +* Detect monitor name when available, instead of using DRM connector name (Display / Brightness, Linux) + +Features: +* FreeBSD support is improved greatly, and actually tested in a physical machine +* Add `--no-buffer` option for easier debugging. CMake option `ENABLE_BUFFER` is removed and always enabled. +* Support `--*-key-color` option to change the key color of specified module +* Support `--colors-symbol` and `--colors-padding-left` (Colors) +* Add LM (Login Manager) module. Currently requires systemd installed (thus Linux only) +* Add `--wmi-timeout` option (Windows) +* Add `--logo-type small` to search for small logos +* Support detecting brightness of external displays with DDC/CI (guard behind `--allow-slow-operations`) (Brightness) +* Add option `--size-ndigits` and `--size-max-prefix` (#494) +* Add option `--processing-timeout` to the timeout when waiting for child processes. +* Public IP module prints the IP location if `--publicip-url` is not set (PublicIP) +* Add option `--localip-default-route-only` (LocalIP) +* Add option `--weather-location` (Weather) +* Support iTerm non-ascii font detection (Terminal, macOS) +* Add option `--title-color-user`, `--title-color-at` and `--title-color-host` (Title) +* Add Exherbo logo and package manager count (Packages, Linux, #503) +* Add module `Terminal Size` which prints the number of terminal width and height in charactors and pixels +* Add new option `--temperature-unit` +* Better CPU and Host detection for Android (Android) +* Support yakuake terminal version & font detection (Terminal, Linux) +* Add new option `--bright-color` which can be used to disable the default bright color of keys, title and ASCII logo. +* Add module `Monitor` which prints physical parameters (native resolutions and demensions) of connected monitors +* Support path with environment variables for `--logo-source` and `--load-config`. + +Bugfixes: +* Fix possible hanging (TerminalFont, #493) +* Fix heap-buffer-overflow reading (DisplayServer, Linux) +* Fix false errors when built without libnm support (Wifi, Linux) +* Properly detect CPU on POWER (CPU, Linux) +* Fix compatibility with Fig (Terminal, macOS) +* Fix option `--title-fqdn` doesn't work (Title) +* Fix used spaces calculation (Disk, Linux / BSD / macOS, #508) +* Fix `--brightness-format` (Brightness) +* Fix specifying `--set-keyless` with the same key second time won't override the value set before (#517) +* Fix specifying `--color` second time won't clear the value set before (#517) + +Logo: +* Change the special handling of `kitty` protocol with `.png` image file to a new image protocol `kitty-direct`. This is the fastest image protocol because fastfetch doesn't need to pre-encode the image to base64 or something and the image content doesn't need to be transmitted via tty. Note: + 1. Although konsole was said to support `kitty` image protocol, it doesn't support `kitty-direct` + 2. wezterm support more image formats other than `.png` (tested with `.jpg` and `.webp`) +* Port all logos supported by neo(wo)fetch. Fastfetch now has 350 builtin logos in total. + # 1.12.2 Features: diff --git a/CMakeLists.txt b/CMakeLists.txt index 870be383b8..d461a209e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ -cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url +cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url & FetchContent project(fastfetch - VERSION 1.12.2 + VERSION 2.0.0 LANGUAGES C DESCRIPTION "Fast system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch" @@ -22,10 +22,6 @@ elseif(NOT APPLE AND NOT WIN32) message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") endif() -if(WIN32) - enable_language(CXX) -endif() - ############################# # Compile time dependencies # ############################# @@ -40,6 +36,24 @@ endif() include(CheckIncludeFile) +include(FetchContent) +function(ff_fetch_dep package repo tag) + FetchContent_Declare( + "${package}" + GIT_REPOSITORY "${repo}" + GIT_TAG "${tag}" + GIT_PROGRESS TRUE + ) + FetchContent_GetProperties("${package}") + if(NOT ${package}_POPULATED) + message("-- Fetching dependency ${package}@${tag} from ${repo}") + FetchContent_Populate(${package}) + add_subdirectory(${${package}_SOURCE_DIR} ${${package}_BINARY_DIR} EXCLUDE_FROM_ALL) + endif() +endfunction() + +ff_fetch_dep(yyjson "https://github.com/ibireme/yyjson" "0.7.0") + ##################### # Configure options # ##################### @@ -70,9 +84,9 @@ cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32" cmake_dependent_option(ENABLE_LIBNM "Enable libnm" ON "LINUX" OFF) cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR WIN32" OFF) +cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF) cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF) -cmake_dependent_option(ENABLE_BUFFER "Enable stdout buffer" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF) +cmake_dependent_option(ENABLE_PCI_MEMORY "Enable detecting GPU memory size with libpci" OFF "LINUX OR BSD" 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 @@ -82,7 +96,7 @@ option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by gith #################### if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) + set(CMAKE_BUILD_TYPE RelWithDebInfo) endif() message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") @@ -102,7 +116,8 @@ set(CMAKE_C_STANDARD 11) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration") if(WIN32) - set(CMAKE_CXX_STANDARD 11) + enable_language(CXX) + set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -fno-exceptions -fno-rtti") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--tsaware -Wl,--build-id -Wl,--subsystem,console:6.1,--major-os-version,6,--minor-os-version,1") endif() @@ -212,17 +227,42 @@ endfunction(fastfetch_load_text) fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE) fastfetch_load_text(src/data/config_system.txt DATATEXT_CONFIG_SYSTEM) fastfetch_load_text(src/data/config_user.txt DATATEXT_CONFIG_USER) +fastfetch_load_text(src/data/config_user.jsonc DATATEXT_CONFIG_USER_JSONC) fastfetch_load_text(src/data/modules.txt DATATEXT_MODULES) fastfetch_load_text(src/data/help.txt DATATEXT_HELP) fastfetch_load_text(src/data/help_color.txt DATATEXT_HELP_COLOR) fastfetch_load_text(src/data/help_format.txt DATATEXT_HELP_FORMAT) fastfetch_load_text(src/data/help_config.txt DATATEXT_HELP_CONFIG) -###################### -# Configure config.h # -###################### +configure_file(src/fastfetch_config.h.in fastfetch_config.h @ONLY) +configure_file(src/fastfetch_datatext.h.in fastfetch_datatext.h @ONLY) + +#################### +# Ascii image data # +#################### -configure_file(src/fastfetch_config.h.in fastfetch_config.h) +function(fastfetch_load_raw_text FILENAME OUTVAR) + file(READ "${FILENAME}" TEMP) + string(REGEX REPLACE "\n$" "" TEMP "${TEMP}") # Remove trailing newline + string(JSON TEMP SET "{}" "${TEMP}" "0") # Encode raw strings using JSON_SET + string(REGEX REPLACE "^\\{[ \t\r\n]*" "" TEMP "${TEMP}") # Remove JSON braces + string(REGEX REPLACE "[ \t\r\n]*:[ \t\r\n]*0[ \t\r\n]*\\}$" "" TEMP "${TEMP}") # Remove trailing ` : 0 }` + if(NOT "${TEMP}" MATCHES "^\"[^\n]*\"") + message(FATAL_ERROR "Internal error: unexpected output: '${TEMP}'") + endif() + set(${OUTVAR} "${TEMP}" PARENT_SCOPE) +endfunction(fastfetch_load_raw_text) + +file(GLOB LOGO_FILES "src/logo/ascii/*.txt") +set(LOGO_BUILTIN_H "#pragma once\n\n") +foreach(file ${LOGO_FILES}) + fastfetch_load_raw_text("${file}" content) + get_filename_component(file "${file}" NAME_WLE) + string(TOUPPER "${file}" file) + string(REGEX REPLACE "\\$\\{c([0-9]+)\\}" "$\\1" content "${content}") + set(LOGO_BUILTIN_H "${LOGO_BUILTIN_H}#define FASTFETCH_DATATEXT_LOGO_${file} ${content}\n") +endforeach() +file(GENERATE OUTPUT logo_builtin.h CONTENT "${LOGO_BUILTIN_H}") ####################### # libfastfetch target # @@ -233,20 +273,21 @@ set(LIBFASTFETCH_SRC src/common/font.c src/common/format.c src/common/init.c + src/common/jsonconfig.c src/common/library.c + src/common/option.c src/common/parsing.c src/common/printing.c src/common/properties.c src/common/settings.c - src/detection/bluetooth/bluetooth.c + src/detection/chassis/chassis.c src/detection/cpu/cpu.c - src/detection/cpuUsage/cpuUsage.c + src/detection/cpuusage/cpuusage.c src/detection/datetime/datetime.c src/detection/disk/disk.c src/detection/displayserver/displayserver.c src/detection/font/font.c src/detection/gpu/gpu.c - src/detection/host/host.c src/detection/locale/locale.c src/detection/media/media.c src/detection/opencl/opencl.c @@ -260,64 +301,67 @@ set(LIBFASTFETCH_SRC src/logo/image/im7.c src/logo/image/image.c src/logo/logo.c - src/modules/battery.c - src/modules/bios.c - src/modules/bluetooth.c - src/modules/board.c - src/modules/brightness.c - src/modules/break.c - src/modules/chassis.c - src/modules/colors.c - src/modules/cpu.c - src/modules/cpuUsage.c - src/modules/cursor.c - src/modules/custom.c - src/modules/command.c - src/modules/date.c - src/modules/datetime.c - src/modules/de.c - src/modules/disk.c - src/modules/font.c - src/modules/gpu.c - src/modules/host.c - src/modules/icons.c - src/modules/gamepad.c - src/modules/kernel.c - src/modules/locale.c - src/modules/localip.c - src/modules/memory.c - src/modules/opencl.c - src/modules/opengl.c - src/modules/os.c - src/modules/packages.c - src/modules/player.c - src/modules/poweradapter.c - src/modules/processes.c - src/modules/publicip.c - src/modules/display.c - src/modules/separator.c - src/modules/shell.c - src/modules/sound.c - src/modules/swap.c - src/modules/media.c - src/modules/terminal.c - src/modules/terminalfont.c - src/modules/theme.c - src/modules/time.c - src/modules/title.c - src/modules/uptime.c - src/modules/users.c - src/modules/vulkan.c - src/modules/wallpaper.c - src/modules/weather.c - src/modules/wifi.c - src/modules/wm.c - src/modules/wmtheme.c + src/logo/option.c + src/modules/battery/battery.c + src/modules/bios/bios.c + src/modules/bluetooth/bluetooth.c + src/modules/board/board.c + src/modules/brightness/brightness.c + src/modules/break/break.c + src/modules/chassis/chassis.c + src/modules/colors/colors.c + src/modules/cpu/cpu.c + src/modules/cpuusage/cpuusage.c + src/modules/cursor/cursor.c + src/modules/custom/custom.c + src/modules/command/command.c + src/modules/datetime/datetime.c + src/modules/de/de.c + src/modules/disk/disk.c + src/modules/font/font.c + src/modules/gpu/gpu.c + src/modules/host/host.c + src/modules/icons/icons.c + src/modules/gamepad/gamepad.c + src/modules/kernel/kernel.c + src/modules/lm/lm.c + src/modules/locale/locale.c + src/modules/localip/localip.c + src/modules/memory/memory.c + src/modules/monitor/monitor.c + src/modules/opencl/opencl.c + src/modules/opengl/opengl.c + src/modules/os/os.c + src/modules/packages/packages.c + src/modules/processes/processes.c + src/modules/player/player.c + src/modules/poweradapter/poweradapter.c + src/modules/publicip/publicip.c + src/modules/display/display.c + src/modules/separator/separator.c + src/modules/shell/shell.c + src/modules/sound/sound.c + src/modules/swap/swap.c + src/modules/media/media.c + src/modules/terminal/terminal.c + src/modules/terminalfont/terminalfont.c + src/modules/terminalsize/terminalsize.c + src/modules/theme/theme.c + src/modules/title/title.c + src/modules/uptime/uptime.c + src/modules/users/users.c + src/modules/vulkan/vulkan.c + src/modules/wallpaper/wallpaper.c + src/modules/weather/weather.c + src/modules/wifi/wifi.c + src/modules/wm/wm.c + src/modules/wmtheme/wmtheme.c + src/util/edidHelper.c src/util/FFlist.c src/util/FFstrbuf.c - src/util/FFvaluestore.c src/util/platform/FFPlatform.c src/util/stringUtils.c + src/util/smbiosHelper.c ) if(LINUX) @@ -332,7 +376,7 @@ if(LINUX) src/detection/brightness/brightness_linux.c src/detection/chassis/chassis_linux.c src/detection/cpu/cpu_linux.c - src/detection/cpuUsage/cpuUsage_linux.c + src/detection/cpuusage/cpuusage_linux.c src/detection/cursor/cursor_linux.c src/detection/bluetooth/bluetooth_linux.c src/detection/disk/disk_linux.c @@ -346,10 +390,12 @@ if(LINUX) src/detection/gtk_qt/gtk.c src/detection/host/host_linux.c src/detection/icons/icons_linux.c + src/detection/lm/lm_linux.c src/detection/localip/localip_linux.c src/detection/gamepad/gamepad_linux.c src/detection/media/media_linux.c src/detection/memory/memory_linux.c + src/detection/monitor/monitor_linux.c src/detection/opengl/opengl_linux.c src/detection/os/os_linux.c src/detection/packages/packages_linux.c @@ -361,6 +407,7 @@ if(LINUX) src/detection/temps/temps_linux.c src/detection/terminalfont/terminalfont_linux.c src/detection/terminalshell/terminalshell_linux.c + src/detection/terminalsize/terminalsize_linux.c src/detection/theme/theme_linux.c src/detection/uptime/uptime_linux.c src/detection/users/users_linux.c @@ -375,24 +422,26 @@ elseif(ANDROID) src/common/networking_linux.c src/common/processing_linux.c src/detection/battery/battery_android.c - src/detection/bios/bios_nosupport.c + src/detection/bios/bios_android.c src/detection/bluetooth/bluetooth_nosupport.c - src/detection/board/board_nosupport.c + src/detection/board/board_android.c src/detection/brightness/brightness_nosupport.c src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_linux.c src/detection/cursor/cursor_nosupport.c - src/detection/cpuUsage/cpuUsage_linux.c + src/detection/cpuusage/cpuusage_linux.c src/detection/disk/disk_linux.c - src/detection/displayserver/displayserver_nosupport.c + src/detection/displayserver/displayserver_android.c src/detection/font/font_nosupport.c src/detection/gpu/gpu_nosupport.c src/detection/host/host_android.c src/detection/icons/icons_nosupport.c + src/detection/lm/lm_nosupport.c src/detection/localip/localip_linux.c src/detection/gamepad/gamepad_nosupport.c src/detection/media/media_nosupport.c src/detection/memory/memory_linux.c + src/detection/monitor/monitor_nosupport.c src/detection/opengl/opengl_linux.c src/detection/os/os_android.c src/detection/packages/packages_linux.c @@ -403,6 +452,7 @@ elseif(ANDROID) src/detection/temps/temps_linux.c src/detection/terminalfont/terminalfont_android.c src/detection/terminalshell/terminalshell_linux.c + src/detection/terminalsize/terminalsize_linux.c src/detection/theme/theme_nosupport.c src/detection/uptime/uptime_linux.c src/detection/users/users_linux.c @@ -421,11 +471,11 @@ elseif(BSD) src/detection/battery/battery_bsd.c src/detection/bios/bios_bsd.c src/detection/bluetooth/bluetooth_linux.c - src/detection/board/board_nosupport.c - src/detection/brightness/brightness_nosupport.c - src/detection/chassis/chassis_nosupport.c + src/detection/board/board_bsd.c + src/detection/brightness/brightness_bsd.c + src/detection/chassis/chassis_bsd.c src/detection/cpu/cpu_bsd.c - src/detection/cpuUsage/cpuUsage_bsd.c + src/detection/cpuusage/cpuusage_bsd.c src/detection/cursor/cursor_linux.c src/detection/disk/disk_bsd.c src/detection/displayserver/linux/displayserver_linux.c @@ -437,11 +487,13 @@ elseif(BSD) src/detection/gpu/gpu_linux.c src/detection/gtk_qt/gtk.c src/detection/host/host_bsd.c + src/detection/lm/lm_linux.c src/detection/icons/icons_linux.c src/detection/localip/localip_linux.c - src/detection/gamepad/gamepad_nosupport.c + src/detection/gamepad/gamepad_bsd.c src/detection/media/media_linux.c src/detection/memory/memory_bsd.c + src/detection/monitor/monitor_nosupport.c src/detection/opengl/opengl_linux.c src/detection/os/os_linux.c src/detection/packages/packages_linux.c @@ -450,14 +502,15 @@ elseif(BSD) src/detection/gtk_qt/qt.c src/detection/sound/sound_linux.c src/detection/swap/swap_bsd.c - src/detection/temps/temps_linux.c + src/detection/temps/temps_bsd.c src/detection/terminalfont/terminalfont_linux.c src/detection/terminalshell/terminalshell_linux.c + src/detection/terminalsize/terminalsize_linux.c src/detection/theme/theme_linux.c src/detection/uptime/uptime_bsd.c src/detection/users/users_linux.c src/detection/wallpaper/wallpaper_linux.c - src/detection/wifi/wifi_nosupport.c + src/detection/wifi/wifi_bsd.c src/detection/wmtheme/wmtheme_linux.c src/util/platform/FFPlatform_unix.c ) @@ -474,7 +527,7 @@ elseif(APPLE) src/detection/brightness/brightness_apple.c src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_apple.c - src/detection/cpuUsage/cpuUsage_apple.c + src/detection/cpuusage/cpuusage_apple.c src/detection/cursor/cursor_apple.m src/detection/disk/disk_apple.m src/detection/disk/disk_bsd.c @@ -482,11 +535,13 @@ elseif(APPLE) src/detection/font/font_apple.m src/detection/gpu/gpu_apple.c src/detection/host/host_apple.c + src/detection/lm/lm_nosupport.c src/detection/icons/icons_nosupport.c src/detection/localip/localip_linux.c src/detection/gamepad/gamepad_apple.c src/detection/media/media_apple.m src/detection/memory/memory_apple.c + src/detection/monitor/monitor_apple.m src/detection/opengl/opengl_apple.c src/detection/os/os_apple.m src/detection/packages/packages_apple.c @@ -497,6 +552,7 @@ elseif(APPLE) src/detection/temps/temps_apple.c src/detection/terminalfont/terminalfont_apple.m src/detection/terminalshell/terminalshell_linux.c + src/detection/terminalsize/terminalsize_linux.c src/detection/theme/theme_nosupport.c src/detection/uptime/uptime_bsd.c src/detection/users/users_linux.c @@ -517,9 +573,9 @@ elseif(WIN32) src/detection/bluetooth/bluetooth_windows.c src/detection/board/board_windows.c src/detection/brightness/brightness_windows.cpp - src/detection/chassis/chassis_nosupport.c + src/detection/chassis/chassis_windows.cpp src/detection/cpu/cpu_windows.c - src/detection/cpuUsage/cpuUsage_windows.c + src/detection/cpuusage/cpuusage_windows.c src/detection/cursor/cursor_windows.c src/detection/disk/disk_windows.c src/detection/displayserver/displayserver_windows.c @@ -527,10 +583,12 @@ elseif(WIN32) src/detection/gpu/gpu_windows.c src/detection/host/host_windows.c src/detection/icons/icons_windows.c + src/detection/lm/lm_nosupport.c src/detection/localip/localip_windows.c src/detection/gamepad/gamepad_windows.c src/detection/media/media_nosupport.c src/detection/memory/memory_windows.c + src/detection/monitor/monitor_windows.c src/detection/opengl/opengl_windows.c src/detection/os/os_windows.cpp src/detection/packages/packages_windows.c @@ -540,6 +598,7 @@ elseif(WIN32) src/detection/swap/swap_windows.c src/detection/terminalfont/terminalfont_windows.c src/detection/terminalshell/terminalshell_windows.c + src/detection/terminalsize/terminalsize_windows.c src/detection/temps/temps_windows.cpp src/detection/theme/theme_nosupport.c src/detection/uptime/uptime_windows.c @@ -556,11 +615,17 @@ elseif(WIN32) ) endif() +include(CheckFunctionExists) +check_function_exists(wcwidth HAVE_WCWIDTH) +if(NOT HAVE_WCWIDTH) + list(APPEND LIBFASTFETCH_SRC src/util/wcwidth.c) +endif() + add_library(libfastfetch OBJECT ${LIBFASTFETCH_SRC} ) -target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE) +target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE) if(WIN32) target_compile_definitions(libfastfetch PUBLIC WIN32_LEAN_AND_MEAN=1) endif() @@ -570,6 +635,10 @@ if(HAVE_UTMPX_H) target_compile_definitions(libfastfetch PRIVATE FF_HAVE_UTMPX_H) endif() +if(HAVE_WCWIDTH) + target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WCWIDTH) +endif() + function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME) if(NOT ENABLE_${VARNAME}) return() @@ -702,9 +771,9 @@ ff_lib_enable(PULSE "libpulse" "Pulse" ) -ff_lib_enable(LIBCJSON - "libcjson" - "CJson" +ff_lib_enable(DDCUTIL + "ddcutil" + "Ddcutil" ) if(ENABLE_THREADS) @@ -714,11 +783,15 @@ if(ENABLE_THREADS) endif() endif() -if(ENABLE_BUFFER) - target_compile_definitions(libfastfetch PRIVATE FF_ENABLE_BUFFER) +if(ENABLE_PCI_MEMORY) + target_compile_definitions(libfastfetch PRIVATE FF_USE_PCI_MEMORY) endif() -if(APPLE) +if(LINUX) + target_link_libraries(libfastfetch + PRIVATE "m" + ) +elseif(APPLE) target_link_libraries(libfastfetch PRIVATE "-framework Cocoa" PRIVATE "-framework CoreFoundation" @@ -750,6 +823,11 @@ elseif(WIN32) PRIVATE "setupapi" PRIVATE "hid" PRIVATE "wtsapi32" + PRIVATE "dxva2" + ) +elseif(BSD) + target_link_libraries(libfastfetch + PRIVATE "usbhid" ) endif() @@ -760,6 +838,7 @@ target_include_directories(libfastfetch target_link_libraries(libfastfetch PRIVATE ${CMAKE_DL_LIBS} + PRIVATE yyjson ) ###################### @@ -774,6 +853,7 @@ target_compile_definitions(fastfetch ) target_link_libraries(fastfetch PRIVATE libfastfetch + PRIVATE yyjson ) add_executable(flashfetch @@ -784,13 +864,9 @@ target_compile_definitions(flashfetch ) target_link_libraries(flashfetch PRIVATE libfastfetch + PRIVATE yyjson ) -if(ENABLE_BUFFER) # FF_ENABLE_BUFFER is used in fastfetch.c - target_compile_definitions(fastfetch PRIVATE FF_ENABLE_BUFFER) - target_compile_definitions(flashfetch PRIVATE FF_ENABLE_BUFFER) -endif() - if(WIN32) set(TARGET_NAME fastfetch) target_sources(fastfetch @@ -838,12 +914,6 @@ install( DESTINATION "${CMAKE_INSTALL_BINDIR}" ) -install( - FILES "${CMAKE_SOURCE_DIR}/src/data/config_system.txt" - DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/${CMAKE_PROJECT_NAME}" - RENAME "config.conf" -) - install( FILES "${CMAKE_SOURCE_DIR}/completions/bash" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/bash-completion/completions" diff --git a/README.md b/README.md index a8593d1384..71d29bfaf2 100644 --- a/README.md +++ b/README.md @@ -16,20 +16,24 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/ ## Customization -With customization and speed being two competing goals, this project actually builds two executables. +With customization and speed being two competing goals, this project actually builds two executables: -* The main one being `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent in `$XDG_CONFIG_HOME/fastfetch/config.conf`. To view the available options run `fastfetch --help`. -* The second executable being built is called `flashfetch`, which is configured at compile time to eliminate any possible overhead. Configuration of it can be very easily done in [`src/flashfetch.c`](src/flashfetch.c). +* The main one is `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent by modifying `$XDG_CONFIG_HOME/fastfetch/config.conf`. Use `fastfetch --gen-config conf` to generate one. To view the available options, run `fastfetch --help`. +* The second executable is called `flashfetch`, which is configured at compile time to eliminate any possible overhead. Configuration of it can be very easily done in [`src/flashfetch.c`](src/flashfetch.c). -At the moment the performance difference is measurable, but too small to be human recognizable. But the leap will get bigger with more and more options coming, and on slow machines this might actually make a difference. +Currently, the performance difference is measurable, but too small to be recognizable by humans. But with more options planned, the leap will get bigger over time and on slow machines this might actually make a difference. There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `--load-config `. They may also serve as a good example for format arguments. -Logos can be heavily customized to. See the [logo documentation](doc/logo.md) for more information. +Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information. + +### Customization with new JSONC format + +A new, structure based, and user-friendly config file format was introduced in v2.0.0. This format is based on [JSONC](https://jsonc.org/). [See more details in Wiki](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration) ## Dependencies -Fastfetch dynamically loads needed libraries if they are available. On Linux, its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) (if built with multithreading support). They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions. +Fastfetch dynamically loads needed libraries if they are available. On Linux, its only hard dependencies are `libc` (any implementation of the c standard library), `libdl`, `libm` and [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) (if built with multithreading support). They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most Linux distributions. The following libraries are used if present at runtime: @@ -55,9 +59,9 @@ The following libraries are used if present at runtime: * [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font. * [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count. * [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE. -* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( WSL ). * [`libnm`](https://networkmanager.dev/docs/libnm/latest/): Used for Wifi detection. * [`libpulse`](https://freedesktop.org/software/pulseaudio/doxygen/): Used for Sound detection. +* [`libddcutil`](https://github.com/rockowitz/ddcutil): Used for brightness detection of external displays ### macOS @@ -73,13 +77,12 @@ For the image logo, iTerm with iterm image protocol should work. Apple Terminal ### Windows * [`wlanapi`](https://learn.microsoft.com/en-us/windows/win32/api/wlanapi/): A system dll which isn't supported by Windows Server by default. Used for Wifi info detection. -* [`libcJSON`](https://github.com/DaveGamble/cJSON): Used for Windows Terminal font detection. [`cjson`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-cjson) * [`libvulkan`](https://www.vulkan.org/): Vulkan module. Usually has been provided by GPU drivers. [`vulkan-loader`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-loader) [`vulkan-headers`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-headers) * [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module. [`opencl-icd`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-opencl-icd) Note: In Windows 7, 8 and 8.1, [ConEmu](https://conemu.github.io/en/AnsiEscapeCodes.html) is required to run fastfetch due to [the lack of ASCII escape code native support](https://en.wikipedia.org/wiki/ANSI_escape_code#DOS,_OS/2,_and_Windows). In addition, as fastfetch for Windows targets [UCRT](https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment) C runtime library, [it must be installed manually](https://support.microsoft.com/en-us/topic/update-for-universal-c-runtime-in-windows-c0514201-7fe6-95a3-b0a5-287930f3560c) as UCRT is only pre-installed in Windows 10 and later. -For the image logo, only chafa is supported due to [the design flaw of ConPTY](https://github.com/microsoft/terminal/issues/1173). In addition, chafa support is not built by default due to the massive dependencies of imagemagick. You must built it yourself. +For the image logo, only chafa is supported due to [a design flaw of ConPTY](https://github.com/microsoft/terminal/issues/1173). In addition, chafa support is not included by default due to the massive dependencies of imagemagick. You must built it yourself. ### Android @@ -92,17 +95,21 @@ All categories not listed here should work without needing a specific implementa ##### Available Modules ``` -Battery, Bios, Bluetooth, Board, Break, Brightness, Colors, Command, CPU, CPUUsage, Cursor, Custom, Date, DateTime, DE, Disk, Display, Font, Gamepad, GPU, Host, Icons, Kernel, Locale, LocalIP, Media, Memory, OpenCL, OpenGL, Packages, Player, Power Adapter, Processes, PublicIP, Separator, OS, Shell, Sound, Swap, Terminal, Terminal Font, Theme, Time, Title, Uptime, Vulkan, Wallpaper, Wifi, WM, WMTheme +Battery, Bios, Bluetooth, Board, Break, Brightness, Colors, Command, CPU, CPUUsage, Cursor, Custom, Date, DateTime, DE, Disk, Display, Font, Gamepad, GPU, Host, Icons, Kernel, LM, Locale, LocalIP, Media, Memory, Monitor, OpenCL, OpenGL, Packages, Player, Power Adapter, Processes, PublicIP, Separator, OS, Shell, Sound, Swap, Terminal, Terminal Font, Terminal Size, Theme, Time, Title, Uptime, Vulkan, Wallpaper, Wifi, WM, WMTheme ``` ##### Builtin logos + + ``` -AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, CRUX, Crystal, Debian, Deepin, Devuan, Endeavour, Enso, Fedora, FreeBSD, Garuda, Gentoo, GhostBSD, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE LEAP, OpenSUSE Tumbleweed, Parabola, Pop!_OS, Raspbian, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Solus, SteamOS, Ubuntu, Vanilla, Void, Windows, Windows 11, Windows 8, Zorin +AIX, AlmaLinux, Alpine, Alpine2Small, AlpineSmall, Alter, Amazon, AmogOS, Anarchy, Android, AndroidSmall, Antergos, Antix, AoscOS, AoscOsRetro, AoscOsRetro_small, Aperture, Apple, AppleSmall, Apricity, Arch, Arch2, ArchBox, Archcraft, Archcraft2, Archlabs, ArchSmall, ArchStrike, ArcoLinux, ArcoLinuxSmall, ArseLinux, Artix, Artix2Small, ArtixSmall, Arya, Asahi, Aster, AsteroidOS, AstOS, Astra, Ataraxia, Athena, Bedrock, BigLinux, Bitrig, BlackArch, BlackPanther, BLAG, BlankOn, BlueLight, Bodhi, Bonsai, BSD, BunsenLabs, CachyOS, CachyOSSmall, Calculate, CalinixOS, CalinixOSSmall, Carbs, CBL-Mariner, CelOS, Center, CentOS, CentOSSmall, Chakra, ChaletOS, Chapeau, ChonkySealOS, Chrom, Cleanjaro, CleanjaroSmall, ClearLinux, ClearOS, Clover, Cobalt, Condres, ContainerLinux, CRUX, CRUXSmall, CrystalLinux, Cucumber, CutefishOS, CuteOS, CyberOS, Dahlia, DarkOS, Debian, DebianSmall, Deepin, DesaOS, Devuan, DevuanSmall, DietPi, DracOS, DragonFly, DragonFlyOld, DragonFlySmall, Drauger, Droidian, Elementary, ElementarySmall, Elive, EncryptOS, Endeavour, Endless, Enso, EuroLinux, EvolutionOS, Exherbo, ExodiaPredator, Fedora, FedoraOld, FedoraSmall, FemboyOS, Feren, Finnix, Floflis, FreeBSD, FreeBSDSmall, FreeMiNT, Frugalware, Funtoo, GalliumOS, Garuda, GarudaDragon, GarudaSmall, Gentoo, GentooSmall, GhostBSD, Glaucus, GNewSense, Gnome, GNU, GoboLinux, GrapheneOS, Grombyang, Guix, GuixSmall, Haiku, HaikuSmall, HamoniKR, HarDClanZ, HardenedBSD, Hash, Huayra, Hybrid, HydroOS, Hyperbola, HyperbolaSmall, Iglunix, InstantOS, IRIX, Itc, Januslinux, Kaisen, Kali, KaliSmall, KaOS, KDENeon, Kibojoe, KISSLinux, Kogaion, Korora, KrassOS, KSLinux, Kubuntu, LangitKetujuh, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, Laxeros, LEDE, LibreELEC, Linspire, Linux, LinuxLight, LinuxLightSmall, LinuxMint, LinuxMintOld, LinuxMintSmall, LinuxSmall, Live_Raizo, LMDE, Lunar, MacOS, MacOS2, MacOS2Small, MacOSSmall, Mageia, MageiaSmall, MagpieOS, Mandriva, Manjaro, ManjaroSmall, MassOS, MatuusOS, MaUI, Meowix, Mer, Minix, Mint, MintOld, MintSmall, MiracleLinux, Msys2, MX, MXSmall, Namib, Nekos, Neptune, NetBSD, NetRunner, Nitrux, NixOS, NixOS_small, NixOsOld, NixOsSmall, Nobara, NomadBSD, Nurunner, NuTyX, Obarun, OBRevenge, OmniOS, OpenBSD, OpenBSDSmall, OpenEuler, OpenIndiana, OpenKylin, OpenMamba, OpenMandriva, OpenStage, OpenSuse, OpenSuseLeap, OpenSuseSmall, OpenSuseTumbleweed, OpenWrt, OPNsense, Oracle, Orchid, OrchidSmall, OS_Elbrus, OSMC, OSX, OSXSmall, PacBSD, Panwah, Parabola, ParabolaSmall, Parch, Pardus, Parrot, Parsix, PCBSD, PCLinuxOS, PearOS, Pengwin, Pentoo, Peppermint, PhyOS, Pisi, PNMLinux, Pop, PopSmall, Porteus, PostMarketOS, PostMarketOSSmall, Proxmox, PuffOS, Puppy, PureOS, PureOSSmall, Q4OS, Qubes, Qubyt, Quibian, Radix, Raspbian, RaspbianSmall, RavynOS, Reborn, RebornSmall, RedCore, RedHatEnterpriseLinux, RedHatEnterpriseLinux_old, RedstarOS, Refracted Devuan, Regata, Regolith, RhaymOS, RockyLinux, RockyLinuxSmall, RosaLinux, Sabayon, Sabotage, Sailfish, SalentOS, SalientOS, Salix, SambaBOX, Sasanqua, Scientific, Semc, Septor, Serene, SharkLinux, ShastraOS, Siduction, SkiffOS, Slackel, Slackware, SlackwareSmall, Slitaz, SmartOS, Soda, Solaris, SolarisSmall, Solus, SourceMage, Sparky, Star, SteamOS, StockLinux, Sulin, Suse, SuseSmall, Swagarch, T2, Tails, TeArch, TorizonCore, Trisquel, Twister, Ubuntu, Ubuntu2Old, Ubuntu2Small, UbuntuBudgie, UbuntuCinnamon, UbuntuGnome, UbuntuKde, UbuntuKylin, UbuntuMate, UbuntuOld, UbuntuSmall, UbuntuStudio, UbuntuSway, UbuntuTouch, UbuntuUnity, Ultramarine, Univalent, Univention, UOS, UrukOS, Uwuntu, Vanilla, Venom, Vnux, Void, VoidSmall, Vzlinux, WiiLinuxNgx, Windows, Windows11, Windows11Small, Windows8, Windows95, Xferience, YiffOS, Zorin ``` +Run `fastfetch --print-logos` to print them + ##### Package managers ``` -apk, brew, Chocolatey, dpkg, emerge, eopkg, Flatpak, MacPorts, nix, Pacman, pkg, pkgtool, rpm, scoop, Snap, xbps +apk, brew, Chocolatey, dpkg, emerge, eopkg, Flatpak, MacPorts, nix, Pacman, paludis, pkg, pkgtool, rpm, scoop, Snap, xbps ``` ##### WM themes @@ -117,7 +124,7 @@ Budgie, Cinnamon, Gnome, KDE Plasma, LXQt, Mate, XFCE4 ##### Terminal fonts ``` -Alacritty, Apple Terminal, ConEmu, Deepin Terminal, foot, Gnome Terminal, iTerm2, Kitty, Konsole, LXTerminal, MATE Terminal, mintty, QTerminal, Tabby, Terminator, Termux, Tilix, TTY, Warp, WezTerm, Windows Terminal, XFCE4 Terminal +Alacritty, Apple Terminal, ConEmu, Deepin Terminal, foot, Gnome Terminal, iTerm2, Kitty, Konsole, LXTerminal, MATE Terminal, mintty, QTerminal, Tabby, Terminator, Termux, Tilix, TTY, Warp, WezTerm, Windows Terminal, XFCE4 Terminal, Yakuake ``` ## Building @@ -140,7 +147,7 @@ Currently GCC or clang is required (MSVC is not supported). MSYS2 with CLANG64 s 1. Open `MSYS2 / CLANG64` (not `MSYS2 / MSYS`, which targets cygwin C runtime) 1. Install dependencies ```bash -pacman -Syu mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-pkgconf 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 +pacman -Syu mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-pkgconf mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd ``` Follow the building instructions of Linux next. diff --git a/completions/bash b/completions/bash index 5752ffdb5e..a8db1c6000 100644 --- a/completions/bash +++ b/completions/bash @@ -16,13 +16,13 @@ __fastfetch_complete_help() "display-format" "de-format" "wm-format" - "wm-theme-format" + "wmtheme-format" "theme-format" "icons-format" "font-format" "cursor-format" "terminal-format" - "terminal-font-format" + "terminalfont-format" "cpu-format" "cpu-usage-format" "gpu-format" @@ -113,7 +113,7 @@ __fastfetch_complete_option() "${FF_OPTIONS_LOGO[@]}" "${FF_OPTIONS_LOGO_TYPE[@]}" "${FF_OPTIONS_BINARY_PREFIX[@]}" - "${FF_OPTIONS_GL[@]}" + "${FF_OPTIONS_OPENGL[@]}" ) if [[ $WORD_COUND -lt 3 ]]; then @@ -193,10 +193,8 @@ __fastfetch_completion() "--pipe" "--title-fqdn" "--escape-bedrock" - "--shell-version" - "--terminal-version" "--disk-folders" - "--disk-show-removable" + "--disk-show-external" "--disk-show-hidden" "--disk-show-subvolumes" "--gpu-hide-integrated" @@ -241,124 +239,124 @@ __fastfetch_completion() "--weather-timeout" "--os-key" "--os-format" - "--os-error" + "--os-key-color" "--host-key" "--host-format" - "--host-error" + "--host-key-color" "--kernel-key" "--kernel-format" - "--kernel-error" + "--kernel-key-color" "--uptime-key" "--uptime-format" - "--uptime-error" + "--uptime-key-color" "--processes-key" "--processes-format" - "--processes-error" + "--processes-key-color" "--packages-key" "--packages-format" - "--packages-error" + "--packages-key-color" "--shell-key" "--shell-format" - "--shell-error" + "--shell-key-color" "--display-key" "--display-format" - "--display-error" + "--display-key-color" "--de-key" "--de-format" - "--de-error" + "--de-key-color" "--wm-key" "--wm-format" - "--wm-error" - "--wm-theme-key" - "--wm-theme-format" - "--wm-theme-error" + "--wm-key-color" + "--wmtheme-key" + "--wmtheme-format" + "--wmtheme-key-color" "--theme-key" "--theme-format" - "--theme-error" + "--theme-key-color" "--icons-key" "--icons-format" - "--icons-error" + "--icons-key-color" "--font-key" "--font-format" - "--font-error" + "--font-key-color" "--cursor-key" "--cursor-format" - "--cursor-error" + "--cursor-key-color" "--terminal-key" "--terminal-format" - "--terminal-error" - "--terminal-font-key" - "--terminal-font-format" - "--terminal-font-error" + "--terminal-key-color" + "--terminalfont-key" + "--terminalfont-format" + "--terminalfont-key-color" "--cpu-key" "--cpu-format" - "--cpu-error" + "--cpu-key-color" "--cpu-useage-key" "--cpu-useage-format" - "--cpu-useage-error" + "--cpu-useage-key-color" "--gpu-key" "--gpu-format" - "--gpu-error" + "--gpu-key-color" "--memory-key" "--memory-format" - "--memory-error" + "--memory-key-color" "--swap-key" "--swap-format" - "--swap-error" + "--swap-key-color" "--disk-key" "--disk-format" - "--disk-error" + "--disk-key-color" "--battery-key" "--battery-format" - "--battery-error" + "--battery-key-color" "--poweradapter-key" "--poweradapter-format" - "--poweradapter-error" + "--poweradapter-key-color" "--locale-key" "--locale-format" - "--locale-error" + "--locale-key-color" "--localip-key" "--localip-format" - "--localip-error" + "--localip-key-color" "--publicip-key" "--publicip-format" - "--publicip-error" + "--publicip-key-color" "--wifi-key" "--wifi-format" - "--wifi-error" + "--wifi-key-color" "--weather-key" "--weather-format" - "--weather-error" + "--weather-key-color" "--player-key" "--player-format" - "--player-error" + "--player-key-color" "--media-key" "--media-format" - "--media-error" + "--media-key-color" "--datetime-key" "--datetime-format" - "--datetime-error" + "--datetime-key-color" "--date-key" "--date-format" - "--date-error" + "--date-key-color" "--time-key" "--time-format" - "--time-error" + "--time-key-color" "--vulkan-key" "--vulkan-format" - "--vulkan-error" + "--vulkan-key-color" "--opengl-key" "--opengl-format" - "--opengl-error" + "--opengl-key-color" "--opencl-key" "--opencl-format" - "--opencl-error" + "--opencl-key-color" "--users-key" "--users-format" - "--users-error" + "--users-key-color" "--bluetooth-key" "--bluetooth-format" - "--bluetooth-error" + "--bluetooth-key-color" ) local FF_OPTIONS_PATH=( @@ -385,6 +383,8 @@ __fastfetch_completion() "--lib-osmesa" "--lib-opencl" "--lib-pulse" + "--lib-ddcutil" + "--lib-nm" "--battery-dir" ) @@ -401,8 +401,8 @@ __fastfetch_completion() "--binary-prefix" ) - local FF_OPTIONS_GL=( - "--gl" + local FF_OPTIONS_OPENGL=( + "--opengl-type" ) if __fastfetch_previous_matches "${FF_OPTIONS_SINGLE[@]}"; then @@ -425,7 +425,7 @@ __fastfetch_completion() __fastfetch_complete_logo_type elif __fastfetch_previous_matches "${FF_OPTIONS_BINARY_PREFIX[@]}"; then __fastfetch_complete_binary_prefix - elif __fastfetch_previous_matches "${FF_OPTIONS_GL[@]}"; then + elif __fastfetch_previous_matches "${FF_OPTIONS_OPENGL[@]}"; then __fastfetch_complete_gl else __fastfetch_complete_option diff --git a/doc/json_schema.json b/doc/json_schema.json new file mode 100644 index 0000000000..279aac96c7 --- /dev/null +++ b/doc/json_schema.json @@ -0,0 +1,1093 @@ +{ + "$schema": "http://json-schema.org/schema", + "$defs": { + "colors": { + "type": "string", + "enum": [ + "reset_", "bright_", "dim_", + "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "default", + "bright_black", "bright_red", "bright_green", "bright_yellow", "bright_blue", "bright_magenta", "bright_cyan", "bright_white" + ] + }, + "key": { + "title": "Key of the module", + "type": "string" + }, + "keyColor": { + "title": "Color of the module key. Left empty to use `display.color.keys`", + "$ref": "#/$defs/colors" + }, + "format": { + "title": "Output format of the module", + "type": "string" + } + }, + "type": "object", + "title": "JSON config", + "description": "JSON config file for fastfetch. Usually be `~/.config/fastfetch.jsonc`", + "properties": { + "$schema": { + "type": "string", + "title": "JSON schema URL, for JSON validation and IDE intelligence", + "format": "uri", + "default": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json" + }, + "logo": { + "oneOf": [ + { + "title": "Disable logo", + "type": "null" + }, + { + "title": "Set the source file of the logo", + "type": "string" + }, + { + "title": "Fastfetch logo configurations", + "type": "object", + "properties": { + "type": { + "title": "Set the type of the logo given", + "enum": [ + "auto", + "builtin", + "small", + "file", + "file-raw", + "data", + "data-raw", + "sixel", + "kitty", + "kitty-direct", + "iterm", + "chafa", + "raw", + "none" + ], + "default": "auto" + }, + "source": { + "type": "string", + "title": "Set the source file of the logo" + }, + "color": { + "type": "object", + "title": "Overwrite a color in the logo", + "properties": { + "1": { + "title": "Color 1", + "$ref": "#/$defs/colors" + }, + "2": { + "title": "Color 2", + "$ref": "#/$defs/colors" + }, + "3": { + "title": "Color 3", + "$ref": "#/$defs/colors" + }, + "4": { + "title": "Color 4", + "$ref": "#/$defs/colors" + }, + "5": { + "title": "Color 5", + "$ref": "#/$defs/colors" + }, + "6": { + "title": "Color 6", + "$ref": "#/$defs/colors" + }, + "7": { + "title": "Color 7", + "$ref": "#/$defs/colors" + }, + "8": { + "title": "Color 8", + "$ref": "#/$defs/colors" + }, + "9": { + "title": "Color 9", + "$ref": "#/$defs/colors" + } + }, + "additionalProperties": false + }, + "width": { + "type": "integer", + "title": "Set the width of the logo (in characters). Required for iTerm image protocol", + "minimum": 1 + }, + "height": { + "type": "integer", + "title": "Set the height of the logo (in characters). Required for iTerm image protocol", + "minimum": 1 + }, + "padding": { + "type": "object", + "title": "Set the padding of the logo", + "properties": { + "top": { + "type": "integer", + "title": "Set the top padding of the logo", + "minimum": 0 + }, + "left": { + "type": "integer", + "title": "Set the left padding of the logo", + "minimum": 0 + }, + "right": { + "type": "integer", + "title": "Set the right padding of the logo", + "minimum": 0 + } + }, + "additionalProperties": false + }, + "printRemaining": { + "type": "boolean", + "title": "Whether to print the remaining logo, if it has more lines than modules to display", + "default": false + }, + "preserveAspectRadio": { + "type": "boolean", + "title": "Whether to preserve the aspect ratio of the logo. Supported by iTerm image protocol", + "default": false + }, + "chafa": { + "type": "object", + "title": "Chafa configuration. See chafa document for details", + "properties": { + "fgOnly": { + "type": "boolean", + "title": "Produce character-cell output using foreground colors only", + "default": false + }, + "symbols": { + "type": "string", + "title": "Specify character symbols to employ in final output" + }, + "canvasMode": { + "type": "string", + "title": "Determine how colors are used in the output. This value maps the value of enum ChafaCanvasMode.", + "enum": [ + "TRUECOLOR", + "INDEXED_256", + "INDEXED_240", + "INDEXED_16", + "FGBG_BGFG", + "FGBG", + "INDEXED_8", + "INDEXED_16_8" + ] + }, + "colorSpace": { + "type": "string", + "title": "Set color space used for quantization. This value maps the value of enum ChafaColorSpace.", + "enum": [ + "RGB", + "DIN99D" + ] + }, + "ditherMode": { + "type": "string", + "title": "Set output dither mode (No effect with 24-bit color). This value maps the value of enum ChafaDitherMode.", + "enum": [ + "NONE", + "ORDERED", + "DIFFUSION" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "general": { + "title": "Fastfetch general configurations", + "type": "object", + "properties": { + "allowSlowOperations": { + "type": "boolean", + "title": "Allow operations that can be very slow for more detailed output", + "default": false + }, + "multithreading": { + "type": "boolean", + "title": "Use multiple threads to detect values", + "default": true + }, + "stat": { + "type": "boolean", + "title": "Show time usage (in ms) for individual modules", + "default": false + }, + "escapeBedrock": { + "type": "boolean", + "title": "On Bedrock Linux, whether to escape the bedrock jail", + "default": true + }, + "pipe": { + "type": "boolean", + "title": "Whether to enable pipe mode (disable logo and all escape sequences)", + "default": false + }, + "playerName": { + "type": "string", + "title": "The name of the player to use for module Media and Player. Linux only" + }, + "osFile": { + "type": "string", + "title": "Set the path to the file containing OS information. Linux only" + }, + "dsForceDrm": { + "type": "boolean", + "title": "Force display detection to use `/sys/class/drm`. Linux only", + "default": false + }, + "wmiTimeout": { + "type": "integer", + "title": "Set the timeout (ms) for WMI queries, `-1` for no timeout. Windows only", + "default": 5000 + } + }, + "additionalProperties": false + }, + "display": { + "title": "Configure how things to be displayed", + "type": "object", + "properties": { + "showErrors": { + "type": "boolean", + "title": "Print occurring errors to the console. False to ignore errored modules", + "default": false + }, + "disableLinewrap": { + "type": "boolean", + "title": "Whether to disable line wrap during the run", + "default": true + }, + "hideCursor": { + "type": "boolean", + "title": "Whether to hide the cursor during the run", + "default": true + }, + "separator": { + "type": "string", + "title": "Set the separator between key and value", + "default": ": " + }, + "color": { + "title": "Set the color of the keys and title", + "oneOf": [ + { + "title": "Set the both color of the keys and title", + "$ref": "#/$defs/colors" + }, + { + "type": "object", + "properties": { + "keys": { + "title": "Set the color of the keys", + "$ref": "#/$defs/colors" + }, + "title": { + "title": "Set the color of the title", + "$ref": "#/$defs/colors" + } + }, + "additionalProperties": false + } + ] + }, + "brightColor": { + "title": "Set if the keys, title and ASCII logo should be printed in bright color", + "type": "boolean", + "default": true + }, + "binaryPrefix": { + "type": "string", + "title": "Set the binary prefix to used when printing bytes", + "enum": [ + "iec", + "si", + "jedec" + ] + }, + "sizeNdigits": { + "type": "integer", + "title": "Set the number of digits to keep after the decimal point when formatting sizes", + "default": 2 + }, + "sizeMaxPrefix": { + "type": "string", + "title": "Set the largest binary prefix to use when formatting sizes", + "enum": ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], + "default": "YB" + }, + "temperatureUnit": { + "type": "string", + "title": "Set the unit of the temperature", + "enum": ["CELSIUS", "C", "FAHRENHEIT", "F", "KELVIN", "K"], + "default": "C" + }, + "percentType": { + "type": "number", + "title": "Set the percentage output type. 1 for percentage number, 2 for bar, 3 for both, 6 for bar only, 9 for colored number", + "minimum": 0, + "maximum": 9, + "default": 1 + }, + "noBuffer": { + "type": "boolean", + "title": "Whether to disable the stdout application buffer", + "default": false + } + }, + "additionalProperties": false + }, + "library": { + "title": "Set the path of a library to load", + "type": "object", + "properties": { + "pci": { + "type": "string", + "title": "GPU output (Linux and FreeBSD)" + }, + "vulkan": { + "type": "string", + "title": "Vulkan module & fallback for GPU output" + }, + "freetype": { + "type": "string", + "title": "Used for Termux font detection (Android)" + }, + "wayland": { + "type": "string", + "title": "Better display performance and output in wayland sessions.\nSupports different refresh rates per monitor.\n(Linux)" + }, + "xcbRandr": { + "type": "string", + "title": "" + }, + "xcb": { + "type": "string", + "title": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)" + }, + "xrandr": { + "type": "string", + "title": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)" + }, + "x11": { + "type": "string", + "title": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)" + }, + "gio": { + "type": "string", + "title": "Needed for values that are only stored GSettings (Linux, FreeBSD)" + }, + "dconf": { + "type": "string", + "title": "Needed for values that are only stored in DConf + Fallback for GSettings (Linux, FreeBSD)" + }, + "dbus": { + "type": "string", + "title": "Bluetooth, Player & Media detection (Linux, FreeBSD)" + }, + "xfconf": { + "type": "string", + "title": "Needed for XFWM theme and XFCE Terminal font (Linux, FreeBSD)" + }, + "sqlite3": { + "type": "string", + "title": "Needed for pkg & rpm package count (Linux, FreeBSD)" + }, + "rpm": { + "type": "string", + "title": "Slower fallback for rpm package count. Needed on openSUSE & old CentOS / Redhat. (Linux)" + }, + "imagemagick": { + "type": "string", + "title": "Images in terminal using sixel or kitty graphics protocol (Linux, FreeBSD, macOS)" + }, + "z": { + "title": "Libz. Faster image output when using kitty graphics protocol (Linux, FreeBSD, macOS)", + "type": "string" + }, + "chafa": { + "type": "string", + "title": "Image output as ascii art (Linux, FreeBSD, macOS)" + }, + "egl": { + "type": "string", + "title": "Needed by the OpenGL module for gl context creation (Linux, FreeBSD)" + }, + "glx": { + "type": "string", + "title": "Needed by the OpenGL module for gl context creation (Linux, FreeBSD)" + }, + "osmesa": { + "type": "string", + "title": "Needed by the OpenGL module for gl context creation (Linux, FreeBSD)" + }, + "opencl": { + "type": "string", + "title": "OpenCL module (Linux, FreeBSD, Windows)" + }, + "pulse": { + "title": "Pulseaudio. Used for Sound detection (Linux, FreeBSD)", + "type": "string" + }, + "nm": { + "title": "NetworkManager. Used for Wifi detection (Linux)", + "type": "string" + }, + "ddcutil": { + "title": "Used for brightness detection of external displays (Linux)", + "type": "string" + } + }, + "additionalProperties": false + }, + "modules": { + "title": "Fastfetch modules to run", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string", + "title": "Run module with default configurations", + "enum": [ + "battery", + "bios", + "bluetooth", + "board", + "break", + "brightness", + "chassis", + "cpu", + "cpuusage", + "command", + "colors", + "cursor", + "datetime", + "display", + "disk", + "de", + "font", + "gamepad", + "gpu", + "host", + "icons", + "kernel", + "lm", + "locale", + "localip", + "media", + "memory", + "monitor", + "opencl", + "opengl", + "os", + "packages", + "player", + "poweradapter", + "processes", + "publicip", + "separator", + "shell", + "sound", + "swap", + "terminal", + "terminalfont", + "terminalsize", + "title", + "theme", + "uptime", + "users", + "vulkan", + "wallpaper", + "weather", + "wm", + "wifi", + "wmtheme" + ] + }, + { + "type": "object", + "title": "Run module with custom configurations", + "required": [ + "type" + ], + "properties": { + "type": { + "title": "Module type", + "type": "string" + } + }, + "oneOf": [ + { + "title": "Break", + "description": "Print a empty line", + "properties": { + "type": { + "const": "break" + } + }, + "additionalProperties": false + }, + { + "title": "No additional properties", + "properties": { + "type": { + "enum": [ + "bios", + "board", + "brightness", + "chassis", + "cpuusage", + "cursor", + "datetime", + "de", + "font", + "gamepad", + "host", + "icons", + "kernel", + "lm", + "locale", + "media", + "memory", + "monitor", + "opencl", + "os", + "packages", + "player", + "poweradapter", + "processes", + "shell", + "swap", + "terminal", + "terminalfont", + "terminalsize", + "theme", + "uptime", + "users", + "vulkan", + "wallpaper", + "wm", + "wifi", + "wmtheme" + ] + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "Battery", + "properties": { + "type": { + "const": "battery" + }, + "dir": { + "title": "The directory where the battery folders are. Standard: `/sys/class/power_supply/`. Linux only", + "type": "string" + }, + "temp": { + "title": "Detect and display Battery temperature if supported", + "type": "boolean", + "default": false + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "Bluetooth", + "properties": { + "type": { + "const": "bluetooth" + }, + "showDisconnected": { + "title": "Set if disconnected bluetooth devices should be printed", + "type": "boolean", + "default": false + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "CPU", + "properties": { + "type": { + "const": "cpu" + }, + "temp": { + "title": "Detect and display CPU temperature if supported", + "type": "boolean", + "default": false + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "Colors", + "properties": { + "type": { + "const": "colors" + }, + "symbol": { + "title": "Set the symbol to use", + "type": "string", + "enum": [ + "block", + "circle", + "diamond", + "triangle", + "square", + "star" + ], + "default": "block" + }, + "paddingLeft": { + "title": "Set the number of white spaces to print before the symbol", + "type": "integer", + "minimum": 0, + "default": 0 + } + } + }, + { + "title": "Command", + "properties": { + "type": { + "const": "command" + }, + "shell": { + "title": "Set the shell program to execute the command text\nDefault: cmd for Windows, /bin/sh for *nix", + "type": "string" + }, + "text": { + "title": "Set the command text to be executed", + "type": "string" + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "Custom", + "description": "Print a custom string, with or without key", + "properties": { + "type": { + "const": "custom" + }, + "key": { + "title": "Leave empty not to print the key", + "type": "string" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "title": "Text to print", + "type": "string" + } + }, + "required": [ + "format" + ], + "additionalProperties": false + }, + { + "title": "Display", + "properties": { + "type": { + "const": "display" + }, + "compactType": { + "enum": [ + "none", + "original", + "scaled" + ], + "title": "Set if all displays should be printed in one line", + "default": "none" + }, + "preciseRefreshRate": { + "title": "Set if decimal refresh rates should not be rounded into integers when printing", + "type": "boolean", + "default": true + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "Disk", + "properties": { + "type": { + "const": "disk" + }, + "folders": { + "type": "string", + "title": "A colon (semicolon on Windows) separated list of folder paths for the disk output\nDefault: \"/:/home\" (\"C:\\\\;D:\\\\ ...\" on Windows)" + }, + "showExternal": { + "type": "boolean", + "title": "Set if external volume should be printed", + "default": true + }, + "showHidden": { + "type": "boolean", + "title": "Set if hidden volumes should be printed", + "default": false + }, + "showSubvolumes": { + "type": "boolean", + "title": "Set if subvolumes should be printed", + "default": false + }, + "showUnknown": { + "type": "boolean", + "title": "Set if unknown (unable to detect sizes) volumes should be printed", + "default": false + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "GPU", + "properties": { + "type": { + "const": "gpu" + }, + "temp": { + "title": "Detect and display GPU temperature if supported", + "type": "boolean", + "default": false + }, + "forceVulkan": { + "title": "Force using vulkan to detect GPUs, which support video memory usage detection with `--allow-slow-operations`", + "type": "boolean", + "default": false + }, + "hideType": { + "title": "Specify the type of GPUs should not be printed", + "enum": [ + "integrated", + "discrete", + "none" + ], + "default": "none" + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "Local IP", + "properties": { + "type": { + "const": "localip" + }, + "showIpv4": { + "title": "Show IPv4 addresses", + "type": "boolean", + "default": true + }, + "showIpv6": { + "title": "Show IPv6 addresses", + "type": "boolean", + "default": false + }, + "showMac": { + "title": "Show MAC addresses", + "type": "boolean", + "default": false + }, + "showLoop": { + "title": "Show loop back addresses (127.0.0.1)", + "type": "boolean", + "default": false + }, + "compact": { + "title": "Show all IPs in one line", + "type": "boolean", + "default": false + }, + "namePrefix": { + "title": "Show IPs with given name prefix only", + "type": "string" + }, + "showDefaultRouteOnly": { + "title": "Show ips that are used for default routing only", + "type": "boolean", + "default": false + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "OpenGL", + "properties": { + "type": { + "const": "opengl" + }, + "library": { + "title": "Set the OpenGL context creation library to use. Linux only", + "enum": [ + "auto", + "egl", + "glx", + "osmesa" + ], + "default": "auto" + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "Public IP", + "properties": { + "type": { + "const": "publicip" + }, + "url": { + "title": "The URL of public IP detection server to be used. Only HTTP protocol is supported", + "type": "string", + "format": "url", + "default": "http://ipinfo.io/ip" + }, + "timeout": { + "title": "Time in milliseconds to wait for the public ip server to respond", + "type": "integer", + "minimum": 0, + "default": "disabled (0)" + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "Separator", + "properties": { + "type": { + "const": "separator" + }, + "string": { + "title": "Set the string to be printed", + "type": "string", + "default": "-" + } + }, + "additionalProperties": false + }, + { + "title": "Sound", + "properties": { + "type": { + "const": "sound" + }, + "soundType": { + "title": "Set what type of sound devices should be printed", + "type": "string", + "enum": [ + "main", + "active", + "all" + ], + "default": "main" + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "Title", + "properties": { + "type": { + "const": "title" + }, + "fqdn": { + "type": "boolean", + "title": "Set if the title should use fully qualified domain name", + "default": false + }, + "color": { + "title": "Set colors of the different part of title", + "properties": { + "user": { + "title": "Set color of the user name (left part)", + "$ref": "#/$defs/colors" + }, + "at": { + "title": "Set color of the @ symbol (middle part)", + "$ref": "#/$defs/colors" + }, + "host": { + "title": "Set color of the host name (right part)", + "$ref": "#/$defs/colors" + } + }, + "additionalProperties": false + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + }, + { + "title": "Weather", + "properties": { + "type": { + "const": "weather" + }, + "location": { + "title": "The location to display", + "type": "string" + }, + "timeout": { + "title": "Time in milliseconds to wait for the weather server to respond", + "type": "integer", + "minimum": 0, + "default": "disabled (0)" + }, + "outputFormat": { + "title": "The output weather format to be used (must be URI encoded)", + "type": "string", + "default": "%t+-+%C+(%l)" + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "format": { + "$ref": "#/$defs/format" + } + }, + "additionalProperties": false + } + ] + } + ] + } + } + }, + "additionalProperties": false +} diff --git a/doc/logo.md b/doc/logo.md deleted file mode 100644 index 69d13e8efc..0000000000 --- a/doc/logo.md +++ /dev/null @@ -1,116 +0,0 @@ -# Logo options - -## General - -| Option | Default | Description | -|--------|---------|-------------| -| `--logo`, `-l` | `""` | The logo source, interpreted depending on type | -| `--logo-type` | `auto` | The logo type. See the following categories for possible values | -| `--` | `""` | Short for `--logo-type --logo ` | -| `--logo-padding` | `""` | Sets the padding left and right of the logo | -| `--logo-padding-left` | `0` | Sets the padding left of the logo | -| `--logo-padding-right` | `4` | Sets the padding right of the logo | -| `--logo-padding-top` | `0` | Sets the padding top of the logo | - -All filesytem paths can be: -* Absolute -* Relative to the current working directory -* Relative to any of the directories listed by `fastfetch --list-data-paths` + `/logos` - For example, the file `~/.local/share/fastfetch/logos/shrek` can simply be referenced as `shrek`. - -## Text - -| Option | Default | Description | -|--------|---------|-------------| -| `--logo-color-[1-9]` | `""` | Overrides a color for logos that support it | -| `--logo-print-remaining` | `true` | Print the remaining logo, if it is higher than the keys | - -* Color placeholders are in the form `$[1-9]`. To print a `$`, use `$$`. -* If a color placeholder value is not set, the placeholder is simply discarded. - -## Image - -| Option | Default | Description | -|--------|---------|-------------| -| `--logo-width` | `""` | Sets the width of the logo for logos that support it | -| `--logo-height` | `""` | Sets the height of the logo for logos that support it | - -* If one of the height / width options is set, but the other not, the aspect ratio is preserved. -* If neither height nor width is set, the original size is used. - -# Logo types - -## auto - -Trys to detect the logo type depending on the value of `--logo`, in the following order: -* If the value is empty / not set, an autodected builtin logo is displayed. -* If the value is the name of a builtin logo, it is displayed. -* If the value is the path to an image file, and the terminal emulator is known to support an image protocol, the image is displayed. -* If the value is the path to a text file, the content is displayed. -* The autodetected builtin logo is displayed. - -## builtin - -The value of `--logo` is interpreted as the name of a builtin logo. -* If the value is empty / not set, it is autodetected. -* Use `--list-logos` to get a list of all available logos. -* Use `--print-logos` to see all available logos. -* All builtin logos set default values for `--logo-color-[1-9]`. -* Use `none` to disable the logo, but keep key colors from the detected logo. - -## file - -The value of `--logo` is interpreted as the path to a file. The content of the file is displayed. -* If the file can't be read, the autodetected builtin logo is displayed. - -## file-raw - -The value of `--logo` is interpreted as the path to a file. The content of the file is displayed. -* No color placeholder replacement is done. -* If the file can't be read, the autodetected builtin logo is displayed. - -## data - -The value of `--logo` is interpreted as the logo and directly displayed. -* If the value is empty / not set, the autodetected builtin logo is displayed. - -## data-raw - -The value of `--logo` is interpreted as the logo and directly displayed. -* No color placeholder replacement is done. -* If the value is empty / not set, the autodetected builtin logo is displayed. - -## sixel - -The value of `--logo` is interpreted as the path to an image file. It is displayed using the sixel graphics protocol. -* `fastfetch` must be compiled with the `imagemagick6` or `imagemagick7` feature. - -## kitty - -The value of `--logo` is interpreted as the path to an image file. It is displayed using the kitty graphics protocol. -* If the file is a png file, and both `--logo-width` and `--logo-height` are specified, the image is directly send to the terminal emulator. -* Otherwise `fastfetch` must be compiled with the `imagemagick6` or `imagemagick7` feature. - -## iterm - -The value of `--logo` is interpreted as the path to an image file. It is displayed using the iTerm graphics protocol. -* Both `--logo-width` and `--logo-height` must be specified. - -## chafa - -The value of `--logo` is interpreted as the path to an image file. It is converted to an ascii logo using `libchafa`. -* `fastfetch` must be compiled with the `chafa` feature. -* `fastfetch` must be compiled with the `imagemagick6` or `imagemagick7` feature. -* Use `--chafa-fg-only` to set weather to render foreground only. -* Use `--chafa-symbols` to set the symbols. -* Use `--chafa-canvas-mode` to set the canvas mode. -* Use `--chafa-color-space` to set the color space. -* Use `--chafa-dither-mode` to set the dither mode. -* See the [chafa documentation](https://hpjansson.org/chafa/man/) for more information. - -## raw - -The value of `--logo` is interpreted as the path to a binary file. It is printed as-is. -* Both `--logo-width` and `--logo-height` must be specified. -* Use this to display a pre converted image file. -* If the file can't be read, the autodetected builtin logo is displayed. diff --git a/presets/all b/presets/all index 7079c84af0..48d24b4a78 100644 --- a/presets/all +++ b/presets/all @@ -1 +1 @@ ---structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Wallpaper:Terminal:TerminalFont:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:Break:Colors +--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:Monitor:LM:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Wallpaper:Terminal:TerminalFont:TerminalSize:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:Break:Colors diff --git a/presets/all.jsonc b/presets/all.jsonc new file mode 100644 index 0000000000..a1e722fae1 --- /dev/null +++ b/presets/all.jsonc @@ -0,0 +1,57 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "modules": [ + "title", + "separator", + "os", + "host", + "bios", + "board", + "chassis", + "kernel", + "uptime", + "processes", + "packages", + "shell", + "display", + "brightness", + "monitor", + "lm", + "de", + "wm", + "wmtheme", + "theme", + "icons", + "font", + "cursor", + "wallpaper", + "terminal", + "terminalfont", + "terminalsize", + "cpu", + "cpuusage", + "gpu", + "memory", + "swap", + "disk", + "battery", + "poweradapter", + "player", + "media", + "publicip", + "localip", + "wifi", + "datetime", + "locale", + "vulkan", + "opengl", + "opencl", + "users", + "bluetooth", + "sound", + "gamepad", + "weather", + "break", + "colors" + ] +} diff --git a/presets/btw.jsonc b/presets/btw.jsonc new file mode 100644 index 0000000000..8ad31e61a0 --- /dev/null +++ b/presets/btw.jsonc @@ -0,0 +1,42 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "type": "builtin", + "source": "arch" + }, + "modules": [ + "title", + "separator", + { + "type": "os", + "format": "Arch Linux ({12})" + }, + "host", + "kernel", + "uptime", + { + "type": "packages", + "format": "{} (pacman)" + }, + "shell", + "display", + "de", + "wm", + "wmtheme", + "theme", + "icons", + "font", + "cursor", + "terminal", + "terminalfont", + "cpu", + "gpu", + "memory", + "disk", + "battery", + "poweradapter", + "locale", + "break", + "colors" + ] +} diff --git a/presets/devinfo.jsonc b/presets/devinfo.jsonc new file mode 100644 index 0000000000..450adb9262 --- /dev/null +++ b/presets/devinfo.jsonc @@ -0,0 +1,49 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "type": "builtin", + "source": "arch" + }, + "display": { + "disableLinewrap": false, + "showErrors": true + }, + "general": { + "multithreading": false + }, + "modules": [ + "title", + "separator", + { + "type": "os", + "format": "Arch Linux ({12})" + }, + "host", + "kernel", + "uptime", + { + "type": "packages", + "format": "{} (pacman)" + }, + "shell", + "display", + "de", + "wm", + "wmtheme", + "theme", + "icons", + "font", + "cursor", + "terminal", + "terminalfont", + "cpu", + "gpu", + "memory", + "disk", + "battery", + "poweradapter", + "locale", + "break", + "colors" + ] +} diff --git a/presets/examples/2 b/presets/examples/2 index a7eda7fd94..6bd5a0ce3b 100644 --- a/presets/examples/2 +++ b/presets/examples/2 @@ -20,5 +20,5 @@ --wm-key " " --shell-key " " --terminal-key " " ---terminal-font-key " " +--terminalfont-key " " --packages-key " " diff --git a/presets/examples/2.jsonc b/presets/examples/2.jsonc new file mode 100644 index 0000000000..4b89cff761 --- /dev/null +++ b/presets/examples/2.jsonc @@ -0,0 +1,166 @@ +// Load with --load-config examples/2.jsonc +// Note that you must replace the image path to an existing image to display it. + +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + // "logo": { + // "type": "iterm", + // "source": "/Users/carter/Desktop/apple1.png", + // "width": 28, + // "height": 12 + // }, + "display": { + "separator": "  " + }, + "modules": [ + { + "type": "custom", // HardwareStart + "format": "┌─────────── \u001b[1mHardware Information\u001b[0m ───────────┐" // `\u001b` is `\033`, or `\e` + }, + { + "type": "host", + "key": " " + }, + { + "type": "cpu", + "key": " " + }, + { + "type": "gpu", + "key": " ﬙" + }, + { + "type": "disk", + "key": " " + }, + { + "type": "memory", + "key": " 󰑭" + }, + { + "type": "swap", + "key": " 󰓡" + }, + { + "type": "display", + "key": " 󰍹" + }, + { + "type": "brightness", + "key": " 󰃞" + }, + { + "type": "battery", + "key": " " + }, + { + "type": "poweradapter", + "key": " " + }, + { + "type": "bluetooth", + "key": " " + }, + { + "type": "sound", + "key": " " + }, + { + "type": "gamepad", + "key": " " + }, + { + "type": "custom", // SoftwareStart + "format": "├─────────── \u001b[1mSoftware Information\u001b[0m ───────────┤" + }, + { + "type": "title", + "key": " ", + "format": "{1}@{2}" + }, + { + "type": "os", + "key": " " // Just get your distro's logo off nerdfonts.com + }, + { + "type": "kernel", + "key": " ", + "format": "{1} {2}" + }, + { + "type": "lm", + "key": " 󰧨" + }, + { + "type": "de", + "key": " " + }, + { + "type": "wm", + "key": " " + }, + { + "type": "shell", + "key": " " + }, + { + "type": "terminal", + "key": " " + }, + { + "type": "terminalfont", + "key": " " + }, + { + "type": "theme", + "key": " 󰉼" + }, + { + "type": "icons", + "key": " 󰀻" + }, + { + "type": "wallpaper", + "key": " 󰸉" + }, + { + "type": "packages", + "key": " 󰏖" + }, + { + "type": "uptime", + "key": " 󰅐" + }, + { + "type": "media", + "key": " 󰝚" + }, + { + "type": "localip", + "key": " 󰩟", + "compact": true + }, + { + "type": "publicip", + "key": " 󰩠" + }, + { + "type": "wifi", + "key": " ", + "format": "{4}" // ssid + }, + { + "type": "locale", + "key": " " + }, + { + "type": "custom", // InformationEnd + "format": "└────────────────────────────────────────────┘" + }, + { + "type": "colors", + "paddingLeft": 2, + "symbol": "circle" + } + ] +} diff --git a/presets/examples/3.jsonc b/presets/examples/3.jsonc new file mode 100644 index 0000000000..89fc93198c --- /dev/null +++ b/presets/examples/3.jsonc @@ -0,0 +1,20 @@ +// Load with --load-config examples/3.jsonc + +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": "debian_small", + "display": { + "binaryPrefix": "si" + }, + "modules": [ + "vulkan", + "opengl", + "opencl", + "memory", + { + "type": "disk", + "folders": "/:/home:/boot:/efi" + }, + "localip" + ] +} diff --git a/presets/examples/4 b/presets/examples/4 index bd0ea06b51..f41e25a73f 100644 --- a/presets/examples/4 +++ b/presets/examples/4 @@ -4,4 +4,4 @@ --logo arch_small --logo-padding-right 1 --separator "  " ---structure Date:Time:Break:Player:Media +--structure DateTime:Break:Player:Media diff --git a/presets/examples/4.jsonc b/presets/examples/4.jsonc new file mode 100644 index 0000000000..81040c0d86 --- /dev/null +++ b/presets/examples/4.jsonc @@ -0,0 +1,31 @@ +// Load with --load-config examples/4.jsonc + +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "source": "arch_small", + "padding": { + "right": 1 + } + }, + "display": { + "binaryPrefix": "si", + "color": "blue", + "separator": "  " + }, + "modules": [ + { + "type": "datetime", + "key": "Date", + "format": "{1}-{3}-{11}" + }, + { + "type": "datetime", + "key": "Time", + "format": "{14}:{17}:{20}" + }, + "break", + "player", + "media" + ] +} diff --git a/presets/examples/5.jsonc b/presets/examples/5.jsonc new file mode 100644 index 0000000000..888c763d7c --- /dev/null +++ b/presets/examples/5.jsonc @@ -0,0 +1,29 @@ +// Load with --load-config examples/5.jsonc + +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": null, + "display": { + "color": "reset_magenta" + }, + "modules": [ + { + "type": "theme", + "key": "T", + "format": "{7}" + }, + { + "type": "icons", + "key": "I", + "format": "{5}" + }, + { + "type": "font", + "key": "F" + }, + { + "type": "cursor", + "key": "C" + } + ] +} diff --git a/presets/examples/6.jsonc b/presets/examples/6.jsonc new file mode 100644 index 0000000000..4a9c4c7ebe --- /dev/null +++ b/presets/examples/6.jsonc @@ -0,0 +1,185 @@ +// Load with --load-config examples/2.jsonc +// Note that you must replace the image path to an existing image to display it. + +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + // "logo": { + // "type": "iterm", + // "source": "/Users/carter/Desktop/apple1.png", + // "width": 28, + // "height": 12 + // }, + "display": { + "separator": " " + }, + "modules": [ + { + "type": "host", + "key": "╭─", + "keyColor": "green" + }, + { + "type": "cpu", + "key": "├─", + "keyColor": "green" + }, + { + "type": "gpu", + "key": "├─﬙", + "keyColor": "green" + }, + { + "type": "disk", + "key": "├─", + "keyColor": "green" + }, + { + "type": "memory", + "key": "├─󰑭", + "keyColor": "green" + }, + { + "type": "swap", + "key": "├─󰓡", + "keyColor": "green" + }, + { + "type": "display", + "key": "├─󰍹", + "keyColor": "green" + }, + { + "type": "brightness", + "key": "├─󰃞", + "keyColor": "green" + }, + { + "type": "battery", + "key": "├─", + "keyColor": "green" + }, + { + "type": "poweradapter", + "key": "├─", + "keyColor": "green" + }, + { + "type": "gamepad", + "key": "├─", + "keyColor": "green" + }, + { + "type": "bluetooth", + "key": "├─", + "keyColor": "green" + }, + { + "type": "sound", + "key": "╰─", + "keyColor": "green" + }, + "break", + + { + "type": "shell", + "key": "╭─", + "keyColor": "yellow" + }, + { + "type": "terminal", + "key": "├─", + "keyColor": "yellow" + }, + { + "type": "terminalfont", + "key": "├─", + "keyColor": "yellow" + }, + { + "type": "lm", + "key": "├─󰧨", + "keyColor": "yellow" + }, + { + "type": "de", + "key": "├─", + "keyColor": "yellow" + }, + { + "type": "wm", + "key": "├─", + "keyColor": "yellow" + }, + { + "type": "theme", + "key": "├─󰉼", + "keyColor": "yellow" + }, + { + "type": "icons", + "key": "├─󰀻", + "keyColor": "yellow" + }, + { + "type": "wallpaper", + "key": "╰─󰸉", + "keyColor": "yellow" + }, + + "break", + { + "type": "title", + "key": "╭─", + "format": "{1}@{2}", + "keyColor": "blue" + }, + { + "type": "os", + "key": "├─", // Just get your distro's logo off nerdfonts.com + "keyColor": "blue" + }, + { + "type": "kernel", + "key": "├─", + "format": "{1} {2}", + "keyColor": "blue" + }, + { + "type": "packages", + "key": "├─󰏖", + "keyColor": "blue" + }, + { + "type": "uptime", + "key": "├─󰅐", + "keyColor": "blue" + }, + { + "type": "media", + "key": "├─󰝚", + "keyColor": "blue" + }, + { + "type": "localip", + "key": "├─󰩟", + "compact": true, + "keyColor": "blue" + }, + { + "type": "publicip", + "key": "├─󰩠", + "keyColor": "blue" + }, + { + "type": "wifi", + "key": "├─", + "format": "{4}", // ssid + "keyColor": "blue" + }, + { + "type": "locale", + "key": "╰─", + "keyColor": "blue" + } + ] +} diff --git a/presets/examples/7.jsonc b/presets/examples/7.jsonc new file mode 100644 index 0000000000..59048f7d20 --- /dev/null +++ b/presets/examples/7.jsonc @@ -0,0 +1,139 @@ +// Load with --load-config examples/2.jsonc +// Note that you must replace the image path to an existing image to display it. + +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "padding": { + "top": 2 + } + }, + "display": { + "separator": " -> " + }, + "modules": [ + "title", + "separator", + { + "type": "os", + "key": " OS", + "keyColor": "yellow", + "format": "{2}" + }, + { + "type": "os", + "key": "├", // Just get your distro's logo off nerdfonts.com + "keyColor": "yellow", + "format": "{6}{?6} {?}{10} {8}" + }, + { + "type": "kernel", + "key": "├", + "keyColor": "yellow" + }, + { + "type": "packages", + "key": "├󰏖", + "keyColor": "yellow" + }, + { + "type": "shell", + "key": "└", + "keyColor": "yellow" + }, + "break", + + { + "type": "wm", + "key": " DE/WM", + "keyColor": "blue" + }, + { + "type": "lm", + "key": "├󰧨", + "keyColor": "blue" + }, + { + "type": "wmtheme", + "key": "├󰉼", + "keyColor": "blue" + }, + { + "type": "icons", + "key": "├󰀻", + "keyColor": "blue" + }, + { + "type": "terminal", + "key": "├", + "keyColor": "blue" + }, + { + "type": "wallpaper", + "key": "└󰸉", + "keyColor": "blue" + }, + + "break", + { + "type": "host", + "key": " PC", + "keyColor": "green" + }, + { + "type": "cpu", + "key": "├", + "keyColor": "green" + }, + { + "type": "gpu", + "key": "├﬙", + "keyColor": "green" + }, + { + "type": "disk", + "key": "├", + "keyColor": "green" + }, + { + "type": "memory", + "key": "├󰑭", + "keyColor": "green" + }, + { + "type": "swap", + "key": "├󰓡", + "keyColor": "green" + }, + { + "type": "uptime", + "key": "├󰅐", + "keyColor": "green" + }, + { + "type": "display", + "key": "└󰍹", + "keyColor": "green" + }, + + "break", + { + "type": "sound", + "key": " SOUND", + "keyColor": "cyan" + }, + { + "type": "player", + "key": "├󰥠", + "keyColor": "cyan" + }, + { + "type": "media", + "key": "└󰝚", + "keyColor": "cyan" + }, + + "break", + "colors" + ] +} diff --git a/presets/examples/8.jsonc b/presets/examples/8.jsonc new file mode 100644 index 0000000000..7fe01dd7f8 --- /dev/null +++ b/presets/examples/8.jsonc @@ -0,0 +1,51 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "type": "small" + }, + "display": { + "separator": " ", + "color": { + "keys": "magenta" + }, + "sizeNdigits": 0, + "sizeMaxPrefix": "MB", + "percentType": 9 + }, + "modules": [ + { + "type": "title", + "color": { + "user": "green", + "at": "red", + "host": "blue" + } + }, + { + "type": "os", + "key": "", + "format": "{2} {8}" + }, + { + "type": "kernel", + "key": "" + }, + { + "type": "memory", + "key": "" + }, + { + "type": "packages", + "key": "" + }, + { + "type": "uptime", + "key": "" + }, + { + "type": "custom", + "key": "", + "format": "\u001b[31m███\u001b[32m███\u001b[33m███\u001b[34m███\u001b[35m███\u001b[36m███" + } + ] +} diff --git a/presets/hardware.jsonc b/presets/hardware.jsonc new file mode 100644 index 0000000000..d976285fc6 --- /dev/null +++ b/presets/hardware.jsonc @@ -0,0 +1,25 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "type": "builtin", + "source": "arch" + }, + "modules": [ + "host", + "display", + "cpu", + "gpu", + { + "type": "memory", + "format": "{?2}{2}{?}" + }, + { + "type": "disk", + "format": "{?2}{2}{?}" + }, + { + "type": "battery", + "format": "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}" + } + ] +} diff --git a/presets/neofetch b/presets/neofetch index 9d42df956d..925f4705b0 100644 --- a/presets/neofetch +++ b/presets/neofetch @@ -1,10 +1,9 @@ --structure "Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Display:DE:WM:WMTheme:Theme:Icons:Terminal:TerminalFont:CPU:GPU:Memory:Break:Colors" --host-format "{/2}{-}{/}{2}{?3} {3}{?}" --os-format "{3} {12}" ---display-format "{}x{}" +--display-key Resolution +--display-compact-type original --de-format "{2} {3}" --theme-format "{?1}{1}{?3} {3}{?} [Plasma], {?}{7}" ---terminal-font-format "{/2}{-}{/}{2}{?3} {3}{?}" +--terminalfont-format "{/2}{-}{/}{2}{?3} {3}{?}" --memory-format "{/1}{-}{/}{/2}{-}{/}{} / {}" ---gpu-key "GPU" ---display-key "Display" diff --git a/presets/neofetch.jsonc b/presets/neofetch.jsonc new file mode 100644 index 0000000000..b7bbaac47a --- /dev/null +++ b/presets/neofetch.jsonc @@ -0,0 +1,48 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "modules": [ + "title", + "separator", + { + "type": "os", + "format": "{3} {12}" + }, + { + "type": "host", + "format": "{/2}{-}{/}{2}{?3} {3}{?}" + }, + "kernel", + "uptime", + "packages", + "shell", + { + "type": "display", + "compactType": "original", + "key": "Resolution" + }, + "de", + "wm", + "wmtheme", + { + "type": "theme", + "format": "{?1}{1}{?3} {3}{?} [Plasma], {?}{7}" + }, + "icons", + "terminal", + { + "type": "terminalfont", + "format": "{/2}{-}{/}{2}{?3} {3}{?}" + }, + "cpu", + { + "type": "gpu", + "key": "GPU" + }, + { + "type": "memory", + "format": "{/1}{-}{/}{/2}{-}{/}{} / {}" + }, + "break", + "colors" + ] +} diff --git a/presets/paleofetch.jsonc b/presets/paleofetch.jsonc new file mode 100644 index 0000000000..7fe9ea0aaf --- /dev/null +++ b/presets/paleofetch.jsonc @@ -0,0 +1,35 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "modules": [ + "title", + "separator", + "os", + { + "type": "host", + "format": "{/2}{-}{/}{2}{?3} {3}{?}" + }, + "kernel", + "uptime", + { + "type": "battery", + "format": "{/4}{-}{/}{4}%{?5} [{5}]{?}" + }, + "break", + "packages", + "shell", + { + "type": "display", + "key": "Display" + }, + "terminal", + "break", + "cpu", + { + "type": "gpu", + "key": "GPU" + }, + "memory", + "break", + "colors" + ] +} diff --git a/presets/software.jsonc b/presets/software.jsonc new file mode 100644 index 0000000000..b2715adaa6 --- /dev/null +++ b/presets/software.jsonc @@ -0,0 +1,17 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "modules": [ + "os", + "kernel", + "shell", + "de", + "wm", + "wmtheme", + "theme", + "icons", + "font", + "cursor", + "terminal", + "terminalfont" + ] +} diff --git a/presets/verbose b/presets/verbose index 6a92397284..3ed020f193 100644 --- a/presets/verbose +++ b/presets/verbose @@ -3,23 +3,23 @@ --kernel-format Sysname: {}; Release: {}; Version: {} --uptime-format Days: {}; Hours: {}; Minutes: {}; Seconds: {} --processes-format Count: {} ---packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; eopkg: {}; xbps: {}; apk: {}; flatpak-system: {}; flatpak-user: {}; snap: {}; brew: {}; brew-cask: {}; port: {}; scoop: {}; choco: {}; pkgtool: {} +--packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; eopkg: {}; xbps: {}; apk: {}; flatpak-system: {}; flatpak-user: {}; snap: {}; brew: {}; brew-cask: {}; port: {}; scoop: {}; choco: {}; pkgtool: {}; paludis {} --shell-format Process name: {}; Process path: {}; Process exe: {}; Process version: {}; User path: {}; User exe: {}; User version: {} --display-format Width: {}; Height: {}; Refresh rate: {}; ScaledWith: {}; ScaledHeight: {} --de-format Process name: {}; Pretty name: {}; Version: {} --wm-format Process name: {}; Pretty name: {}; Protocol: {} ---wm-theme-format Name: {} +--wmtheme-format Name: {} --theme-format Plasma: {}; Plasma colors: {}; Plasma colors pretty: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {} --icons-format Plasma: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {} --font-format Font1: {}; Font2: {}; Font3: {}; Font4: {} --cursor-format Theme: {}; Size: {} --terminal-format Process: {}; Path: {}; Exe: {} ---terminal-font-format Pretty: {}; Name: {}; Size: {}; Styles: {} +--terminalfont-format Pretty: {}; Name: {}; Size: {}; Styles: {} --cpu-format Name: {}, Vendor: {}, CoresPhysical: {}, CoresLogical: {}, CoresOnline: {}, FrequencyMin: {}, FrequencyMax: {}, Temperature: {} --cpu-usage-format Percentage: {} --gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}; CoreCount: {}; Type: {} --memory-format Used: {}; Total: {}; Percentage: {} ---disk-format SizeUsed: {}; SizeTotal: {}; SizePercentage: {}; FilesUsed: {}; FilesTotal: {}; FilesPercentage: {}; Removable: {}; Hidden: {}; Filesystem: {}; Name: {} +--disk-format SizeUsed: {}; SizeTotal: {}; SizePercentage: {}; FilesUsed: {}; FilesTotal: {}; FilesPercentage: {}; External: {}; Hidden: {}; Filesystem: {}; Name: {} --battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {} --poweradapter-format Watts: {}; Name: {}; Manufactor: {}; Model: {}; Description: {} --player-format Pretty: {}; Name: {}; Bus: {}; Url: {} diff --git a/src/common/bar.c b/src/common/bar.c index d4a8cf0f1b..e42a07c2a1 100644 --- a/src/common/bar.c +++ b/src/common/bar.c @@ -3,7 +3,7 @@ // green, yellow, red: print the color on nth (0~9) block // set its value == 10 means the color will not be printed -void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red) +void ffAppendPercentBar(FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red) { assert(green <= 10 && yellow <= 10 && red <= 10); @@ -15,14 +15,14 @@ void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, percent = (uint8_t)(percent + 5) / 10; assert(percent <= 10); - if(!instance->config.pipe) + if(!instance.config.pipe) ffStrbufAppendS(buffer, "\033[97m[ "); else ffStrbufAppendS(buffer, "[ "); for (uint8_t i = 0; i < percent; ++i) { - if(!instance->config.pipe) + if(!instance.config.pipe) { if (i == green) ffStrbufAppendS(buffer, "\033[32m"); @@ -36,13 +36,13 @@ void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, if (percent < 10) { - if(!instance->config.pipe) + if(!instance.config.pipe) ffStrbufAppendS(buffer, "\033[97m"); for (uint8_t i = percent; i < 10; ++i) ffStrbufAppendS(buffer, "-"); } - if(!instance->config.pipe) + if(!instance.config.pipe) ffStrbufAppendS(buffer, "\033[97m ]" FASTFETCH_TEXT_MODIFIER_RESET); else ffStrbufAppendS(buffer, " ]"); @@ -57,16 +57,16 @@ void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, // [green, 100]: print green // [yellow, green): print yellow // [0, yellow): PRINT RED -void ffAppendPercentNum(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, bool parentheses) +void ffAppendPercentNum(FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, bool parentheses) { assert(green <= 100 && yellow <= 100); - bool colored = !!(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT); + bool colored = !!(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT); if (parentheses) ffStrbufAppendC(buffer, '('); - if (colored && !instance->config.pipe) + if (colored && !instance.config.pipe) { if(green < yellow) { @@ -89,7 +89,7 @@ void ffAppendPercentNum(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, } ffStrbufAppendF(buffer, "%u%%", (unsigned) percent); - if (colored && !instance->config.pipe) + if (colored && !instance.config.pipe) { ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET); } diff --git a/src/common/bar.h b/src/common/bar.h index f28cbe7773..d776454d4d 100644 --- a/src/common/bar.h +++ b/src/common/bar.h @@ -13,7 +13,7 @@ enum FF_PERCENTAGE_TYPE_NUM_COLOR_BIT = 1 << 3, }; -void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red); -void ffAppendPercentNum(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, bool parentheses); +void ffAppendPercentBar(FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red); +void ffAppendPercentNum(FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, bool parentheses); #endif diff --git a/src/common/color.h b/src/common/color.h new file mode 100644 index 0000000000..7f8c539cc4 --- /dev/null +++ b/src/common/color.h @@ -0,0 +1,55 @@ +#pragma once + +#define FF_COLOR_MODE_RESET "0;" +#define FF_COLOR_MODE_BOLD "1;" +#define FF_COLOR_MODE_DIM "2;" +#define FF_COLOR_MODE_ITALIC "3;" +#define FF_COLOR_MODE_UNDERLINE "4;" +#define FF_COLOR_MODE_BLINK "5;" +#define FF_COLOR_MODE_INVERSE "7;" +#define FF_COLOR_MODE_HIDDEN "8;" +#define FF_COLOR_MODE_STRIKETHROUGH "9;" + +#define FF_COLOR_FG_BLACK "30" +#define FF_COLOR_FG_RED "31" +#define FF_COLOR_FG_GREEN "32" +#define FF_COLOR_FG_YELLOW "33" +#define FF_COLOR_FG_BLUE "34" +#define FF_COLOR_FG_MAGENTA "35" +#define FF_COLOR_FG_CYAN "36" +#define FF_COLOR_FG_WHITE "37" +#define FF_COLOR_FG_DEFAULT "39" + +#define FF_COLOR_FG_LIGHT_BLACK "90" +#define FF_COLOR_FG_LIGHT_RED "91" +#define FF_COLOR_FG_LIGHT_GREEN "92" +#define FF_COLOR_FG_LIGHT_YELLOW "93" +#define FF_COLOR_FG_LIGHT_BLUE "94" +#define FF_COLOR_FG_LIGHT_MAGENTA "95" +#define FF_COLOR_FG_LIGHT_CYAN "96" +#define FF_COLOR_FG_LIGHT_WHITE "97" + +#define FF_COLOR_BG_BLACK "40" +#define FF_COLOR_BG_RED "41" +#define FF_COLOR_BG_GREEN "42" +#define FF_COLOR_BG_YELLOW "43" +#define FF_COLOR_BG_BLUE "44" +#define FF_COLOR_BG_MAGENTA "45" +#define FF_COLOR_BG_CYAN "46" +#define FF_COLOR_BG_WHITE "47" +#define FF_COLOR_BG_DEFAULT "49" + +#define FF_COLOR_BG_LIGHT_BLACK "100" +#define FF_COLOR_BG_LIGHT_RED "101" +#define FF_COLOR_BG_LIGHT_GREEN "102" +#define FF_COLOR_BG_LIGHT_YELLOW "103" +#define FF_COLOR_BG_LIGHT_BLUE "104" +#define FF_COLOR_BG_LIGHT_MAGENTA "105" +#define FF_COLOR_BG_LIGHT_CYAN "106" +#define FF_COLOR_BG_LIGHT_WHITE "107" + +#define FF_COLOR_FG_256 "38;5;" +#define FF_COLOR_BG_256 "48;5;" + +#define FF_COLOR_FG_RGB "38;2;" +#define FF_COLOR_BG_RGB "48;2;" diff --git a/src/common/dbus.c b/src/common/dbus.c index b0f5c4ffe9..968358a8d6 100644 --- a/src/common/dbus.c +++ b/src/common/dbus.c @@ -5,9 +5,9 @@ #include "common/thread.h" #include "util/stringUtils.h" -static bool loadLibSymbols(const FFinstance* instance, FFDBusLibrary* lib) +static bool loadLibSymbols(FFDBusLibrary* lib) { - FF_LIBRARY_LOAD(dbus, &instance->config.libDBus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4); + FF_LIBRARY_LOAD(dbus, &instance.config.libDBus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4); FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_bus_get, false) FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_new_method_call, false) FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_init, false) @@ -28,7 +28,7 @@ static bool loadLibSymbols(const FFinstance* instance, FFDBusLibrary* lib) return true; } -static const FFDBusLibrary* loadLib(const FFinstance* instance) +static const FFDBusLibrary* loadLib(void) { static FFDBusLibrary lib; static bool loaded = false; @@ -40,16 +40,16 @@ static const FFDBusLibrary* loadLib(const FFinstance* instance) if(!loaded) { loaded = true; - loadSuccess = loadLibSymbols(instance, &lib); + loadSuccess = loadLibSymbols(&lib); } ffThreadMutexUnlock(&mutex); return loadSuccess ? &lib : NULL; } -const char* ffDBusLoadData(const FFinstance* instance, DBusBusType busType, FFDBusData* data) +const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data) { - data->lib = loadLib(instance); + data->lib = loadLib(); if(data->lib == NULL) return "Failed to load DBus library"; diff --git a/src/common/dbus.h b/src/common/dbus.h index 7f0fa24028..bf112e244c 100644 --- a/src/common/dbus.h +++ b/src/common/dbus.h @@ -45,7 +45,7 @@ typedef struct FFDBusData DBusConnection* connection; } FFDBusData; -const char* ffDBusLoadData(const FFinstance* instance, DBusBusType busType, FFDBusData* data); //Returns an error message or NULL on success +const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data); //Returns an error message or NULL on success bool ffDBusGetValue(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result); bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result); bool ffDBusGetByte(FFDBusData* dbus, DBusMessageIter* iter, uint8_t* result); diff --git a/src/common/font.c b/src/common/font.c index d789d466fb..042fa74eee 100644 --- a/src/common/font.c +++ b/src/common/font.c @@ -3,12 +3,13 @@ #include -static void fontInit(FFfont* font) +void ffFontInit(FFfont* font) { + // Ensure no memory allocates ffStrbufInit(&font->pretty); ffStrbufInit(&font->name); - ffStrbufInitA(&font->size, 4); - ffListInitA(&font->styles, sizeof(FFstrbuf), 4); + ffStrbufInit(&font->size); + ffListInit(&font->styles, sizeof(FFstrbuf)); } static void fontInitPretty(FFfont* font) @@ -44,7 +45,7 @@ static void fontInitPretty(FFfont* font) void ffFontInitQt(FFfont* font, const char* data) { - fontInit(font); + ffFontInit(font); //See https://doc.qt.io/qt-5/qfont.html#toString @@ -181,7 +182,7 @@ static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* altern void ffFontInitPango(FFfont* font, const char* data) { - fontInit(font); + ffFontInit(font); while(*data != '\0' && *data != '`' && *data != '\\') fontPangoParseWord(&data, font, NULL); @@ -191,7 +192,7 @@ void ffFontInitPango(FFfont* font, const char* data) void ffFontInitValues(FFfont* font, const char* name, const char* size) { - fontInit(font); + ffFontInit(font); ffStrbufAppendS(&font->name, name); ffStrbufAppendS(&font->size, size); @@ -213,7 +214,7 @@ void ffFontInitWithSpace(FFfont* font, const char* rawName) return; } - fontInit(font); + ffFontInit(font); ffStrbufAppendNS(&font->name, (uint32_t)(pspace - rawName), rawName); ffStrbufAppendS(&font->size, pspace + 1); diff --git a/src/common/font.h b/src/common/font.h index 605f7c4307..58b3841ae6 100644 --- a/src/common/font.h +++ b/src/common/font.h @@ -14,6 +14,7 @@ typedef struct FFfont FFlist styles; } FFfont; +void ffFontInit(FFfont* font); void ffFontInitQt(FFfont* font, const char* data); void ffFontInitPango(FFfont* font, const char* data); void ffFontInitCopy(FFfont* font, const char* name); diff --git a/src/common/format.c b/src/common/format.c index 7394822f82..4ed096dc1c 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -25,7 +25,7 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg) else if(formatarg->type == FF_FORMAT_ARG_TYPE_DOUBLE) ffStrbufAppendF(buffer, "%g", *(double*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_BOOL) - ffStrbufAppendS(buffer, formatarg->value != NULL ? "true" : "false"); + ffStrbufAppendS(buffer, *(bool*)formatarg->value ? "true" : "false"); else if(formatarg->type == FF_FORMAT_ARG_TYPE_LIST) { const FFlist* list = formatarg->value; @@ -134,18 +134,14 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n continue; } - FFstrbuf placeholderValue; - ffStrbufInit(&placeholderValue); + FF_STRBUF_AUTO_DESTROY placeholderValue = ffStrbufCreate(); while(i < formatstr->length && formatstr->chars[i] != '}') ffStrbufAppendC(&placeholderValue, formatstr->chars[i++]); // test if for stop, if so break the loop if(placeholderValue.length == 1 && placeholderValue.chars[0] == '-') - { - ffStrbufDestroy(&placeholderValue); break; - } // test for end of an if, if so do nothing if(placeholderValue.length == 1 && placeholderValue.chars[0] == '?') @@ -155,7 +151,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n else --numOpenIfs; - ffStrbufDestroy(&placeholderValue); continue; } @@ -167,7 +162,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n else --numOpenNotIfs; - ffStrbufDestroy(&placeholderValue); continue; } @@ -182,7 +176,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n --numOpenColors; } - ffStrbufDestroy(&placeholderValue); continue; } @@ -197,7 +190,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n if(index > numArgs) { appendInvalidPlaceholder(buffer, "{?", &placeholderValue, i, formatstr->length); - ffStrbufDestroy(&placeholderValue); continue; } @@ -205,13 +197,11 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n if(formatArgSet(&arguments[index - 1])) { ++numOpenIfs; - ffStrbufDestroy(&placeholderValue); continue; } // fastforward to the end of the if without printing the in between i = ffStrbufNextIndexS(formatstr, i, "{?}") + 2; // 2 is the length of "{?}" - 1 because the loop will increament it again directly after continue - ffStrbufDestroy(&placeholderValue); continue; } @@ -226,7 +216,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n if(index > numArgs) { appendInvalidPlaceholder(buffer, "{/", &placeholderValue, i, formatstr->length); - ffStrbufDestroy(&placeholderValue); continue; } @@ -234,13 +223,11 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n if(!formatArgSet(&arguments[index - 1])) { ++numOpenNotIfs; - ffStrbufDestroy(&placeholderValue); continue; } // fastforward to the end of the if without printing the in between i = ffStrbufNextIndexS(formatstr, i, "{/}") + 2; // 2 is the length of "{/}" - 1 because the loop will increament it again directly after continue - ffStrbufDestroy(&placeholderValue); continue; } @@ -252,7 +239,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n ffStrbufAppendS(buffer, "\033["); ffStrbufAppend(buffer, &placeholderValue); ffStrbufAppendC(buffer, 'm'); - ffStrbufDestroy(&placeholderValue); continue; } @@ -262,13 +248,10 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n if(index > numArgs) { appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length); - ffStrbufDestroy(&placeholderValue); continue; } ffFormatAppendFormatArg(buffer, &arguments[index - 1]); - - ffStrbufDestroy(&placeholderValue); } ffStrbufTrimRight(buffer, ' '); diff --git a/src/common/format.h b/src/common/format.h index cc7e29e6dc..57c8c680fe 100644 --- a/src/common/format.h +++ b/src/common/format.h @@ -27,6 +27,4 @@ typedef struct FFformatarg void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg); void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments); -#define FF_FORMAT_ARG_VALUE_BOOL(xpr) ((xpr) ? (const void*) 1 : NULL) - #endif diff --git a/src/common/init.c b/src/common/init.c index 4b7f1ce4f3..a74be3e331 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -3,18 +3,22 @@ #include "common/thread.h" #include "detection/displayserver/displayserver.h" #include "util/textModifier.h" +#include "logo/logo.h" #include #include -#include +#include #ifdef _WIN32 #include - #include #include "util/windows/unicode.h" #else #include #endif +#include "modules/modules.h" + +FFinstance instance; // Global singleton + static void initState(FFstate* state) { state->logoWidth = 0; @@ -22,192 +26,141 @@ static void initState(FFstate* state) state->keysHeight = 0; ffPlatformInit(&state->platform); + state->configDoc = NULL; } -static void initModuleArg(FFModuleArgs* args) +static void defaultConfig(void) { - ffStrbufInit(&args->key); - ffStrbufInit(&args->outputFormat); - ffStrbufInit(&args->errorFormat); -} + ffInitLogoOptions(&instance.config.logo); + + ffStrbufInit(&instance.config.colorKeys); + ffStrbufInit(&instance.config.colorTitle); + instance.config.brightColor = true; + ffStrbufInitStatic(&instance.config.keyValueSeparator, ": "); + instance.config.processingTimeout = 1000; + + #if defined(__linux__) || defined(__FreeBSD__) + ffStrbufInit(&instance.config.playerName); + ffStrbufInit(&instance.config.osFile); + instance.config.dsForceDrm = false; + #elif defined(_WIN32) + instance.config.wmiTimeout = 5000; + #endif -static void defaultConfig(FFinstance* instance) -{ - ffStrbufInitA(&instance->config.logo.source, 0); - instance->config.logo.type = FF_LOGO_TYPE_AUTO; - for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i) - ffStrbufInit(&instance->config.logo.colors[i]); - instance->config.logo.width = 0; - instance->config.logo.height = 0; //preserve aspect ratio - instance->config.logo.paddingTop = 0; - instance->config.logo.paddingLeft = 0; - instance->config.logo.paddingRight = 4; - instance->config.logo.printRemaining = true; - instance->config.logo.preserveAspectRadio = false; - - instance->config.logo.chafaFgOnly = false; - ffStrbufInitS(&instance->config.logo.chafaSymbols, "block+border+space-wide-inverted"); // Chafa default - instance->config.logo.chafaCanvasMode = UINT32_MAX; - instance->config.logo.chafaColorSpace = UINT32_MAX; - instance->config.logo.chafaDitherMode = UINT32_MAX; - - ffStrbufInit(&instance->config.colorKeys); - ffStrbufInit(&instance->config.colorTitle); - - ffStrbufInit(&instance->config.separator); - ffStrbufAppendS(&instance->config.separator, ": "); - - instance->config.showErrors = false; - instance->config.recache = false; - instance->config.allowSlowOperations = false; - instance->config.pipe = !isatty(STDOUT_FILENO); - instance->config.disableLinewrap = !instance->config.pipe; - instance->config.hideCursor = !instance->config.pipe; - instance->config.escapeBedrock = true; - instance->config.binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC; - instance->config.glType = FF_GL_TYPE_AUTO; - instance->config.multithreading = true; - instance->config.stat = false; - - initModuleArg(&instance->config.os); - initModuleArg(&instance->config.host); - initModuleArg(&instance->config.bios); - initModuleArg(&instance->config.board); - initModuleArg(&instance->config.brightness); - initModuleArg(&instance->config.chassis); - initModuleArg(&instance->config.kernel); - initModuleArg(&instance->config.uptime); - initModuleArg(&instance->config.processes); - initModuleArg(&instance->config.packages); - initModuleArg(&instance->config.shell); - initModuleArg(&instance->config.display); - initModuleArg(&instance->config.de); - initModuleArg(&instance->config.wm); - initModuleArg(&instance->config.wmTheme); - initModuleArg(&instance->config.theme); - initModuleArg(&instance->config.icons); - initModuleArg(&instance->config.font); - initModuleArg(&instance->config.cursor); - initModuleArg(&instance->config.terminal); - initModuleArg(&instance->config.terminalFont); - initModuleArg(&instance->config.cpu); - initModuleArg(&instance->config.cpuUsage); - initModuleArg(&instance->config.gpu); - initModuleArg(&instance->config.memory); - initModuleArg(&instance->config.swap); - initModuleArg(&instance->config.disk); - initModuleArg(&instance->config.battery); - initModuleArg(&instance->config.powerAdapter); - initModuleArg(&instance->config.locale); - initModuleArg(&instance->config.localIP); - initModuleArg(&instance->config.publicIP); - initModuleArg(&instance->config.weather); - initModuleArg(&instance->config.wifi); - initModuleArg(&instance->config.player); - initModuleArg(&instance->config.media); - initModuleArg(&instance->config.dateTime); - initModuleArg(&instance->config.date); - initModuleArg(&instance->config.time); - initModuleArg(&instance->config.vulkan); - initModuleArg(&instance->config.wallpaper); - initModuleArg(&instance->config.openGL); - initModuleArg(&instance->config.openCL); - initModuleArg(&instance->config.users); - initModuleArg(&instance->config.bluetooth); - initModuleArg(&instance->config.sound); - initModuleArg(&instance->config.gamepad); - - ffStrbufInitA(&instance->config.libPCI, 0); - ffStrbufInitA(&instance->config.libVulkan, 0); - ffStrbufInitA(&instance->config.libWayland, 0); - ffStrbufInitA(&instance->config.libXcbRandr, 0); - ffStrbufInitA(&instance->config.libXcb, 0); - ffStrbufInitA(&instance->config.libXrandr, 0); - ffStrbufInitA(&instance->config.libX11, 0); - ffStrbufInitA(&instance->config.libGIO, 0); - ffStrbufInitA(&instance->config.libDConf, 0); - ffStrbufInitA(&instance->config.libDBus, 0); - ffStrbufInitA(&instance->config.libXFConf, 0); - ffStrbufInitA(&instance->config.libSQLite3, 0); - ffStrbufInitA(&instance->config.librpm, 0); - ffStrbufInitA(&instance->config.libImageMagick, 0); - ffStrbufInitA(&instance->config.libZ, 0); - ffStrbufInitA(&instance->config.libChafa, 0); - ffStrbufInitA(&instance->config.libEGL, 0); - ffStrbufInitA(&instance->config.libGLX, 0); - ffStrbufInitA(&instance->config.libOSMesa, 0); - ffStrbufInitA(&instance->config.libOpenCL, 0); - ffStrbufInitA(&instance->config.libcJSON, 0); - ffStrbufInitA(&instance->config.libfreetype, 0); - ffStrbufInit(&instance->config.libPulse); - ffStrbufInit(&instance->config.libwlanapi); - ffStrbufInit(&instance->config.libnm); - - instance->config.cpuTemp = false; - instance->config.gpuTemp = false; - instance->config.gpuForceVulkan = false; - instance->config.batteryTemp = false; - - instance->config.gpuHideIntegrated = false; - instance->config.gpuHideDiscrete = false; - - instance->config.shellVersion = true; - instance->config.terminalVersion = true; - - instance->config.titleFQDN = false; - - ffStrbufInitA(&instance->config.diskFolders, 0); - instance->config.diskShowTypes = FF_DISK_TYPE_REGULAR_BIT | FF_DISK_TYPE_EXTERNAL_BIT; - - instance->config.displayCompactType = FF_DISPLAY_COMPACT_TYPE_NONE; - instance->config.displayDetectName = false; - instance->config.displayPreciseRefreshRate = false; - - instance->config.bluetoothShowDisconnected = false; - - instance->config.soundType = FF_SOUND_TYPE_MAIN; - - ffStrbufInitA(&instance->config.batteryDir, 0); - - ffStrbufInitA(&instance->config.separatorString, 0); - - instance->config.localIpShowType = FF_LOCALIP_TYPE_IPV4_BIT; - ffStrbufInit(&instance->config.localIpNamePrefix); - - instance->config.publicIpTimeout = 0; - ffStrbufInit(&instance->config.publicIpUrl); - - instance->config.weatherTimeout = 0; - ffStrbufInitS(&instance->config.weatherOutputFormat, "%t+-+%C+(%l)"); - - ffStrbufInitA(&instance->config.osFile, 0); - - ffStrbufInitA(&instance->config.playerName, 0); - - instance->config.percentType = 1; - - ffStrbufInitS(&instance->config.commandShell, - #ifdef _WIN32 - "cmd" - #elif defined(__FreeBSD__) - "csh" - #else - "bash" - #endif - ); - ffListInit(&instance->config.commandKeys, sizeof(FFstrbuf)); - ffListInit(&instance->config.commandTexts, sizeof(FFstrbuf)); + instance.config.showErrors = false; + instance.config.recache = false; + instance.config.allowSlowOperations = false; + instance.config.pipe = !isatty(STDOUT_FILENO); + + #ifdef NDEBUG + instance.config.disableLinewrap = !instance.config.pipe; + instance.config.hideCursor = !instance.config.pipe; + #else + instance.config.disableLinewrap = false; + instance.config.hideCursor = false; + #endif + + instance.config.escapeBedrock = true; + instance.config.binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC; + instance.config.sizeNdigits = 2; + instance.config.sizeMaxPrefix = UINT8_MAX; + instance.config.temperatureUnit = FF_TEMPERATURE_UNIT_CELSIUS; + instance.config.multithreading = true; + instance.config.stat = false; + instance.config.noBuffer = false; + + ffInitTitleOptions(&instance.config.title); + ffInitOSOptions(&instance.config.os); + ffInitHostOptions(&instance.config.host); + ffInitBiosOptions(&instance.config.bios); + ffInitBoardOptions(&instance.config.board); + ffInitBrightnessOptions(&instance.config.brightness); + ffInitChassisOptions(&instance.config.chassis); + ffInitCommandOptions(&instance.config.command); + ffInitCustomOptions(&instance.config.custom); + ffInitKernelOptions(&instance.config.kernel); + ffInitUptimeOptions(&instance.config.uptime); + ffInitProcessesOptions(&instance.config.processes); + ffInitPackagesOptions(&instance.config.packages); + ffInitShellOptions(&instance.config.shell); + ffInitDisplayOptions(&instance.config.display); + ffInitDEOptions(&instance.config.de); + ffInitWMOptions(&instance.config.wm); + ffInitWMThemeOptions(&instance.config.wmTheme); + ffInitThemeOptions(&instance.config.theme); + ffInitIconsOptions(&instance.config.icons); + ffInitFontOptions(&instance.config.font); + ffInitCursorOptions(&instance.config.cursor); + ffInitTerminalOptions(&instance.config.terminal); + ffInitTerminalFontOptions(&instance.config.terminalFont); + ffInitCPUOptions(&instance.config.cpu); + ffInitCPUUsageOptions(&instance.config.cpuUsage); + ffInitGPUOptions(&instance.config.gpu); + ffInitMemoryOptions(&instance.config.memory); + ffInitSwapOptions(&instance.config.swap); + ffInitDiskOptions(&instance.config.disk); + ffInitBatteryOptions(&instance.config.battery); + ffInitPowerAdapterOptions(&instance.config.powerAdapter); + ffInitLMOptions(&instance.config.lm); + ffInitLocaleOptions(&instance.config.locale); + ffInitLocalIpOptions(&instance.config.localIP); + ffInitPublicIpOptions(&instance.config.publicIP); + ffInitWeatherOptions(&instance.config.weather); + ffInitWifiOptions(&instance.config.wifi); + ffInitPlayerOptions(&instance.config.player); + ffInitMediaOptions(&instance.config.media); + ffInitDateTimeOptions(&instance.config.dateTime); + ffInitVulkanOptions(&instance.config.vulkan); + ffInitWallpaperOptions(&instance.config.wallpaper); + ffInitOpenGLOptions(&instance.config.openGL); + ffInitOpenCLOptions(&instance.config.openCL); + ffInitUsersOptions(&instance.config.users); + ffInitBluetoothOptions(&instance.config.bluetooth); + ffInitSoundOptions(&instance.config.sound); + ffInitSeparatorOptions(&instance.config.separator); + ffInitGamepadOptions(&instance.config.gamepad); + ffInitColorsOptions(&instance.config.colors); + + ffStrbufInit(&instance.config.libPCI); + ffStrbufInit(&instance.config.libVulkan); + ffStrbufInit(&instance.config.libWayland); + ffStrbufInit(&instance.config.libXcbRandr); + ffStrbufInit(&instance.config.libXcb); + ffStrbufInit(&instance.config.libXrandr); + ffStrbufInit(&instance.config.libX11); + ffStrbufInit(&instance.config.libGIO); + ffStrbufInit(&instance.config.libDConf); + ffStrbufInit(&instance.config.libDBus); + ffStrbufInit(&instance.config.libXFConf); + ffStrbufInit(&instance.config.libSQLite3); + ffStrbufInit(&instance.config.librpm); + ffStrbufInit(&instance.config.libImageMagick); + ffStrbufInit(&instance.config.libZ); + ffStrbufInit(&instance.config.libChafa); + ffStrbufInit(&instance.config.libEGL); + ffStrbufInit(&instance.config.libGLX); + ffStrbufInit(&instance.config.libOSMesa); + ffStrbufInit(&instance.config.libOpenCL); + ffStrbufInit(&instance.config.libfreetype); + ffStrbufInit(&instance.config.libPulse); + ffStrbufInit(&instance.config.libnm); + ffStrbufInit(&instance.config.libDdcutil); + + instance.config.percentType = 1; } -void ffInitInstance(FFinstance* instance) +void ffInitInstance(void) { #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"); + #else + // used for mbsrtowcs in Module `separator` + setlocale(LC_ALL, ""); #endif - initState(&instance->state); - defaultConfig(instance); + initState(&instance.state); + defaultConfig(); } #if defined(FF_HAVE_THREADS) && !(defined(__APPLE__) || defined(_WIN32) || defined(__ANDROID__)) @@ -216,19 +169,19 @@ void ffInitInstance(FFinstance* instance) #define FF_START_DETECTION_THREADS -FF_THREAD_ENTRY_DECL_WRAPPER(ffConnectDisplayServer, FFinstance*) -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*) +FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffConnectDisplayServer) +FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectQt) +FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK2) +FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK3) +FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK4) -void startDetectionThreads(FFinstance* instance) +void startDetectionThreads(void) { - ffThreadDetach(ffThreadCreate(ffConnectDisplayServerThreadMain, instance)); - ffThreadDetach(ffThreadCreate(ffDetectQtThreadMain, instance)); - ffThreadDetach(ffThreadCreate(ffDetectGTK2ThreadMain, instance)); - ffThreadDetach(ffThreadCreate(ffDetectGTK3ThreadMain, instance)); - ffThreadDetach(ffThreadCreate(ffDetectGTK4ThreadMain, instance)); + ffThreadDetach(ffThreadCreate(ffConnectDisplayServerThreadMain, NULL)); + ffThreadDetach(ffThreadCreate(ffDetectQtThreadMain, NULL)); + ffThreadDetach(ffThreadCreate(ffDetectGTK2ThreadMain, NULL)); + ffThreadDetach(ffThreadCreate(ffDetectGTK3ThreadMain, NULL)); + ffThreadDetach(ffThreadCreate(ffDetectGTK4ThreadMain, NULL)); } #endif //FF_HAVE_THREADS @@ -236,7 +189,7 @@ void startDetectionThreads(FFinstance* instance) static volatile bool ffDisableLinewrap = true; static volatile bool ffHideCursor = true; -static void resetConsole() +static void resetConsole(void) { if(ffDisableLinewrap) fputs("\033[?7h", stdout); @@ -244,7 +197,7 @@ static void resetConsole() if(ffHideCursor) fputs("\033[?25h", stdout); - #if defined(_WIN32) && defined(FF_ENABLE_BUFFER) + #if defined(_WIN32) fflush(stdout); #endif } @@ -265,20 +218,18 @@ static void exitSignalHandler(int signal) } #endif -void ffStart(FFinstance* instance) +void ffStart(void) { #ifdef FF_START_DETECTION_THREADS - if(instance->config.multithreading) - startDetectionThreads(instance); + if(instance.config.multithreading) + startDetectionThreads(); #endif - ffDisableLinewrap = instance->config.disableLinewrap && !instance->config.pipe; - ffHideCursor = instance->config.hideCursor && !instance->config.pipe; + ffDisableLinewrap = instance.config.disableLinewrap && !instance.config.pipe; + ffHideCursor = instance.config.hideCursor && !instance.config.pipe; #ifdef _WIN32 - #ifdef FF_ENABLE_BUFFER - setvbuf(stdout, NULL, _IOFBF, 4096); - #endif + if (!instance.config.noBuffer) setvbuf(stdout, NULL, _IOFBF, 4096); SetConsoleCtrlHandler(consoleHandler, TRUE); HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); DWORD mode = 0; @@ -286,9 +237,7 @@ void ffStart(FFinstance* instance) SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING); SetConsoleOutputCP(CP_UTF8); #else - #ifndef FF_ENABLE_BUFFER - setvbuf(stdout, NULL, _IONBF, 0); - #endif + if (instance.config.noBuffer) setvbuf(stdout, NULL, _IONBF, 0); struct sigaction action = { .sa_handler = exitSignalHandler }; sigaction(SIGINT, &action, NULL); sigaction(SIGTERM, &action, NULL); @@ -296,7 +245,7 @@ void ffStart(FFinstance* instance) #endif //reset everything to default before we start printing - if(!instance->config.pipe) + if(!instance.config.pipe) fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); if(ffHideCursor) @@ -305,138 +254,122 @@ void ffStart(FFinstance* instance) if(ffDisableLinewrap) fputs("\033[?7l", stdout); - ffLogoPrint(instance); + ffLogoPrint(); } -void ffFinish(FFinstance* instance) +void ffFinish(void) { - if(instance->config.logo.printRemaining) - ffLogoPrintRemaining(instance); + if(instance.config.logo.printRemaining) + ffLogoPrintRemaining(); resetConsole(); } -static void destroyModuleArg(FFModuleArgs* args) +static void destroyConfig(void) { - ffStrbufDestroy(&args->key); - ffStrbufDestroy(&args->outputFormat); - ffStrbufDestroy(&args->errorFormat); -} + ffDestroyLogoOptions(&instance.config.logo); -static void destroyConfig(FFinstance* instance) -{ - ffStrbufDestroy(&instance->config.logo.source); - ffStrbufDestroy(&instance->config.logo.chafaSymbols); - for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i) - ffStrbufDestroy(&instance->config.logo.colors[i]); - ffStrbufDestroy(&instance->config.colorKeys); - ffStrbufDestroy(&instance->config.colorTitle); - ffStrbufDestroy(&instance->config.separator); - - destroyModuleArg(&instance->config.os); - destroyModuleArg(&instance->config.host); - destroyModuleArg(&instance->config.bios); - destroyModuleArg(&instance->config.board); - destroyModuleArg(&instance->config.chassis); - destroyModuleArg(&instance->config.kernel); - destroyModuleArg(&instance->config.uptime); - destroyModuleArg(&instance->config.processes); - destroyModuleArg(&instance->config.packages); - destroyModuleArg(&instance->config.shell); - destroyModuleArg(&instance->config.display); - destroyModuleArg(&instance->config.de); - destroyModuleArg(&instance->config.wm); - destroyModuleArg(&instance->config.wmTheme); - destroyModuleArg(&instance->config.theme); - destroyModuleArg(&instance->config.icons); - destroyModuleArg(&instance->config.font); - destroyModuleArg(&instance->config.cursor); - destroyModuleArg(&instance->config.terminal); - destroyModuleArg(&instance->config.terminalFont); - destroyModuleArg(&instance->config.cpu); - destroyModuleArg(&instance->config.cpuUsage); - destroyModuleArg(&instance->config.gpu); - destroyModuleArg(&instance->config.memory); - destroyModuleArg(&instance->config.swap); - destroyModuleArg(&instance->config.disk); - destroyModuleArg(&instance->config.battery); - destroyModuleArg(&instance->config.powerAdapter); - destroyModuleArg(&instance->config.locale); - destroyModuleArg(&instance->config.localIP); - destroyModuleArg(&instance->config.publicIP); - destroyModuleArg(&instance->config.wallpaper); - destroyModuleArg(&instance->config.weather); - destroyModuleArg(&instance->config.wifi); - destroyModuleArg(&instance->config.player); - destroyModuleArg(&instance->config.media); - destroyModuleArg(&instance->config.dateTime); - destroyModuleArg(&instance->config.date); - destroyModuleArg(&instance->config.time); - destroyModuleArg(&instance->config.vulkan); - destroyModuleArg(&instance->config.openGL); - destroyModuleArg(&instance->config.openCL); - destroyModuleArg(&instance->config.users); - destroyModuleArg(&instance->config.bluetooth); - destroyModuleArg(&instance->config.sound); - destroyModuleArg(&instance->config.gamepad); - - ffStrbufDestroy(&instance->config.libPCI); - ffStrbufDestroy(&instance->config.libVulkan); - ffStrbufDestroy(&instance->config.libWayland); - ffStrbufDestroy(&instance->config.libXcbRandr); - ffStrbufDestroy(&instance->config.libXcb); - ffStrbufDestroy(&instance->config.libXrandr); - ffStrbufDestroy(&instance->config.libX11); - ffStrbufDestroy(&instance->config.libGIO); - ffStrbufDestroy(&instance->config.libDConf); - ffStrbufDestroy(&instance->config.libDBus); - ffStrbufDestroy(&instance->config.libXFConf); - ffStrbufDestroy(&instance->config.libSQLite3); - ffStrbufDestroy(&instance->config.librpm); - ffStrbufDestroy(&instance->config.libImageMagick); - ffStrbufDestroy(&instance->config.libZ); - ffStrbufDestroy(&instance->config.libChafa); - ffStrbufDestroy(&instance->config.libEGL); - ffStrbufDestroy(&instance->config.libGLX); - ffStrbufDestroy(&instance->config.libOSMesa); - ffStrbufDestroy(&instance->config.libOpenCL); - ffStrbufDestroy(&instance->config.libcJSON); - ffStrbufDestroy(&instance->config.libfreetype); - ffStrbufDestroy(&instance->config.libPulse); - ffStrbufDestroy(&instance->config.libwlanapi); - ffStrbufDestroy(&instance->config.libnm); - - ffStrbufDestroy(&instance->config.diskFolders); - ffStrbufDestroy(&instance->config.batteryDir); - ffStrbufDestroy(&instance->config.separatorString); - ffStrbufDestroy(&instance->config.localIpNamePrefix); - ffStrbufDestroy(&instance->config.publicIpUrl); - ffStrbufDestroy(&instance->config.weatherOutputFormat); - ffStrbufDestroy(&instance->config.osFile); - ffStrbufDestroy(&instance->config.playerName); - - ffStrbufDestroy(&instance->config.commandShell); - FF_LIST_FOR_EACH(FFstrbuf, item, instance->config.commandKeys) - ffStrbufDestroy(item); - ffListDestroy(&instance->config.commandKeys); - FF_LIST_FOR_EACH(FFstrbuf, item, instance->config.commandTexts) - ffStrbufDestroy(item); - ffListDestroy(&instance->config.commandTexts); + ffStrbufDestroy(&instance.config.colorKeys); + ffStrbufDestroy(&instance.config.colorTitle); + ffStrbufDestroy(&instance.config.keyValueSeparator); + + #if defined(__linux__) || defined(__FreeBSD__) + ffStrbufDestroy(&instance.config.playerName); + ffStrbufDestroy(&instance.config.osFile); + #endif + + ffDestroyTitleOptions(&instance.config.title); + ffDestroyOSOptions(&instance.config.os); + ffDestroyHostOptions(&instance.config.host); + ffDestroyBiosOptions(&instance.config.bios); + ffDestroyBoardOptions(&instance.config.board); + ffDestroyBrightnessOptions(&instance.config.brightness); + ffDestroyChassisOptions(&instance.config.chassis); + ffDestroyCommandOptions(&instance.config.command); + ffDestroyCustomOptions(&instance.config.custom); + ffDestroyKernelOptions(&instance.config.kernel); + ffDestroyUptimeOptions(&instance.config.uptime); + ffDestroyProcessesOptions(&instance.config.processes); + ffDestroyPackagesOptions(&instance.config.packages); + ffDestroyShellOptions(&instance.config.shell); + ffDestroyDisplayOptions(&instance.config.display); + ffDestroyDEOptions(&instance.config.de); + ffDestroyWMOptions(&instance.config.wm); + ffDestroyWMThemeOptions(&instance.config.wmTheme); + ffDestroyThemeOptions(&instance.config.theme); + ffDestroyIconsOptions(&instance.config.icons); + ffDestroyFontOptions(&instance.config.font); + ffDestroyCursorOptions(&instance.config.cursor); + ffDestroyTerminalOptions(&instance.config.terminal); + ffDestroyTerminalFontOptions(&instance.config.terminalFont); + ffDestroyCPUOptions(&instance.config.cpu); + ffDestroyCPUUsageOptions(&instance.config.cpuUsage); + ffDestroyGPUOptions(&instance.config.gpu); + ffDestroyMemoryOptions(&instance.config.memory); + ffDestroySwapOptions(&instance.config.swap); + ffDestroyDiskOptions(&instance.config.disk); + ffDestroyBatteryOptions(&instance.config.battery); + ffDestroyPowerAdapterOptions(&instance.config.powerAdapter); + ffDestroyLMOptions(&instance.config.lm); + ffDestroyLocaleOptions(&instance.config.locale); + ffDestroyLocalIpOptions(&instance.config.localIP); + ffDestroyPublicIpOptions(&instance.config.publicIP); + ffDestroyWallpaperOptions(&instance.config.wallpaper); + ffDestroyWeatherOptions(&instance.config.weather); + ffDestroyWifiOptions(&instance.config.wifi); + ffDestroyPlayerOptions(&instance.config.player); + ffDestroyMediaOptions(&instance.config.media); + ffDestroyDateTimeOptions(&instance.config.dateTime); + ffDestroyVulkanOptions(&instance.config.vulkan); + ffDestroyOpenGLOptions(&instance.config.openGL); + ffDestroyOpenCLOptions(&instance.config.openCL); + ffDestroyUsersOptions(&instance.config.users); + ffDestroyBluetoothOptions(&instance.config.bluetooth); + ffDestroySeparatorOptions(&instance.config.separator); + ffDestroySoundOptions(&instance.config.sound); + ffDestroyGamepadOptions(&instance.config.gamepad); + ffDestroyColorsOptions(&instance.config.colors); + + ffStrbufDestroy(&instance.config.libPCI); + ffStrbufDestroy(&instance.config.libVulkan); + ffStrbufDestroy(&instance.config.libWayland); + ffStrbufDestroy(&instance.config.libXcbRandr); + ffStrbufDestroy(&instance.config.libXcb); + ffStrbufDestroy(&instance.config.libXrandr); + ffStrbufDestroy(&instance.config.libX11); + ffStrbufDestroy(&instance.config.libGIO); + ffStrbufDestroy(&instance.config.libDConf); + ffStrbufDestroy(&instance.config.libDBus); + ffStrbufDestroy(&instance.config.libXFConf); + ffStrbufDestroy(&instance.config.libSQLite3); + ffStrbufDestroy(&instance.config.librpm); + ffStrbufDestroy(&instance.config.libImageMagick); + ffStrbufDestroy(&instance.config.libZ); + ffStrbufDestroy(&instance.config.libChafa); + ffStrbufDestroy(&instance.config.libEGL); + ffStrbufDestroy(&instance.config.libGLX); + ffStrbufDestroy(&instance.config.libOSMesa); + ffStrbufDestroy(&instance.config.libOpenCL); + ffStrbufDestroy(&instance.config.libfreetype); + ffStrbufDestroy(&instance.config.libPulse); + ffStrbufDestroy(&instance.config.libnm); + ffStrbufDestroy(&instance.config.libDdcutil); } -static void destroyState(FFinstance* instance) +static void destroyState(void) { - ffPlatformDestroy(&instance->state.platform); + ffPlatformDestroy(&instance.state.platform); + yyjson_doc_free(instance.state.configDoc); } -void ffDestroyInstance(FFinstance* instance) +void ffDestroyInstance(void) { - destroyConfig(instance); - destroyState(instance); + destroyConfig(); + destroyState(); } //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 ffListFeatures(void) { fputs( #ifdef FF_HAVE_THREADS @@ -505,9 +438,6 @@ void ffListFeatures() #ifdef FF_HAVE_OPENCL "opencl\n" #endif - #ifdef FF_HAVE_LIBCJSON - "libcjson\n" - #endif #ifdef FF_HAVE_FREETYPE "freetype\n" #endif @@ -517,6 +447,9 @@ void ffListFeatures() #ifdef FF_HAVE_LIBNM "libnm\n" #endif + #ifdef FF_HAVE_DDCUTIL + "libddcutil\n" + #endif "" , stdout); } diff --git a/src/common/io/io.h b/src/common/io/io.h index e28a9b3c0c..8cca6e1475 100644 --- a/src/common/io/io.h +++ b/src/common/io/io.h @@ -82,11 +82,10 @@ typedef enum FFPathType #define FF_PATHTYPE_ANY (FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY) bool ffPathExists(const char* path, FFPathType pathType); +bool ffPathExpandEnv(const char* in, FFstrbuf* out); -#ifndef _WIN32 - FF_C_SCANF(2, 3) - void ffGetTerminalResponse(const char* request, const char* format, ...); -#endif +FF_C_SCANF(2, 3) +const char* ffGetTerminalResponse(const char* request, const char* format, ...); // Not thread safe! bool ffSuppressIO(bool suppress); diff --git a/src/common/io/io_unix.c b/src/common/io/io_unix.c index 420e4374e1..d1e635e114 100644 --- a/src/common/io/io_unix.c +++ b/src/common/io/io_unix.c @@ -1,15 +1,16 @@ #include "io.h" +#include "util/stringUtils.h" #include #include #include #include #include +#include static void createSubfolders(const char* fileName) { - FFstrbuf path; - ffStrbufInit(&path); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); while(*fileName != '\0') { @@ -18,8 +19,6 @@ static void createSubfolders(const char* fileName) mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH); ++fileName; } - - ffStrbufDestroy(&path); } bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) @@ -109,30 +108,43 @@ bool ffPathExists(const char* path, FFPathType type) return false; } -void ffGetTerminalResponse(const char* request, const char* format, ...) +bool ffPathExpandEnv(const char* in, FFstrbuf* out) +{ + bool result = false; + wordexp_t exp; + if(wordexp(in, &exp, WRDE_NOCMD) != 0) + return false; + + if (exp.we_wordc == 1) + { + result = true; + ffStrbufSetS(out, exp.we_wordv[0]); + } + + wordfree(&exp); + + return result; +} + +const char* ffGetTerminalResponse(const char* request, const char* format, ...) { struct termios oldTerm, newTerm; if(tcgetattr(STDIN_FILENO, &oldTerm) == -1) - return; + return "tcgetattr(STDIN_FILENO, &oldTerm) failed"; newTerm = oldTerm; newTerm.c_lflag &= (tcflag_t) ~(ICANON | ECHO); if(tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) == -1) - return; + return "tcsetattr(STDIN_FILENO, TCSANOW, &newTerm)"; fputs(request, stdout); fflush(stdout); - struct pollfd pfd; - pfd.fd = STDIN_FILENO; - pfd.events = POLLIN; - pfd.revents = 0; - //Give the terminal 35ms to respond - if(poll(&pfd, 1, 35) <= 0) + if(poll(&(struct pollfd) { .fd = STDIN_FILENO, .events = POLLIN }, 1, 35) <= 0) { tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm); - return; + return "poll() timeout or failed"; } char buffer[512]; @@ -141,7 +153,7 @@ void ffGetTerminalResponse(const char* request, const char* format, ...) tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm); if(readed <= 0) - return; + return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed"; buffer[readed] = '\0'; @@ -149,6 +161,8 @@ void ffGetTerminalResponse(const char* request, const char* format, ...) va_start(args, format); vsscanf(buffer, format, args); va_end(args); + + return NULL; } bool ffSuppressIO(bool suppress) @@ -197,7 +211,7 @@ void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* fol { if(entry->d_type == DT_DIR) { - if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, "..")) continue; ffStrbufAppendS(folder, entry->d_name); @@ -218,9 +232,7 @@ void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* fol void ffListFilesRecursively(const char* path) { - FFstrbuf folder; - ffStrbufInitS(&folder, path); + FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path); ffStrbufEnsureEndsWithC(&folder, '/'); listFilesRecursively(&folder, 0, NULL); - ffStrbufDestroy(&folder); } diff --git a/src/common/io/io_windows.c b/src/common/io/io_windows.c index 78cdad7404..2cd916bd8d 100644 --- a/src/common/io/io_windows.c +++ b/src/common/io/io_windows.c @@ -1,10 +1,11 @@ #include "io.h" +#include "util/stringUtils.h" + +#include static void createSubfolders(const char* fileName) { - FF_STRBUF_AUTO_DESTROY path; - ffStrbufInit(&path); - + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); while(*fileName != '\0') { ffStrbufAppendC(&path, *fileName); @@ -97,6 +98,18 @@ bool ffPathExists(const char* path, FFPathType type) return false; } +bool ffPathExpandEnv(const char* in, FFstrbuf* out) +{ + DWORD length = ExpandEnvironmentStringsA(in, NULL, 0); + if (length <= 1) return false; + + ffStrbufClear(out); + ffStrbufEnsureFree(out, (uint32_t)length); + ExpandEnvironmentStringsA(in, out->chars, length); + out->length = (uint32_t)length - 1; + return true; +} + bool ffSuppressIO(bool suppress) { (void) suppress; //Not implemented. @@ -120,7 +133,7 @@ void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* fol { if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - if(strcmp(entry.cFileName, ".") == 0 || strcmp(entry.cFileName, "..") == 0) + if(ffStrEquals(entry.cFileName, ".") || ffStrEquals(entry.cFileName, "..")) continue; ffStrbufSubstrBefore(folder, folderLength); @@ -141,9 +154,62 @@ void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* fol void ffListFilesRecursively(const char* path) { - FFstrbuf folder; - ffStrbufInitS(&folder, path); + FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path); ffStrbufEnsureEndsWithC(&folder, '/'); listFilesRecursively(&folder, 0, NULL); - ffStrbufDestroy(&folder); +} + +const char* ffGetTerminalResponse(const char* request, const char* format, ...) +{ + HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); + DWORD prev_mode; + GetConsoleMode(hInput, &prev_mode); + SetConsoleMode(hInput, 0); + + FlushConsoleInputBuffer(hInput); + + DWORD bytes = 0; + WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), request, (DWORD) strlen(request), &bytes, NULL); + + while (true) + { + if (WaitForSingleObjectEx(hInput, 35, TRUE) != WAIT_OBJECT_0) + { + SetConsoleMode(hInput, prev_mode); + return "WaitForSingleObject() failed or timeout"; + } + + // Ignore all unexpected input events + INPUT_RECORD record; + DWORD len = 0; + if (!PeekConsoleInputW(hInput, &record, 1, &len)) + break; + + if ( + record.EventType == KEY_EVENT && + record.Event.KeyEvent.uChar.UnicodeChar != L'\r' && + record.Event.KeyEvent.uChar.UnicodeChar != L'\n' + ) + break; + else + ReadConsoleInputW(hInput, &record, 1, &len); + } + + char buffer[512]; + bytes = 0; + ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL); + + SetConsoleMode(hInput, prev_mode); + + if(bytes <= 0) + return "ReadFile() failed"; + + buffer[bytes] = '\0'; + + va_list args; + va_start(args, format); + vsscanf(buffer, format, args); + va_end(args); + + return NULL; } diff --git a/src/common/jsonconfig.c b/src/common/jsonconfig.c new file mode 100644 index 0000000000..7b623d7c57 --- /dev/null +++ b/src/common/jsonconfig.c @@ -0,0 +1,523 @@ +#include "fastfetch.h" +#include "common/jsonconfig.h" +#include "common/printing.h" +#include "common/io/io.h" +#include "common/time.h" +#include "modules/modules.h" +#include "util/stringUtils.h" + +#include +#include +#include + +bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs* moduleArgs) +{ + if(ffStrEqualsIgnCase(key, "key")) + { + ffStrbufSetNS(&moduleArgs->key, (uint32_t) yyjson_get_len(val), yyjson_get_str(val)); + return true; + } + else if(ffStrEqualsIgnCase(key, "keyColor")) + { + ffOptionParseColor(yyjson_get_str(val), &moduleArgs->keyColor); + return true; + } + else if(ffStrEqualsIgnCase(key, "format")) + { + ffStrbufSetNS(&moduleArgs->outputFormat, (uint32_t) yyjson_get_len(val), yyjson_get_str(val)); + return true; + } + return false; +} + +const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]) +{ + if (yyjson_is_int(val)) + { + int intVal = yyjson_get_int(val); + + for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) + { + if (intVal == pPair->value) + { + *result = pPair->value; + return NULL; + } + } + + return "Invalid enum integer"; + } + else if (yyjson_is_str(val)) + { + const char* strVal = yyjson_get_str(val); + for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) + { + if (ffStrEqualsIgnCase(strVal, pPair->key)) + { + *result = pPair->value; + return NULL; + } + } + + return "Invalid enum string"; + } + else + return "Invalid enum value type; must be a string or integer"; +} + +static inline bool tryModule(const char* type, yyjson_val* module, const char* moduleName, void (*const f)(yyjson_val *module)) +{ + if (ffStrEqualsIgnCase(type, moduleName)) + { + f(module); + return true; + } + return false; +} + +static bool parseModuleJsonObject(const char* type, yyjson_val* module) +{ + switch (toupper(type[0])) + { + case 'B': { + return + tryModule(type, module, FF_BATTERY_MODULE_NAME, ffParseBatteryJsonObject) || + tryModule(type, module, FF_BIOS_MODULE_NAME, ffParseBiosJsonObject) || + tryModule(type, module, FF_BLUETOOTH_MODULE_NAME, ffParseBluetoothJsonObject) || + tryModule(type, module, FF_BOARD_MODULE_NAME, ffParseBoardJsonObject) || + tryModule(type, module, FF_BREAK_MODULE_NAME, ffParseBreakJsonObject) || + tryModule(type, module, FF_BRIGHTNESS_MODULE_NAME, ffParseBrightnessJsonObject) || + false; + } + + case 'C': { + return + tryModule(type, module, FF_CHASSIS_MODULE_NAME, ffParseChassisJsonObject) || + tryModule(type, module, FF_COMMAND_MODULE_NAME, ffParseCommandJsonObject) || + tryModule(type, module, FF_COLORS_MODULE_NAME, ffParseColorsJsonObject) || + tryModule(type, module, FF_CPU_MODULE_NAME, ffParseCPUJsonObject) || + tryModule(type, module, FF_CPUUSAGE_MODULE_NAME, ffParseCPUUsageJsonObject) || + tryModule(type, module, FF_CURSOR_MODULE_NAME, ffParseCursorJsonObject) || + tryModule(type, module, FF_CUSTOM_MODULE_NAME, ffParseCustomJsonObject) || + false; + } + + case 'D': { + return + tryModule(type, module, FF_DATETIME_MODULE_NAME, ffParseDateTimeJsonObject) || + tryModule(type, module, FF_DE_MODULE_NAME, ffParseDEJsonObject) || + tryModule(type, module, FF_DISPLAY_MODULE_NAME, ffParseDisplayJsonObject) || + tryModule(type, module, FF_DISK_MODULE_NAME, ffParseDiskJsonObject) || + false; + } + + case 'F': { + return + tryModule(type, module, FF_FONT_MODULE_NAME, ffParseFontJsonObject) || + false; + } + + case 'G': { + return + tryModule(type, module, FF_GAMEPAD_MODULE_NAME, ffParseGamepadJsonObject) || + tryModule(type, module, FF_GPU_MODULE_NAME, ffParseGPUJsonObject) || + false; + } + + case 'H': { + return + tryModule(type, module, FF_HOST_MODULE_NAME, ffParseHostJsonObject) || + false; + } + + case 'I': { + return + tryModule(type, module, FF_ICONS_MODULE_NAME, ffParseIconsJsonObject) || + false; + } + + case 'K': { + return + tryModule(type, module, FF_KERNEL_MODULE_NAME, ffParseKernelJsonObject) || + false; + } + + case 'L': { + return + tryModule(type, module, FF_LM_MODULE_NAME, ffParseLMJsonObject) || + tryModule(type, module, FF_LOCALE_MODULE_NAME, ffParseLocaleJsonObject) || + tryModule(type, module, FF_LOCALIP_MODULE_NAME, ffParseLocalIpJsonObject) || + false; + } + + case 'M': { + return + tryModule(type, module, FF_MEDIA_MODULE_NAME, ffParseMediaJsonObject) || + tryModule(type, module, FF_MEMORY_MODULE_NAME, ffParseMemoryJsonObject) || + tryModule(type, module, FF_MONITOR_MODULE_NAME, ffParseMonitorJsonObject) || + false; + } + + case 'O': { + return + tryModule(type, module, FF_OPENCL_MODULE_NAME, ffParseOpenCLJsonObject) || + tryModule(type, module, FF_OPENGL_MODULE_NAME, ffParseOpenGLJsonObject) || + tryModule(type, module, FF_OS_MODULE_NAME, ffParseOSJsonObject) || + false; + } + + case 'P': { + return + tryModule(type, module, FF_PACKAGES_MODULE_NAME, ffParsePackagesJsonObject) || + tryModule(type, module, FF_PLAYER_MODULE_NAME, ffParsePlayerJsonObject) || + tryModule(type, module, FF_POWERADAPTER_MODULE_NAME, ffParsePowerAdapterJsonObject) || + tryModule(type, module, FF_PROCESSES_MODULE_NAME, ffParseProcessesJsonObject) || + tryModule(type, module, FF_PUBLICIP_MODULE_NAME, ffParsePublicIpJsonObject) || + false; + } + + case 'S': { + return + tryModule(type, module, FF_SEPARATOR_MODULE_NAME, ffParseSeparatorJsonObject) || + tryModule(type, module, FF_SHELL_MODULE_NAME, ffParseShellJsonObject) || + tryModule(type, module, FF_SOUND_MODULE_NAME, ffParseSoundJsonObject) || + tryModule(type, module, FF_SWAP_MODULE_NAME, ffParseSwapJsonObject) || + false; + } + + case 'T': { + return + tryModule(type, module, FF_TERMINAL_MODULE_NAME, ffParseTerminalJsonObject) || + tryModule(type, module, FF_TERMINALFONT_MODULE_NAME, ffParseTerminalFontJsonObject) || + tryModule(type, module, FF_TERMINALSIZE_MODULE_NAME, ffParseTerminalSizeJsonObject) || + tryModule(type, module, FF_TITLE_MODULE_NAME, ffParseTitleJsonObject) || + tryModule(type, module, FF_THEME_MODULE_NAME, ffParseThemeJsonObject) || + false; + } + + case 'U': { + return + tryModule(type, module, FF_UPTIME_MODULE_NAME, ffParseUptimeJsonObject) || + tryModule(type, module, FF_USERS_MODULE_NAME, ffParseUsersJsonObject) || + false; + } + + case 'V': { + return + tryModule(type, module, FF_VULKAN_MODULE_NAME, ffParseVulkanJsonObject) || + false; + } + + case 'W': { + return + tryModule(type, module, FF_WALLPAPER_MODULE_NAME, ffParseWallpaperJsonObject) || + tryModule(type, module, FF_WEATHER_MODULE_NAME, ffParseWeatherJsonObject) || + tryModule(type, module, FF_WM_MODULE_NAME, ffParseWMJsonObject) || + tryModule(type, module, FF_WIFI_MODULE_NAME, ffParseWifiJsonObject) || + tryModule(type, module, FF_WMTHEME_MODULE_NAME, ffParseWMThemeJsonObject) || + false; + } + + default: + return false; + } +} + +static const char* printJsonConfig(void) +{ + yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc); + assert(root); + + if (!yyjson_is_obj(root)) + return "Invalid JSON config format. Root value must be an object"; + + yyjson_val* modules = yyjson_obj_get(root, "modules"); + if (!modules) return NULL; + if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects"; + + yyjson_val* item; + size_t idx, max; + yyjson_arr_foreach(modules, idx, max, item) + { + uint64_t ms = 0; + if(__builtin_expect(instance.config.stat, false)) + ms = ffTimeGetTick(); + + yyjson_val* module = item; + const char* type = yyjson_get_str(module); + if (type) + module = NULL; + else if (yyjson_is_obj(module)) + { + type = yyjson_get_str(yyjson_obj_get(module, "type")); + if (!type) return "module object must contain a \"type\" key ( case sensitive )"; + if (yyjson_obj_size(module) == 1) // contains only Property type + module = NULL; + } + else + return "modules must be an array of strings or objects"; + + if(!parseModuleJsonObject(type, module)) + return "Unknown module type"; + + if(__builtin_expect(instance.config.stat, false)) + { + char str[32]; + int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ffTimeGetTick() - ms); + if(instance.config.pipe) + puts(str); + else + printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load + } + + #if defined(_WIN32) + if (!instance.config.noBuffer) fflush(stdout); + #endif + } + + return NULL; +} + +const char* ffParseGeneralJsonConfig(void) +{ + FFconfig* config = &instance.config; + + yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc); + assert(root); + + if (!yyjson_is_obj(root)) + return "Invalid JSON config format. Root value must be an object"; + + yyjson_val* object = yyjson_obj_get(root, "general"); + if (!object) return NULL; + if (!yyjson_is_obj(object)) return "Property 'general' must be an object"; + + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(object, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + + if (ffStrEqualsIgnCase(key, "allowSlowOperations")) + config->allowSlowOperations = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "thread") || ffStrEqualsIgnCase(key, "multithreading")) + config->multithreading = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "stat")) + { + if ((config->stat = yyjson_get_bool(val))) + config->showErrors = true; + } + else if (ffStrEqualsIgnCase(key, "escapeBedrock")) + config->escapeBedrock = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "pipe")) + config->pipe = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "processingTimeout")) + config->processingTimeout = (int32_t) yyjson_get_int(val); + + #if defined(__linux__) || defined(__FreeBSD__) + else if (ffStrEqualsIgnCase(key, "playerName")) + ffStrbufSetS(&config->playerName, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "osFile")) + ffStrbufSetS(&config->osFile, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "dsForceDrm")) + config->dsForceDrm = yyjson_get_bool(val); + #elif defined(_WIN32) + else if (ffStrEqualsIgnCase(key, "wmiTimeout")) + config->wmiTimeout = (int32_t) yyjson_get_int(val); + #endif + + else + return "Unknown general property"; + } + + return NULL; +} + +const char* ffParseDisplayJsonConfig(void) +{ + FFconfig* config = &instance.config; + + yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc); + assert(root); + + if (!yyjson_is_obj(root)) + return "Invalid JSON config format. Root value must be an object"; + + yyjson_val* object = yyjson_obj_get(root, "display"); + if (!object) return NULL; + if (!yyjson_is_obj(object)) return "Property 'display' must be an object"; + + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(object, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + + if (ffStrEqualsIgnCase(key, "showErrors")) + config->showErrors = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "disableLinewrap")) + config->disableLinewrap = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "hideCursor")) + config->hideCursor = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "separator")) + ffStrbufSetS(&config->keyValueSeparator, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "color")) + { + if (yyjson_is_str(val)) + { + ffOptionParseColor(yyjson_get_str(val), &config->colorKeys); + ffStrbufSet(&config->colorTitle, &config->colorKeys); + } + else if (yyjson_is_obj(val)) + { + const char* colorKeys = yyjson_get_str(yyjson_obj_get(val, "keys")); + if (colorKeys) + ffOptionParseColor(colorKeys, &config->colorKeys); + const char* colorTitle = yyjson_get_str(yyjson_obj_get(val, "title")); + if (colorTitle) + ffOptionParseColor(colorTitle, &config->colorTitle); + } + else + return "display.color must be either a string or an object"; + } + else if (ffStrEqualsIgnCase(key, "brightColor")) + config->brightColor = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "binaryPrefix")) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "iec", FF_BINARY_PREFIX_TYPE_IEC }, + { "si", FF_BINARY_PREFIX_TYPE_SI }, + { "jedec", FF_BINARY_PREFIX_TYPE_JEDEC }, + {}, + }); + if (error) return error; + config->binaryPrefixType = (FFBinaryPrefixType) value; + } + else if (ffStrEqualsIgnCase(key, "sizeNdigits")) + config->sizeNdigits = (uint8_t) yyjson_get_uint(val); + else if (ffStrEqualsIgnCase(key, "sizeMaxPrefix")) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "B", 0 }, + { "kB", 1 }, + { "MB", 2 }, + { "GB", 3 }, + { "TB", 4 }, + { "PB", 5 }, + { "EB", 6 }, + { "ZB", 7 }, + { "YB", 8 }, + {} + }); + if (error) return error; + config->sizeMaxPrefix = (uint8_t) value; + } + else if (ffStrEqualsIgnCase(key, "temperatureUnit")) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "CELSIUS", FF_TEMPERATURE_UNIT_CELSIUS }, + { "C", FF_TEMPERATURE_UNIT_CELSIUS }, + { "FAHRENHEIT", FF_TEMPERATURE_UNIT_FAHRENHEIT }, + { "F", FF_TEMPERATURE_UNIT_FAHRENHEIT }, + { "KELVIN", FF_TEMPERATURE_UNIT_KELVIN }, + { "K", FF_TEMPERATURE_UNIT_KELVIN }, + {}, + }); + if (error) return error; + config->temperatureUnit = (FFTemperatureUnit) value; + } + else if (ffStrEqualsIgnCase(key, "percentType")) + config->percentType = (uint32_t) yyjson_get_uint(val); + else if (ffStrEqualsIgnCase(key, "noBuffer")) + config->noBuffer = yyjson_get_bool(val); + else + return "Unknown display property"; + } + + return NULL; +} + +const char* ffParseLibraryJsonConfig(void) +{ + FFconfig* config = &instance.config; + + yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc); + assert(root); + + if (!yyjson_is_obj(root)) + return "Invalid JSON config format. Root value must be an object"; + + yyjson_val* object = yyjson_obj_get(root, "library"); + if (!object) return NULL; + if (!yyjson_is_obj(object)) return "Property 'library' must be an object"; + + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(object, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + + if (ffStrEqualsIgnCase(key, "pci")) + ffStrbufSetS(&config->libPCI, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "vulkan")) + ffStrbufSetS(&config->libVulkan, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "freetype")) + ffStrbufSetS(&config->libfreetype, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "wayland")) + ffStrbufSetS(&config->libWayland, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "xcbRandr")) + ffStrbufSetS(&config->libXcbRandr, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "xcb")) + ffStrbufSetS(&config->libXcb, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "Xrandr")) + ffStrbufSetS(&config->libXrandr, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "X11")) + ffStrbufSetS(&config->libX11, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "gio")) + ffStrbufSetS(&config->libGIO, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "DConf")) + ffStrbufSetS(&config->libDConf, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "dbus")) + ffStrbufSetS(&config->libDBus, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "XFConf")) + ffStrbufSetS(&config->libXFConf, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "sqlite") || ffStrEqualsIgnCase(key, "sqlite3")) + ffStrbufSetS(&config->libSQLite3, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "rpm")) + ffStrbufSetS(&config->librpm, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "imagemagick")) + ffStrbufSetS(&config->libImageMagick, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "z")) + ffStrbufSetS(&config->libZ, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "chafa")) + ffStrbufSetS(&config->libChafa, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "egl")) + ffStrbufSetS(&config->libEGL, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "glx")) + ffStrbufSetS(&config->libGLX, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "osmesa")) + ffStrbufSetS(&config->libOSMesa, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "opencl")) + ffStrbufSetS(&config->libOpenCL, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "pulse")) + ffStrbufSetS(&config->libPulse, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "nm")) + ffStrbufSetS(&config->libnm, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "ddcutil")) + ffStrbufSetS(&config->libDdcutil, yyjson_get_str(val)); + else + return "Unknown library property"; + } + + return NULL; +} + +void ffPrintJsonConfig(void) +{ + const char* error = printJsonConfig(); + if (error) + ffPrintErrorString("JsonConfig", 0, NULL, NULL, "%s", error); +} diff --git a/src/common/jsonconfig.h b/src/common/jsonconfig.h new file mode 100644 index 0000000000..7cf6a96e0c --- /dev/null +++ b/src/common/jsonconfig.h @@ -0,0 +1,10 @@ +#pragma once + +#include "fastfetch.h" + +bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs* moduleArgs); +const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]); +void ffPrintJsonConfig(); +const char* ffParseGeneralJsonConfig(); +const char* ffParseDisplayJsonConfig(); +const char* ffParseLibraryJsonConfig(); diff --git a/src/common/library.c b/src/common/library.c index e771b8d4d2..7f858e966e 100644 --- a/src/common/library.c +++ b/src/common/library.c @@ -32,8 +32,7 @@ static void* libraryLoad(const char* path, int maxVersion) if(result != NULL || maxVersion < 0) return result; - FFstrbuf pathbuf; - ffStrbufInitA(&pathbuf, 64); + FF_STRBUF_AUTO_DESTROY pathbuf = ffStrbufCreateA(64); ffStrbufAppendS(&pathbuf, path); ffStrbufAppendC(&pathbuf, '.'); @@ -49,8 +48,6 @@ static void* libraryLoad(const char* path, int maxVersion) ffStrbufSubstrBefore(&pathbuf, originalLength); } - ffStrbufDestroy(&pathbuf); - #endif return result; diff --git a/src/common/library.h b/src/common/library.h index 67590ce8f2..1721ea8d33 100644 --- a/src/common/library.h +++ b/src/common/library.h @@ -62,16 +62,16 @@ static inline void ffLibraryUnload(void** handle) __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed"); #define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \ - FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName.ff ## symbolName, symbolName, returnValue); + FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, returnValue); #define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \ - FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName.ff ## symbolName, symbolName, "dlsym " #symbolName " failed"); + FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, "dlsym " #symbolName " failed"); #define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(library, varName, symbolName, alternateName) \ - FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, varName.ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed"); + FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, (varName).ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed"); #define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \ - FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName->ff ## symbolName, symbolName, returnValue); + FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue); void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...); diff --git a/src/common/networking_windows.c b/src/common/networking_windows.c index 5814acc165..4cb0e1d1a3 100644 --- a/src/common/networking_windows.c +++ b/src/common/networking_windows.c @@ -75,8 +75,7 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con } } - FF_STRBUF_AUTO_DESTROY command; - ffStrbufInitA(&command, 64); + FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(64); ffStrbufAppendS(&command, "GET "); ffStrbufAppendS(&command, path); ffStrbufAppendS(&command, " HTTP/1.1\nHost: "); diff --git a/src/common/option.c b/src/common/option.c new file mode 100644 index 0000000000..dc4be709d0 --- /dev/null +++ b/src/common/option.c @@ -0,0 +1,185 @@ +#include "common/option.h" +#include "common/color.h" +#include "util/stringUtils.h" + +// Return start position of the inner key if the argument key belongs to the module specified, NULL otherwise +const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName) +{ + const char* subKey = argumentKey; + if(!(subKey[0] == '-' && subKey[1] == '-')) + return NULL; + + subKey += 2; + uint32_t moduleNameLen = (uint32_t)strlen(moduleName); + if(strncasecmp(subKey, moduleName, moduleNameLen) != 0) + return NULL; + + subKey += moduleNameLen; + + if(subKey[0] == '\0') + return subKey; + + if(subKey[0] != '-') + return NULL; + + subKey += 1; + + return subKey; +} + +bool ffOptionParseModuleArgs(const char* argumentKey, const char* subKey, const char* value, FFModuleArgs* result) +{ + if(ffStrEqualsIgnCase(subKey, "key")) + { + ffOptionParseString(argumentKey, value, &result->key); + return true; + } + else if(ffStrEqualsIgnCase(subKey, "key-color")) + { + if(value == NULL) + { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(477); + } + ffOptionParseColor(value, &result->keyColor); + return true; + } + else if(ffStrEqualsIgnCase(subKey, "format")) + { + ffOptionParseString(argumentKey, value, &result->outputFormat); + return true; + } + return false; +} + +void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer) +{ + if(value == NULL) + { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(477); + } + + ffStrbufSetS(buffer, value); +} + +uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value) +{ + if(value == NULL) + { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(480); + } + + char* end; + uint32_t num = (uint32_t) strtoul(value, &end, 10); + if(*end != '\0') + { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(479); + } + + return num; +} + +int32_t ffOptionParseInt32(const char* argumentKey, const char* value) +{ + if(value == NULL) + { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(480); + } + + char* end; + int32_t num = (int32_t) strtol(value, &end, 10); + if(*end != '\0') + { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(479); + } + + return num; +} + +int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]) +{ + if(requestedKey == NULL) + { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(476); + } + + for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) + { + if(ffStrEqualsIgnCase(requestedKey, pPair->key)) + return pPair->value; + } + + fprintf(stderr, "Error: unknown %s value: %s\n", argumentKey, requestedKey); + exit(478); +} + +bool ffOptionParseBoolean(const char* str) +{ + return ( + !ffStrSet(str) || + ffStrEqualsIgnCase(str, "true") || + ffStrEqualsIgnCase(str, "yes") || + ffStrEqualsIgnCase(str, "on") || + ffStrEqualsIgnCase(str, "1") + ); +} + +void ffOptionParseColor(const char* value, FFstrbuf* buffer) +{ + ffStrbufClear(buffer); + ffStrbufEnsureFree(buffer, 63); + + while(*value != '\0') + { + #define FF_APPEND_COLOR_CODE_COND(prefix, code) \ + if(strncasecmp(value, #prefix, strlen(#prefix)) == 0) { ffStrbufAppendS(buffer, code); value += strlen(#prefix); } + + FF_APPEND_COLOR_CODE_COND(reset_, FF_COLOR_MODE_RESET) + else FF_APPEND_COLOR_CODE_COND(bright_, FF_COLOR_MODE_BOLD) + else FF_APPEND_COLOR_CODE_COND(dim_, FF_COLOR_MODE_DIM) + else FF_APPEND_COLOR_CODE_COND(black, FF_COLOR_FG_BLACK) + else FF_APPEND_COLOR_CODE_COND(red, FF_COLOR_FG_RED) + else FF_APPEND_COLOR_CODE_COND(green, FF_COLOR_FG_GREEN) + else FF_APPEND_COLOR_CODE_COND(yellow, FF_COLOR_FG_YELLOW) + else FF_APPEND_COLOR_CODE_COND(blue, FF_COLOR_FG_BLUE) + else FF_APPEND_COLOR_CODE_COND(magenta, FF_COLOR_FG_MAGENTA) + else FF_APPEND_COLOR_CODE_COND(cyan, FF_COLOR_FG_CYAN) + else FF_APPEND_COLOR_CODE_COND(white, FF_COLOR_FG_WHITE) + else FF_APPEND_COLOR_CODE_COND(default, FF_COLOR_FG_DEFAULT) + else FF_APPEND_COLOR_CODE_COND(light_black, FF_COLOR_FG_LIGHT_BLACK) + else FF_APPEND_COLOR_CODE_COND(light_red, FF_COLOR_FG_LIGHT_RED) + else FF_APPEND_COLOR_CODE_COND(light_green, FF_COLOR_FG_LIGHT_GREEN) + else FF_APPEND_COLOR_CODE_COND(light_yellow, FF_COLOR_FG_LIGHT_YELLOW) + else FF_APPEND_COLOR_CODE_COND(light_blue, FF_COLOR_FG_LIGHT_BLUE) + else FF_APPEND_COLOR_CODE_COND(light_magenta, FF_COLOR_FG_LIGHT_MAGENTA) + else FF_APPEND_COLOR_CODE_COND(light_cyan, FF_COLOR_FG_LIGHT_CYAN) + else FF_APPEND_COLOR_CODE_COND(light_white, FF_COLOR_FG_LIGHT_WHITE) + else + { + ffStrbufAppendC(buffer, *value); + ++value; + } + + #undef FF_APPEND_COLOR_CODE_COND + } +} + +void ffOptionInitModuleArg(FFModuleArgs* args) +{ + ffStrbufInit(&args->key); + ffStrbufInit(&args->keyColor); + ffStrbufInit(&args->outputFormat); +} + +void ffOptionDestroyModuleArg(FFModuleArgs* args) +{ + ffStrbufDestroy(&args->key); + ffStrbufDestroy(&args->keyColor); + ffStrbufDestroy(&args->outputFormat); +} diff --git a/src/common/option.h b/src/common/option.h new file mode 100644 index 0000000000..bbd9565060 --- /dev/null +++ b/src/common/option.h @@ -0,0 +1,27 @@ +#pragma once + +#include "util/FFstrbuf.h" + +typedef struct FFModuleArgs +{ + FFstrbuf key; + FFstrbuf keyColor; + FFstrbuf outputFormat; +} FFModuleArgs; + +typedef struct FFKeyValuePair +{ + const char* key; + int value; +} FFKeyValuePair; + +const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName); +bool ffOptionParseModuleArgs(const char* argumentKey, const char* pkey, const char* value, FFModuleArgs* result); +void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer); +FF_C_NODISCARD uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value); +FF_C_NODISCARD int32_t ffOptionParseInt32(const char* argumentKey, const char* value); +FF_C_NODISCARD int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]); +FF_C_NODISCARD bool ffOptionParseBoolean(const char* str); +void ffOptionParseColor(const char* value, FFstrbuf* buffer); +void ffOptionInitModuleArg(FFModuleArgs* args); +void ffOptionDestroyModuleArg(FFModuleArgs* args); diff --git a/src/common/parsing.c b/src/common/parsing.c index 4bd8c19be6..55a2780fed 100644 --- a/src/common/parsing.c +++ b/src/common/parsing.c @@ -60,12 +60,12 @@ void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty) ffStrbufAppendF(pretty, ".%u", version->patch); } -static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, uint8_t prefixesLength, const char** prefixes) +static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const char** prefixes) { - long double size = (long double) bytes; + double size = (double) bytes; uint8_t counter = 0; - while(size >= base && counter < prefixesLength - 1) + while(size >= base && counter < instance.config.sizeMaxPrefix && prefixes[counter + 1]) { size /= base; counter++; @@ -73,22 +73,43 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, uint8_t p if(counter == 0) ffStrbufAppendF(result, "%"PRIu64" %s", bytes, prefixes[0]); - else if(counter < 3 || (counter == 3 && size < 100.0)) - ffStrbufAppendF(result, "%.2Lf %s", size, prefixes[counter]); else - ffStrbufAppendF(result, "%.0Lf %s", size, prefixes[counter]); + ffStrbufAppendF(result, "%.*f %s", instance.config.sizeNdigits, size, prefixes[counter]); } -void ffParseSize(uint64_t bytes, FFBinaryPrefixType binaryPrefix, FFstrbuf* result) +void ffParseSize(uint64_t bytes, FFstrbuf* result) { - if(binaryPrefix == FF_BINARY_PREFIX_TYPE_IEC) - parseSize(result, bytes, 1024, 5, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB"}); - else if(binaryPrefix == FF_BINARY_PREFIX_TYPE_SI) - parseSize(result, bytes, 1000, 5, (const char*[]) {"B", "kB", "MB", "GB", "TB"}); - else if(binaryPrefix == FF_BINARY_PREFIX_TYPE_JEDEC) - parseSize(result, bytes, 1024, 5, (const char*[]) {"B", "KB", "MB", "GB", "TB"}); - else - parseSize(result, bytes, 1024, 1, (const char*[]) {"B"}); + switch (instance.config.binaryPrefixType) + { + case FF_BINARY_PREFIX_TYPE_IEC: + parseSize(result, bytes, 1024, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", NULL}); + break; + case FF_BINARY_PREFIX_TYPE_SI: + parseSize(result, bytes, 1000, (const char*[]) {"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", NULL}); + break; + case FF_BINARY_PREFIX_TYPE_JEDEC: + parseSize(result, bytes, 1024, (const char*[]) {"B", "KB", "MB", "GB", "TB", NULL}); + break; + default: + parseSize(result, bytes, 1024, (const char*[]) {"B", NULL}); + break; + } +} + +void ffParseTemperature(double celsius, FFstrbuf* buffer) +{ + switch (instance.config.temperatureUnit) + { + case FF_TEMPERATURE_UNIT_CELSIUS: + ffStrbufAppendF(buffer, "%.1f°C", celsius); + break; + case FF_TEMPERATURE_UNIT_FAHRENHEIT: + ffStrbufAppendF(buffer, "%.1f°F", celsius * 1.8 + 32); + break; + case FF_TEMPERATURE_UNIT_KELVIN: + ffStrbufAppendF(buffer, "%.1f K", celsius + 273.15); + break; + } } void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4) diff --git a/src/common/parsing.h b/src/common/parsing.h index 4f8a29c041..deb555c014 100644 --- a/src/common/parsing.h +++ b/src/common/parsing.h @@ -22,6 +22,7 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty); int8_t ffVersionCompare(const FFVersion* version1, const FFVersion* version2); -void ffParseSize(uint64_t bytes, FFBinaryPrefixType binaryPrefix, FFstrbuf* result); +void ffParseSize(uint64_t bytes, FFstrbuf* result); +void ffParseTemperature(double celsius, FFstrbuf* buffer); #endif diff --git a/src/common/printing.c b/src/common/printing.c index f33d5cf338..1ef1a0ea68 100644 --- a/src/common/printing.c +++ b/src/common/printing.c @@ -2,18 +2,24 @@ #include "common/printing.h" #include "util/textModifier.h" -void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat) +void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor) { - ffLogoPrintLine(instance); + ffLogoPrintLine(); //This is used by --set-keyless, in this case we wan't neither the module name nor the separator if(moduleName == NULL) return; - if(!instance->config.pipe) + if(!instance.config.pipe) { - fputs(FASTFETCH_TEXT_MODIFIER_RESET FASTFETCH_TEXT_MODIFIER_BOLT, stdout); - ffPrintColor(&instance->config.colorKeys); + fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); + if (instance.config.brightColor) + fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); + + if(customKeyColor != NULL && customKeyColor->length > 0) + ffPrintColor(customKeyColor); + else + ffPrintColor(&instance.config.colorKeys); } //NULL check is required for modules with custom keys, e.g. disk with the folder path @@ -26,93 +32,71 @@ void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t mod } else { - FFstrbuf key; - ffStrbufInit(&key); + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); ffParseFormatString(&key, customKeyFormat, 1, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex} }); ffPrintUserString(key.chars); - ffStrbufDestroy(&key); } - if(!instance->config.pipe) + if(!instance.config.pipe) fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); - ffStrbufWriteTo(&instance->config.separator, stdout); + ffStrbufWriteTo(&instance.config.keyValueSeparator, stdout); - if(!instance->config.pipe) + if(!instance.config.pipe) fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); } -void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments) +void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments) { - FFstrbuf buffer; - ffStrbufInitA(&buffer, 256); - + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateA(256); ffParseFormatString(&buffer, format, numArgs, arguments); if(buffer.length > 0) { - ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat); + ffPrintLogoAndKey(moduleName, moduleIndex, customKeyFormat, customKeyColor); ffPrintUserString(buffer.chars); putchar('\n'); } - - ffStrbufDestroy(&buffer); } -void ffPrintFormat(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments) +void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments) { - ffPrintFormatString(instance, moduleName, moduleIndex, &moduleArgs->key, &moduleArgs->outputFormat, numArgs, arguments); + ffPrintFormatString(moduleName, moduleIndex, &moduleArgs->key, &moduleArgs->keyColor, &moduleArgs->outputFormat, numArgs, arguments); } -static void printError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, va_list arguments) +static void printError(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor, const char* message, va_list arguments) { - bool hasCustomErrorFormat = customErrorFormat != NULL && customErrorFormat->length > 0; - if(!hasCustomErrorFormat && !instance->config.showErrors) + if(!instance.config.showErrors) return; - if(hasCustomErrorFormat) - { - FFstrbuf error; - ffStrbufInit(&error); - ffStrbufAppendVF(&error, message, arguments); + ffPrintLogoAndKey(moduleName, moduleIndex, customKeyFormat, customKeyColor); - ffPrintFormatString(instance, moduleName, moduleIndex, customKeyFormat, customErrorFormat, 1, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &error} - }); + if(!instance.config.pipe) + fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout); - ffStrbufDestroy(&error); - } - else - { - ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat); - - if(!instance->config.pipe) - fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout); - - vprintf(message, arguments); + vprintf(message, arguments); - if(!instance->config.pipe) - fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); + if(!instance.config.pipe) + fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); - putchar('\n'); - } + putchar('\n'); } -void ffPrintErrorString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, ...) +void ffPrintErrorString(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor, const char* message, ...) { va_list arguments; va_start(arguments, message); - printError(instance, moduleName, moduleIndex, customKeyFormat, customErrorFormat, message, arguments); + printError(moduleName, moduleIndex, customKeyFormat, customKeyColor, message, arguments); va_end(arguments); } -void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...) +void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...) { va_list arguments; va_start(arguments, message); - printError(instance, moduleName, moduleIndex, &moduleArgs->key, &moduleArgs->errorFormat, message, arguments); + printError(moduleName, moduleIndex, &moduleArgs->key, &moduleArgs->keyColor, message, arguments); va_end(arguments); } diff --git a/src/common/printing.h b/src/common/printing.h index 9a734634b7..8019a01cc6 100644 --- a/src/common/printing.h +++ b/src/common/printing.h @@ -6,11 +6,11 @@ #include "fastfetch.h" #include "common/format.h" -void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat); -void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments); -void ffPrintFormat(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments); -FF_C_PRINTF(6, 7) void ffPrintErrorString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, ...); -FF_C_PRINTF(5, 6) void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...); +void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor); +void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments); +void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments); +FF_C_PRINTF(5, 6) void ffPrintErrorString(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor, const char* message, ...); +FF_C_PRINTF(4, 5) void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...); void ffPrintColor(const FFstrbuf* colorValue); void ffPrintCharTimes(char c, uint32_t times); void ffPrintUserString(const char* str); diff --git a/src/common/processing.h b/src/common/processing.h index 51164b0e9d..380c2a36e4 100644 --- a/src/common/processing.h +++ b/src/common/processing.h @@ -5,6 +5,28 @@ #include "util/FFstrbuf.h" -const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]); +const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr); + +static inline const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) +{ + const char* error = ffProcessAppendOutput(buffer, argv, false); + if (!error) + { + ffStrbufTrimRight(buffer, '\n'); + ffStrbufTrimRight(buffer, ' '); + } + return error; +} + +static inline const char* ffProcessAppendStdErr(FFstrbuf* buffer, char* const argv[]) +{ + const char* error = ffProcessAppendOutput(buffer, argv, true); + if (!error) + { + ffStrbufTrimRight(buffer, '\n'); + ffStrbufTrimRight(buffer, ' '); + } + return error; +} #endif diff --git a/src/common/processing_linux.c b/src/common/processing_linux.c index b9bf20c1b7..815ed1fc88 100644 --- a/src/common/processing_linux.c +++ b/src/common/processing_linux.c @@ -1,29 +1,43 @@ #include "fastfetch.h" #include "common/processing.h" #include "common/io/io.h" +#include "common/time.h" #include #include +#include +#include +#include +#include #include -const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) +enum { FF_PIPE_BUFSIZ = 4096 }; + +static inline void waitpid_wrapper(pid_t* pid) +{ + // remove zombie processes + if (*pid > 0) + waitpid(*pid, NULL, 0); +} + +const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr) { int pipes[2]; if(pipe(pipes) == -1) return "pipe() failed"; - pid_t childPid = fork(); + __attribute__((__cleanup__(waitpid_wrapper))) pid_t childPid = fork(); if(childPid == -1) return "fork() failed"; //Child if(childPid == 0) { - dup2(pipes[1], STDOUT_FILENO); + dup2(pipes[1], useStdErr ? STDERR_FILENO : STDOUT_FILENO); close(pipes[0]); close(pipes[1]); - close(STDERR_FILENO); + close(useStdErr ? STDOUT_FILENO : STDERR_FILENO); execvp(argv[0], argv); exit(901); } @@ -32,18 +46,40 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) close(pipes[1]); int FF_AUTO_CLOSE_FD childPipeFd = pipes[0]; - int status = -1; - if(waitpid(childPid, &status, 0) < 0) - return "waitpid(childPid, &status, 0) failed"; - if (!WIFEXITED(status)) - return "WIFEXITED(status) == false"; + int timeout = instance.config.processingTimeout; + if (timeout >= 0) + fcntl(childPipeFd, F_SETFL, fcntl(childPipeFd, F_GETFL) | O_NONBLOCK); - if(WEXITSTATUS(status) == 901) - return "WEXITSTATUS(status) == 901 ( execvp failed )"; + do + { + if (timeout >= 0) + { + struct pollfd pollfd = { childPipeFd, POLLIN, 0 }; + if (poll(&pollfd, 1, timeout) == 0) + { + kill(childPid, SIGTERM); + return "poll(&pollfd, 1, timeout) timeout"; + } + else if (pollfd.revents & POLLERR) + { + kill(childPid, SIGTERM); + return "poll(&pollfd, 1, timeout) error"; + } + } - if(!ffAppendFDBuffer(childPipeFd, buffer)) - return "ffAppendFDBuffer(childPipeFd, buffer) failed"; + char str[FF_PIPE_BUFSIZ]; + while (true) + { + ssize_t nRead = read(childPipeFd, str, FF_PIPE_BUFSIZ); + if (nRead > 0) + ffStrbufAppendNS(buffer, (uint32_t) nRead, str); + else if (nRead == 0) + return NULL; + else if (nRead < 0) + break; + } + } while (errno == EAGAIN); return NULL; } diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index a2db719c1e..6355a3a1f9 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -1,35 +1,59 @@ #include "fastfetch.h" #include "common/processing.h" +#include "common/io/io.h" #include -const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) +enum { FF_PIPE_BUFSIZ = 4096 }; + +const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr) { - SECURITY_ATTRIBUTES saAttr = { - .nLength = sizeof(SECURITY_ATTRIBUTES), - .lpSecurityDescriptor = NULL, - .bInheritHandle = TRUE, - }; + int timeout = instance.config.processingTimeout; - HANDLE hChildStdoutRead, hChildStdoutWrite; - if (!CreatePipe(&hChildStdoutRead, &hChildStdoutWrite, &saAttr, 0)) - return "CreatePipe() failed"; + FF_AUTO_CLOSE_FD HANDLE hChildPipeRead = CreateNamedPipeW( + L"\\\\.\\pipe\\LOCAL\\", + PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | (timeout < 0 ? 0 : FILE_FLAG_OVERLAPPED), + 0, + 1, + FF_PIPE_BUFSIZ, + FF_PIPE_BUFSIZ, + 0, + NULL + ); + if (hChildPipeRead == INVALID_HANDLE_VALUE) + return "CreateNamedPipeW(L\"\\\\.\\pipe\\LOCAL\\\") failed"; - if (!SetHandleInformation(hChildStdoutRead, HANDLE_FLAG_INHERIT, 0)) - return "SetHandleInformation(hChildStdoutRead) failed"; + HANDLE hChildPipeWrite = CreateFileW( + L"\\\\.\\pipe\\LOCAL\\", + GENERIC_WRITE, + 0, + &(SECURITY_ATTRIBUTES){ + .nLength = sizeof(SECURITY_ATTRIBUTES), + .lpSecurityDescriptor = NULL, + .bInheritHandle = TRUE, + }, + OPEN_EXISTING, + 0, + NULL + ); + if (hChildPipeWrite == INVALID_HANDLE_VALUE) + return "CreateFileW(L\"\\\\.\\pipe\\LOCAL\\\") failed"; PROCESS_INFORMATION piProcInfo = {0}; - STARTUPINFOA siStartInfo = { - .cb = sizeof(siStartInfo), - .dwFlags = STARTF_USESTDHANDLES, - .hStdOutput = hChildStdoutWrite, - }; BOOL success; { - FF_STRBUF_AUTO_DESTROY cmdline; - ffStrbufInitF(&cmdline, "\"%s\"", argv[0]); + STARTUPINFOA siStartInfo = { + .cb = sizeof(siStartInfo), + .dwFlags = STARTF_USESTDHANDLES, + }; + if (useStdErr) + siStartInfo.hStdError = hChildPipeWrite; + else + siStartInfo.hStdOutput = hChildPipeWrite; + + FF_STRBUF_AUTO_DESTROY cmdline = ffStrbufCreateF("\"%s\"", argv[0]); for(char* const* parg = &argv[1]; *parg; ++parg) { ffStrbufAppendC(&cmdline, ' '); @@ -50,18 +74,54 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) ); } - CloseHandle(hChildStdoutWrite); + CloseHandle(hChildPipeWrite); if(!success) - { - CloseHandle(hChildStdoutRead); return "CreateProcessA() failed"; - } - char str[1024]; - DWORD nRead; - while(ReadFile(hChildStdoutRead, str, sizeof(str), &nRead, NULL) && nRead > 0) + FF_AUTO_CLOSE_FD HANDLE hProcess = piProcInfo.hProcess; + FF_MAYBE_UNUSED FF_AUTO_CLOSE_FD HANDLE hThread = piProcInfo.hThread; + + char str[FF_PIPE_BUFSIZ]; + DWORD nRead = 0; + FF_AUTO_CLOSE_FD HANDLE hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + OVERLAPPED overlapped = { .hEvent = hEvent }; + // ReadFile always completes synchronously if the pipe is not created with FILE_FLAG_OVERLAPPED + do + { + if (!ReadFile(hChildPipeRead, str, sizeof(str), &nRead, &overlapped)) + { + switch (GetLastError()) + { + case ERROR_IO_PENDING: + if (!timeout || WaitForSingleObject(hEvent, (DWORD) timeout) != WAIT_OBJECT_0) + { + CancelIo(hChildPipeRead); + TerminateProcess(hProcess, 1); + return "WaitForSingleObject(hEvent) failed or timeout"; + } + + if (!GetOverlappedResult(hChildPipeRead, &overlapped, &nRead, FALSE)) + { + if (GetLastError() == ERROR_BROKEN_PIPE) + return NULL; + + CancelIo(hChildPipeRead); + TerminateProcess(hProcess, 1); + return "GetOverlappedResult(hChildPipeRead) failed"; + } + break; + + case ERROR_BROKEN_PIPE: + return NULL; + + default: + CancelIo(hChildPipeRead); + TerminateProcess(hProcess, 1); + return "ReadFile(hChildPipeRead) failed"; + } + } ffStrbufAppendNS(buffer, nRead, str); + } while (nRead > 0); - CloseHandle(hChildStdoutRead); return NULL; } diff --git a/src/common/properties.c b/src/common/properties.c index 48b797599c..c91f107eb1 100644 --- a/src/common/properties.c +++ b/src/common/properties.c @@ -144,27 +144,17 @@ bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquer return true; } -bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) +bool ffParsePropFileHomeValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries) { - FFstrbuf absolutePath; - ffStrbufInitA(&absolutePath, 64); - ffStrbufAppend(&absolutePath, &instance->state.platform.homeDir); - ffStrbufAppendC(&absolutePath, '/'); - ffStrbufAppendS(&absolutePath, relativeFile); - - bool result = ffParsePropFileValues(absolutePath.chars, numQueries, queries); - - ffStrbufDestroy(&absolutePath); - - return result; + FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateF("%s/%s", instance.state.platform.homeDir.chars, relativeFile); + return ffParsePropFileValues(absolutePath.chars, numQueries, queries); } bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) { bool foundAFile = false; - FFstrbuf baseDir; - ffStrbufInitA(&baseDir, 64); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64); FF_LIST_FOR_EACH(FFstrbuf, dirPrefix, *list) { @@ -189,7 +179,5 @@ bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uin break; } - ffStrbufDestroy(&baseDir); - return foundAFile; } diff --git a/src/common/properties.h b/src/common/properties.h index ea78ed9032..8b65e419ca 100644 --- a/src/common/properties.h +++ b/src/common/properties.h @@ -14,7 +14,7 @@ typedef struct FFpropquery bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer); bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer); bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries); -bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries); +bool ffParsePropFileHomeValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries); bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries); static inline bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer) @@ -22,9 +22,9 @@ static inline bool ffParsePropFile(const char* filename, const char* start, FFst return ffParsePropFileValues(filename, 1, (FFpropquery[]){{start, buffer}}); } -static inline bool ffParsePropFileHome(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer) +static inline bool ffParsePropFileHome(const char* relativeFile, const char* start, FFstrbuf* buffer) { - return ffParsePropFileHomeValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}}); + return ffParsePropFileHomeValues(relativeFile, 1, (FFpropquery[]){{start, buffer}}); } static inline bool ffParsePropFileList(const FFlist* list, const char* relativeFile, const char* start, FFstrbuf* buffer) @@ -32,24 +32,24 @@ static inline bool ffParsePropFileList(const FFlist* list, const char* relativeF return ffParsePropFileListValues(list, relativeFile, 1, (FFpropquery[]){{start, buffer}}); } -static inline bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) +static inline bool ffParsePropFileConfigValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries) { - return ffParsePropFileListValues(&instance->state.platform.configDirs, relativeFile, numQueries, queries); + return ffParsePropFileListValues(&instance.state.platform.configDirs, relativeFile, numQueries, queries); } -static inline bool ffParsePropFileConfig(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer) +static inline bool ffParsePropFileConfig(const char* relativeFile, const char* start, FFstrbuf* buffer) { - return ffParsePropFileConfigValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}}); + return ffParsePropFileConfigValues(relativeFile, 1, (FFpropquery[]){{start, buffer}}); } -static inline bool ffParsePropFileDataValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) +static inline bool ffParsePropFileDataValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries) { - return ffParsePropFileListValues(&instance->state.platform.dataDirs, relativeFile, numQueries, queries); + return ffParsePropFileListValues(&instance.state.platform.dataDirs, relativeFile, numQueries, queries); } -static inline bool ffParsePropFileData(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer) +static inline bool ffParsePropFileData(const char* relativeFile, const char* start, FFstrbuf* buffer) { - return ffParsePropFileDataValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}}); + return ffParsePropFileDataValues(relativeFile, 1, (FFpropquery[]){{start, buffer}}); } #endif diff --git a/src/common/settings.c b/src/common/settings.c index 09cf723ee3..dda3fe62db 100644 --- a/src/common/settings.c +++ b/src/common/settings.c @@ -97,9 +97,9 @@ typedef struct GSettingsData GVariantGetters variantGetters; } GSettingsData; -static const GSettingsData* getGSettingsData(const FFinstance* instance) +static const GSettingsData* getGSettingsData(void) { - FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance->config.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1); + FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance.config.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1); FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_lookup) FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_has_key) @@ -123,9 +123,9 @@ static const GSettingsData* getGSettingsData(const FFinstance* instance) FF_LIBRARY_DATA_LOAD_RETURN } -FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type) +FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type) { - const GSettingsData* data = getGSettingsData(instance); + const GSettingsData* data = getGSettingsData(); if(data == NULL) return FF_VARIANT_NULL; @@ -152,9 +152,9 @@ FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaN return getGVariantValue(variant, type, &data->variantGetters); } #else //FF_HAVE_GIO -FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type) +FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type) { - FF_UNUSED(instance, schemaName, path, key, type) + FF_UNUSED(schemaName, path, key, type) return FF_VARIANT_NULL; } #endif //FF_HAVE_GIO @@ -170,9 +170,9 @@ typedef struct DConfData DConfClient* client; } DConfData; -static const DConfData* getDConfData(const FFinstance* instance) +static const DConfData* getDConfData(void) { - FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance->config.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2); + FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance.config.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2); FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_read_full) FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new) @@ -191,9 +191,9 @@ static const DConfData* getDConfData(const FFinstance* instance) FF_LIBRARY_DATA_LOAD_RETURN } -FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type) +FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type) { - const DConfData* data = getDConfData(instance); + const DConfData* data = getDConfData(); if(data == NULL) return FF_VARIANT_NULL; @@ -209,23 +209,23 @@ FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvari return getGVariantValue(variant, type, &data->variantGetters); } #else //FF_HAVE_DCONF -FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type) +FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type) { - FF_UNUSED(instance, key, type) + FF_UNUSED(key, type) return FF_VARIANT_NULL; } #endif //FF_HAVE_DCONF -FFvariant ffSettingsGet(const FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type) +FFvariant ffSettingsGet(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type) { - FFvariant gsettings = ffSettingsGetGSettings(instance, gsettingsSchemaName, gsettingsPath, gsettingsKey, type); + FFvariant gsettings = ffSettingsGetGSettings(gsettingsSchemaName, gsettingsPath, gsettingsKey, type); if( (type == FF_VARIANT_TYPE_BOOL && gsettings.boolValueSet) || (type != FF_VARIANT_TYPE_BOOL && gsettings.strValue != NULL) ) return gsettings; - return ffSettingsGetDConf(instance, dconfKey, type); + return ffSettingsGetDConf(dconfKey, type); } #ifdef FF_HAVE_XFCONF @@ -241,9 +241,9 @@ typedef struct XFConfData FF_LIBRARY_SYMBOL(xfconf_init) } XFConfData; -static const XFConfData* getXFConfData(const FFinstance* instance) +static const XFConfData* getXFConfData(void) { - FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance->config.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4); + FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance.config.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4); FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get) FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_has_property) @@ -258,9 +258,9 @@ static const XFConfData* getXFConfData(const FFinstance* instance) FF_LIBRARY_DATA_LOAD_RETURN } -FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type) +FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type) { - const XFConfData* data = getXFConfData(instance); + const XFConfData* data = getXFConfData(); if(data == NULL) return FF_VARIANT_NULL; @@ -281,9 +281,9 @@ FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelNam return FF_VARIANT_NULL; } #else //FF_HAVE_XFCONF -FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type) +FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type) { - FF_UNUSED(instance, channelName, propertyName, type) + FF_UNUSED(channelName, propertyName, type) return FF_VARIANT_NULL; } #endif //FF_HAVE_XFCONF @@ -303,9 +303,9 @@ typedef struct SQLiteData FF_LIBRARY_SYMBOL(sqlite3_close) } SQLiteData; -static const SQLiteData* getSQLiteData(const FFinstance* instance) +static const SQLiteData* getSQLiteData(void) { - FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance->config.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1); + FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance.config.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1); FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_open_v2) FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_prepare_v2) @@ -319,12 +319,12 @@ static const SQLiteData* getSQLiteData(const FFinstance* instance) FF_LIBRARY_DATA_LOAD_RETURN } -int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query) +int ffSettingsGetSQLite3Int(const char* dbPath, const char* query) { if(!ffPathExists(dbPath, FF_PATHTYPE_FILE)) return 0; - const SQLiteData* data = getSQLiteData(instance); + const SQLiteData* data = getSQLiteData(); if(data == NULL) return 0; @@ -354,12 +354,12 @@ int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, cons return result; } -bool ffSettingsGetSQLite3String(const FFinstance* instance, const char* dbPath, const char* query, FFstrbuf* result) +bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result) { if(!ffPathExists(dbPath, FF_PATHTYPE_FILE)) return false; - const SQLiteData* data = getSQLiteData(instance); + const SQLiteData* data = getSQLiteData(); if(data == NULL) return false; @@ -389,23 +389,38 @@ bool ffSettingsGetSQLite3String(const FFinstance* instance, const char* dbPath, return true; } #else //FF_HAVE_SQLITE3 -int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query) +int ffSettingsGetSQLite3Int(const char* dbPath, const char* query) { - FF_UNUSED(instance, dbPath, query) + FF_UNUSED(dbPath, query) return 0; } -bool ffSettingsGetSQLite3String(const FFinstance* instance, const char* dbPath, const char* query, FFstrbuf* result) +bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result) { - FF_UNUSED(instance, dbPath, query, result) + FF_UNUSED(dbPath, query, result) return false; } #endif //FF_HAVE_SQLITE3 #ifdef __ANDROID__ #include -void ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) { +bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) { ffStrbufEnsureFree(result, PROP_VALUE_MAX); - result->length += (uint32_t) __system_property_get(propName, result->chars + result->length); + int len = __system_property_get(propName, result->chars + result->length); + if (len <= 0) return false; + result->length += (uint32_t) len; result->chars[result->length] = '\0'; + return true; +} +#elif defined(__FreeBSD__) +#include +bool ffSettingsGetFreeBSDKenv(const char* propName, FFstrbuf* result) +{ + //https://wiki.ghostbsd.org/index.php/Kenv + ffStrbufEnsureFree(result, KENV_MVALLEN); + int len = kenv(KENV_GET, propName, result->chars + result->length, KENV_MVALLEN); + if (len <= 0) return false; + result->length += (uint32_t) len; + result->chars[result->length] = '\0'; + return true; } -#endif //__ANDROID__ +#endif diff --git a/src/common/settings.h b/src/common/settings.h index 57fbf56737..212727fe91 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -25,16 +25,18 @@ typedef union FFvariant #define FF_VARIANT_NULL ((FFvariant){.strValue = NULL}) -FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type); -FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type); -FFvariant ffSettingsGet(const FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type); -FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type); +FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type); +FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type); +FFvariant ffSettingsGet(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type); +FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type); -int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query); -bool ffSettingsGetSQLite3String(const FFinstance* instance, const char* dbPath, const char* query, FFstrbuf* result); +int ffSettingsGetSQLite3Int(const char* dbPath, const char* query); +bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result); #ifdef __ANDROID__ -void ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result); +bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result); +#elif defined(__FreeBSD__) +bool ffSettingsGetFreeBSDKenv(const char* propName, FFstrbuf* result); #endif #endif diff --git a/src/common/thread.h b/src/common/thread.h index 0b9bcb7e10..0b8989c4e3 100644 --- a/src/common/thread.h +++ b/src/common/thread.h @@ -19,6 +19,7 @@ return (FFThreadType)_beginthreadex(NULL, 0, func, data, 0, NULL); } #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; } + #define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) static __stdcall unsigned fn ## ThreadMain () { fn(); return 0; } static inline void ffThreadDetach(FFThreadType thread) { CloseHandle(thread); } static inline void ffThreadJoin(FFThreadType thread) { WaitForSingleObject(thread, 0xffffffff /*INFINITE*/); } #else @@ -34,6 +35,7 @@ return newThread; } #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static void* fn ## ThreadMain (void* data) { fn((paramType)data); return NULL; } + #define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) static void* fn ## ThreadMain () { fn(); return NULL; } static inline void ffThreadDetach(FFThreadType thread) { pthread_detach(thread); } static inline void ffThreadJoin(FFThreadType thread) { pthread_join(thread, NULL); } #endif diff --git a/src/data/config_user.jsonc b/src/data/config_user.jsonc new file mode 100644 index 0000000000..2e3bbb36f7 --- /dev/null +++ b/src/data/config_user.jsonc @@ -0,0 +1,43 @@ +// ~/.config/fastfetch/config.jsonc +// See https://github.com/fastfetch-cli/fastfetch/wiki/Configuration for more details +// See *.jsonc in https://github.com/fastfetch-cli/fastfetch/tree/dev/presets/examples for more examples +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "padding": { + "top": 2 + } + }, + "display": { + "percentType": 9 // colored percent number + }, + "modules": [ + "title", + "separator", + "os", + "host", + "kernel", + "uptime", + "packages", + "shell", + "display", + "de", + "wm", + "wmtheme", + "theme", + "icons", + "font", + "cursor", + "terminal", + "terminalfont", + "cpu", + "gpu", + "memory", + "disk", + "battery", + "poweradapter", + "locale", + "break", + "colors" + ] +} diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 0ade6d30b7..619bdfdc35 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -58,6 +58,18 @@ # Default is true. #--hide-cursor true +# Processing timeout option: +# Sets the timeout (ms) when waiting for child processes +# Must be an integer. +# Default is 1000 +#--processing-timeout 1000 + +# WMI timeout option: +# Sets the timeout (ms) for WMI queries. Windows only +# Must be an integer. +# Default is 5000 +#--wmi-timeout 5000 + # Logo option: # Sets the logo to use. # List available logos with "fastfetch --list-logos". @@ -146,12 +158,45 @@ # Default is IEC. #--binary-prefix IEC +# Size number of digits option: +# Sets the number of digits to keep after the decimal point when formatting sizes. +# Must be an possitive integer. +# Default is 2. +#--size-ndigits 2 + +# Size max prefix option: +# Sets the largest binary prefix to use when formatting sizes. +# Must be one of B, kB, MB, GB, TB, PB, EB, ZB, YB +# Default is YB. +#--size-max-prefix YB + +# Disable output buffer option: +# Sets if the stdout application buffer should be disabled. +# Must be true or false. +# Default is false. +#--no-buffer false + # Title FQDN option: # Sets if the title should use the fully qualified domain name. # Must be true or false. # Default is false. #--title-fqdn false +# Title user color option: +# Sets color of the user name (left part). +# Default is empty (use color of `--color-title`). +#--title-color-user + +# Title at color option: +# Sets color of the @ symbol (middle part). +# Default is empty (use color of `--color-title`). +#--title-color-at + +# Title host color option: +# Sets color of the host name (right part). +# Default is empty (use color of `--color-title`). +#--title-color-host + # Separator option: # Sets the string placed between a key and its value. # Can be any string. @@ -176,6 +221,11 @@ # Default is 0 (disabled). #--publicip-timeout 0 +# Weather location option: +# Sets the location to be used. It must be URI encoded (eg a whitespace must be encoded as `+`). +# Default is empty (guessing by public IP) +#--weather-location "Location" + # Weather output format option: # Sets the weather format to be used. It must be URI encoded. # See: https://github.com/chubin/wttr.in#one-line-output @@ -200,20 +250,28 @@ # Default is the first match starting with org.mpris.MediaPlayer2. #--player-name spotify +# Display server force DRM option +# Sets if fastfetch should only use `/sys/class/drm` to detect displays if you get issues with the default behavior. +# Note DRM doesn't support refresh rate or scaled resolution detection. +# Only supported on Linux. +# Must be true or false. +# Default is false. +#--ds-force-drm false + # Escape bedrock option # Sets if fastfetch should escape the bedrock jail, if it detectes that it is running in one # Must be true or false. # Default is true. #--escape-bedrock true -# GL option +# OpenGL option # Sets with opengl context creation library to use # Must be either auto, egl, glx or osmesa # Default is auto. -#--gl auto +#--opengl-library auto # GPU hide options -# Sets weather to hide certain gpu types +# Sets whether to hide certain gpu types # Must be either true or false # Default is false. #--gpu-hide-integrated @@ -226,23 +284,11 @@ # Default is false. #--gpu-force-vulkan -# Shell option -# Sets if shell version should be detected and printed -# Must be either true or false -# Default is true. -#--shell-version true - -# Terminal option -# Sets if terminal version should be detected and printed -# Must be either true or false -# Default is true. -#--terminal-version true - # Disk show options # Sets if certain types of disk should be printed # Must be either true or false -# Default is false except for --disk-show-removable. -#--disk-show-removable true +# Default is false except for --disk-show-external. +#--disk-show-external true #--disk-show-hidden false #--disk-show-subvolumes false #--disk-show-unknown false @@ -303,15 +349,16 @@ #--shell-key Shell #--display-key Display {1} #--brightness-key Brightness ({1}) +#--monitor-key Monitor #--de-key DE #--wm-key WM -#--wm-theme-key WM Theme +#--wmtheme-key WM Theme #--theme-key Theme #--icons-key Icons #--font-key Font #--cursor-key Cursor #--terminal-key Terminal -#--terminal-font-key Terminal Font +#--terminalfont-key Terminal Font #--cpu-key CPU #--cpu-usage-key CPU Usage #--gpu-key GPU {1} @@ -320,6 +367,7 @@ #--disk-key Disk ({1}) #--battery-key Battery {1} #--poweradapter-key Power Adapter {1} +#--lm-key LM #--locale-key Locale #--localip-key Local IP ({1}) #--publicip-key Public IP @@ -354,13 +402,13 @@ #--brightness-format #--de-format #--wm-format -#--wm-theme-format +#--wmtheme-format #--theme-format #--icons-format #--font-format #--cursor-format #--terminal-format -#--terminal-font-format +#--terminalfont-format #--cpu-format #--cpu-usage-format #--gpu-format @@ -369,10 +417,12 @@ #--disk-format #--battery-format #--poweradapter-format +#--lm-format #--locale-format #--localip-format #--publicip-format #--weather-format +#--monitor-format #--player-format #--media-format #--datetime-format @@ -385,53 +435,52 @@ #--gamepad-format #--wallpaper-format -# Error options: -# Sets the format string to use if an error occured -# For information on format strings, see "fastfetch --help format". -# Each of them take the error as first and only argument. -# If one of them is set, the module will appear, even if --show-errors is not given. -#--os-error -#--host-error -#--chassis-error -#--kernel-error -#--uptime-error -#--processes-error -#--packages-error -#--shell-error -#--display-error -#--brightness-error -#--de-error -#--wm-error -#--wm-theme-error -#--theme-error -#--icons-error -#--font-error -#--cursor-error -#--terminal-error -#--terminal-font-error -#--cpu-error -#--cpu-usage-error -#--gpu-error -#--memory-error -#--swap-error -#--disk-error -#--battery-error -#--poweradapter-error -#--locale-error -#--localip-error -#--publicip-error -#--weather-error -#--player-error -#--media-error -#--datetime-error -#--vulkan-error -#--opengl-error -#--opencl-error -#--users-error -#--bluetooth-error -#--sound-error -#--gamepad-error -#--wallpaper-error +# Key color options: +# Overrides the global `--color-keys` for one specified module +#--os-key-color +#--host-key-color +#--chassis-key-color +#--kernel-key-color +#--uptime-key-color +#--processes-key-color +#--packages-key-color +#--shell-key-color +#--display-key-color +#--brightness-key-color +#--de-key-color +#--wm-key-color +#--wmtheme-key-color +#--theme-key-color +#--icons-key-color +#--font-key-color +#--cursor-key-color +#--terminal-key-color +#--terminalfont-key-color +#--cpu-key-color +#--cpu-usage-key-color +#--gpu-key-color +#--memory-key-color +#--swap-key-color +#--disk-key-color +#--battery-key-color +#--poweradapter-key-color +#--lm-key-color +#--locale-key-color +#--localip-key-color +#--publicip-key-color +#--weather-key-color +#--monitor-key-color +#--player-key-color +#--media-key-color +#--datetime-key-color +#--vulkan-key-color +#--opengl-key-color +#--opencl-key-color +#--users-key-color +#--bluetooth-key-color +#--sound-key-color +#--gamepad-key-color +#--wallpaper-key-color # Library options: # Sets an user specific path to a library to load. @@ -456,6 +505,7 @@ #--lib-glx /usr/lib/libGLX.so #--lib-osmesa /usr/lib/libOSMesa.so #--lib-opencl /usr/lib/libOpenCL.so -#--lib-cjson /usr/lib/libcjson.so #--lib-freetype /data/data/com.termux/files/usr/lib #--lib-pulse /usr/lib/libpulse.so +#--lib-ddcutil /usr/lib/libddcutil.so +#--lib-nm /usr/lib/libnm.so diff --git a/src/data/help.txt b/src/data/help.txt index 83428e0dae..95a74429c2 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -1,21 +1,21 @@ Usage: fastfetch Informative options: - -h,--help: Show this message - -h,--help : Show help for a specific command - -v,--version: Show the version of fastfetch - --list-config-paths: List search paths of config files - --list-data-paths: List search paths of presets and logos - --list-logos: List available logos - --list-modules: List available modules - --list-presets: List presets fastfetch knows about; they can be loaded with --load-config (+) - --list-features: List the supported features fastfetch was compiled with (mainly for development) - --print-logos: Print available logos - --print-config-system: Print the default system config - --print-config-user: Print the default user config - --print-structure: Print the default structure - --gen-config: Generate a sample config file in the default path - --gen-config-force: Generate a sample config file in the default path. Overwrite the existing one + -h,--help: Show this message + -h,--help : Show help for a specific command + -v,--version: Show the version of fastfetch + --list-config-paths: List search paths of config files + --list-data-paths: List search paths of presets and logos + --list-logos: List available logos + --list-modules: List available modules + --list-presets: List presets fastfetch knows about; they can be loaded with --load-config (+) + --list-features: List the supported features fastfetch was compiled with (mainly for development) + --print-logos: Print available logos + --print-config-system: Print the default system config + --print-config-user: Print the default user config + --print-structure: Print the default structure + --gen-config : Generate a sample config file in the default path. Param `type` can be `jsonc` or `conf` + --gen-config-force : Generate a sample config file in the default path. Overwrite the existing one General options: --load-config : Load a config file or preset (+) @@ -24,6 +24,9 @@ General options: --allow-slow-operations : Allow operations that are usually very slow for more detailed output --escape-bedrock : On Bedrock Linux, whether to escape the bedrock jail --pipe : Disable logo and all escape sequences + --wmi-timeout : Set the timeout (ms) for WMI queries. Windows only. Default is 5000 + --processing-timeout : Set the timeout (ms) when waiting for child processes. Default is 1000 + --ds-force-drm : Set if only DRM should be used to detect displays. Default is false Logo options: -l,--logo : Set the logo; if default, the name of a builtin logo or a path to a file @@ -55,6 +58,7 @@ Display options: -s,--structure : Set the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available. --color-keys : Set the color of the keys --color-title : Set the color of the title + --bright-color : Set if the keys, title and ASCII logo should be printed in bright color. Default is true -c,--color : Set the color of both the keys and title --separator : Set the separator between key and value. Default is a colon with a space --set : Hard set the value of a key @@ -62,19 +66,22 @@ Display options: --show-errors : Print occurring errors --disable-linewrap : Whether to disable line wrap during the run --hide-cursor : Whether to hide the cursor during the run - --binary-prefix : Set the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC. + --binary-prefix : Set the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC + --percent-type : Set the percentage output type. 1 for percentage number, 2 for bar, 3 for both, 6 for bar only, 9 for colored number. Default is 1 + --no-buffer : Set if the stdout application buffer should be disabled. Default is false + --size-ndigits : Set the number of digits to keep after the decimal point when formatting sizes + --size-max-prefix : Set the largest binary prefix to use when formatting sizes. Default is YB + --temperature-unit : Set the unit of the temperature. Must be one of C, F and K. Default is C General module options: - ---format : Set the format string to use for each specific module. - To see how a format string works, use fastfetch --help format. - To see help about a specific format string, use fastfetch --help -format. + ---format : Set the format string to use for each specific module. + To see how a format string works, use fastfetch --help format. + To see help about a specific format string, use fastfetch --help -format. - ---key : Set the key to use for each specific module. - For modules which print multiple lines, the string is parsed as a format string with the index as first character. + ---key : Set the key to use for each specific module. + For modules which print multiple lines, the string is parsed as a format string with the index as first character. - ---error : Set the error format string to use for each specific module. - The error is given as the first and only argument. - Setting this for a module will cause it to appear, even if --show-errors is not given. + ---key-color : Override the global `--color-keys` option for each specific module. Library options: Set the path of a library to load --lib-PCI @@ -97,50 +104,53 @@ Library options: Set the path of a library to load --lib-glx --lib-osmesa --lib-opencl - --lib-cjson --lib-pulse --lib-freetype + --lib-ddcutil Module specific options: --title-fqdn : Set if the title should use fully qualified domain name. Default is false + --title-color-user : Set color of the user name (left part). Default is empty (use color of `--color-title`). + --title-color-at : Set color of the @ symbol (middle part). Default is empty (use color of `--color-title`) + --title-color-host : Set color of the host name (right part). Default is empty (use color of `--color-title`) --separator-string : Set the string printed by the separator module --os-file : Set the path to the file containing OS information - --shell-version : Set if shell version should be detected and printed - --terminal-version : Set if terminal version should be detected and printed --disk-folders : A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows) --disk-show-regular : Set if regular volume should be printed. Default is true - --disk-show-removable : Set if removable volume should be printed. Default is true + --disk-show-external : Set if external volume should be printed. Default is true --disk-show-hidden : Set if hidden volumes should be printed. Default is false --disk-show-subvolumes : Set if subvolumes should be printed. Default is false --disk-show-unknown : Set if unknown (unable to detect sizes) volumes should be printed. Default is false --bluetooth-show-disconnected: : Set if disconnected bluetooth devices should be printed. Default is false --display-compact-type: : Set if all displays should be printed in one line. Default is none --display-detect-name: : Set if display name should be detected and printed (if supported). Default is false - --display-precise-refresh-rate: :Set if decimal refresh rates should not be rounded into integers when printing + --display-precise-refresh-rate: :Set if decimal refresh rates should not be rounded into integers when printing. Default is true --sound-type: : Set what type of sound devices should be printed. Should be either main, active or all. Default is main --battery-dir : The directory where the battery folders are. Standard: /sys/class/power_supply/ --cpu-temp : Detect and display CPU temperature if supported. Default is false --gpu-temp : Detect and display GPU temperature if supported. Default is false --gpu-force-vulkan : Force using vulkan to detect GPUs, which support video memory usage detection with `--allow-slow-operations`. Default is false - --gpu-hide-integrated : Hide integrated GPU if supported. Default is false - --gpu-hide-discrete : Hide discrete GPU if supported. Default is false + --gpu-hide-type : Specify the type of GPUs should not be printed. Must be `integrated`, `discrete` or `none`. Default is none --battery-temp : Detect and display Battery temperature if supported. Default is false --localip-show-ipv4 : Show IPv4 addresses in local ip module. Default is true --localip-show-ipv6 : Show IPv6 addresses in local ip module. Default is false --localip-show-mac : Show mac addresses in local ip module. Default is false --localip-show-loop : Show loop back addresses (127.0.0.1) in local ip module. Default is false --localip-name-prefix : Show IPs with given name prefix only. Default is empty + --localip-default-route-only : Show ips that are used for default routing only. Default is false --localip-compact : Show all IPs in one line. Default is false --publicip-timeout: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0) --publicip-url: The URL of public IP detection server to be used. + --weather-location: Set the location to be used. It must be URI encoded (eg a whitespace must be encoded as `+`). --weather-timeout: Time in milliseconds to wait for the weather server to respond. Default is disabled (0) --weather-output-format: The output weather format to be used. It must be URI encoded. --player-name: The name of the player to use - --gl : Set the OpenGL context creation library to use. Must be auto, egl, glx or osmesa. Default is auto - --percent-type : Set the percentage output type. 1 for percentage number, 2 for bar, 3 for both, 6 for bar only, 9 for colored number. Default is 1 - --command-shell : Set the shell program to execute the command text. Default is cmd for Windows, csh for FreeBSD, bash for others - --command-key : Set the module key to display, can be specified mulitple times - --command-text : Set the command text to be executed, can be specified mulitple times + --opengl-library : Set the OpenGL context creation library to use. Must be auto, egl, glx or osmesa. Default is auto + --command-shell : Set the shell program to execute the command text. Default is cmd for Windows, /bin/sh for *nix + --command-key : Set the module key to display + --command-text : Set the command text to be executed + --colors-symbol : Set the symbol to be printed by Colors module. Default is block + --colors-padding-left : Set the number of white spaces to print before the symbol. Default is 0 Parsing is not case sensitive. E.g. "--lib-PCI" is equal to "--Lib-Pci" If a value starts with a ?, it is optional. "true" will be used if not set. diff --git a/src/detection/battery/battery.h b/src/detection/battery/battery.h index ab0021b917..5667af76cf 100644 --- a/src/detection/battery/battery.h +++ b/src/detection/battery/battery.h @@ -17,6 +17,6 @@ typedef struct BatteryResult double temperature; } BatteryResult; -const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results); +const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results); #endif diff --git a/src/detection/battery/battery_android.c b/src/detection/battery/battery_android.c index 1a783e595d..b05cce111d 100644 --- a/src/detection/battery/battery_android.c +++ b/src/detection/battery/battery_android.c @@ -7,10 +7,16 @@ #define FF_TERMUX_API_PATH FASTFETCH_TARGET_DIR_ROOT "/libexec/termux-api" #define FF_TERMUX_API_PARAM "BatteryStatus" -const char* ffDetectBatteryImpl(FF_MAYBE_UNUSED FFinstance* instance, FFlist* results) +static inline void wrapYyjsonFree(yyjson_doc** doc) { - FF_STRBUF_AUTO_DESTROY buffer; - ffStrbufInit(&buffer); + assert(doc); + if (*doc) + yyjson_doc_free(*doc); +} + +static const char* parseTermuxApi(FFBatteryOptions* options, FFlist* results) +{ + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); if(ffProcessAppendStdOut(&buffer, (char* const[]){ FF_TERMUX_API_PATH, @@ -19,8 +25,13 @@ const char* ffDetectBatteryImpl(FF_MAYBE_UNUSED FFinstance* instance, FFlist* re })) return "Starting `" FF_TERMUX_API_PATH " " FF_TERMUX_API_PARAM "` failed"; - if(buffer.chars[0] != '{') - return "`" FF_TERMUX_API_PATH " " FF_TERMUX_API_PARAM "` prints invalid result (not a JSON object)"; + yyjson_doc* __attribute__((__cleanup__(wrapYyjsonFree))) doc = yyjson_read_opts(buffer.chars, buffer.length, 0, NULL, NULL); + if (!doc) + return "Failed to parse battery info"; + + yyjson_val* root = yyjson_doc_get_root(doc); + if (!yyjson_is_obj(root)) + return "Battery info result is not a JSON object"; BatteryResult* battery = ffListAdd(results); battery->temperature = FF_BATTERY_TEMP_UNSET; @@ -29,28 +40,89 @@ const char* ffDetectBatteryImpl(FF_MAYBE_UNUSED FFinstance* instance, FFlist* re ffStrbufInit(&battery->status); ffStrbufInit(&battery->technology); - if(ffParsePropLines(buffer.chars, "\"percentage\": ", &battery->status)) + battery->capacity = yyjson_get_num(yyjson_obj_get(root, "percentage")); + ffStrbufAppendS(&battery->status, yyjson_get_str(yyjson_obj_get(root, "status"))); + if(options->temp) + battery->temperature = yyjson_get_num(yyjson_obj_get(root, "temperature")); + + return NULL; +} + +static const char* parseDumpsys(FFBatteryOptions* options, FFlist* results) +{ + FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate(); + if (ffProcessAppendStdOut(&buf, (char* []) { + "/system/bin/dumpsys", + "battery", + NULL, + }) != NULL || buf.length == 0) + return "Executing `/system/bin/dumpsys battery` failed"; // Only works in `adb shell`, or when rooted + + if (!ffStrbufStartsWithS(&buf, "Current Battery Service state:\n")) + return "Invalid `/system/bin/dumpsys battery` result"; + + const char* start = buf.chars + strlen("Current Battery Service state:\n"); + + FF_STRBUF_AUTO_DESTROY temp = ffStrbufCreate(); + if (!ffParsePropLines(start, "present: ", &temp) || !ffStrbufEqualS(&temp, "true")) + return NULL; + ffStrbufClear(&temp); + + BatteryResult* battery = ffListAdd(results); + battery->temperature = FF_BATTERY_TEMP_UNSET; + ffStrbufInit(&battery->manufacturer); + ffStrbufInit(&battery->modelName); + ffStrbufInit(&battery->status); + ffStrbufInit(&battery->technology); + + if (ffParsePropLines(start, "AC powered: ", &temp) && ffStrbufEqualS(&temp, "true")) + ffStrbufAppendS(&battery->status, "AC powered"); + ffStrbufClear(&temp); + + if (ffParsePropLines(start, "USB powered: ", &temp) && ffStrbufEqualS(&temp, "true")) + { + if (battery->status.length) ffStrbufAppendS(&battery->status, ", "); + ffStrbufAppendS(&battery->status, "USB powered"); + } + ffStrbufClear(&temp); + + if (ffParsePropLines(start, "Wireless powered: ", &temp) && ffStrbufEqualS(&temp, "true")) { - battery->capacity = ffStrbufToDouble(&battery->status); - ffStrbufClear(&battery->status); + if (battery->status.length) ffStrbufAppendS(&battery->status, ", "); + ffStrbufAppendS(&battery->status, "Wireless powered"); } + ffStrbufClear(&temp); - if(instance->config.batteryTemp) { - if(ffParsePropLines(buffer.chars, "\"temperature\": ", &battery->status)) - { - ffStrbufTrimRight(&battery->status, ','); - ffStrbufTrim(&battery->status, '"'); - battery->temperature = ffStrbufToDouble(&battery->status); - ffStrbufClear(&battery->status); - } + double level = 0, scale = 0; + if (ffParsePropLines(start, "level: ", &temp)) + level = ffStrbufToDouble(&temp); + ffStrbufClear(&temp); + + if (ffParsePropLines(start, "scale: ", &temp)) + scale = ffStrbufToDouble(&temp); + ffStrbufClear(&temp); + + if (level > 0 && scale > 0) + battery->capacity = level * 100 / scale; } - if(ffParsePropLines(buffer.chars, "\"status\": ", &battery->status)) + if(options->temp) { - ffStrbufTrimRight(&battery->status, ','); - ffStrbufTrim(&battery->status, '"'); + if (ffParsePropLines(start, "temperature: ", &temp)) + battery->temperature = ffStrbufToDouble(&temp); + ffStrbufClear(&temp); } + ffParsePropLines(start, "technology: ", &battery->technology); + return NULL; } + +const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) +{ + const char* error = parseTermuxApi(options, results); + if (error && parseDumpsys(options, results) == NULL) + return NULL; + return error; +} diff --git a/src/detection/battery/battery_apple.c b/src/detection/battery/battery_apple.c index 7244a89a15..dc1281ddab 100644 --- a/src/detection/battery/battery_apple.c +++ b/src/detection/battery/battery_apple.c @@ -5,33 +5,18 @@ #include -static double detectBatteryTemp() +static double detectBatteryTemp(void) { - FF_LIST_AUTO_DESTROY temps; - ffListInit(&temps, sizeof(FFTempValue)); - - ffDetectCoreTemps(FF_TEMP_BATTERY, &temps); + double result = 0; - if(temps.length == 0) + if(ffDetectCoreTemps(FF_TEMP_BATTERY, &result)) return FF_BATTERY_TEMP_UNSET; - double result = 0; - for(uint32_t i = 0; i < temps.length; ++i) - { - FFTempValue* tempValue = (FFTempValue*)ffListGet(&temps, i); - result += tempValue->value; - //TODO: do we really need this? - ffStrbufDestroy(&tempValue->name); - ffStrbufDestroy(&tempValue->deviceClass); - } - result /= temps.length; return result; } -const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) +const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) { - FF_UNUSED(instance); - CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery"); if (matchDict == NULL) return "IOServiceMatching(\"AppleSmartBattery\") failed"; @@ -93,10 +78,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) else ffStrbufAppendS(&battery->status, ""); - if(instance->config.batteryTemp) - battery->temperature = detectBatteryTemp(); - else - battery->temperature = FF_BATTERY_TEMP_UNSET; + battery->temperature = options->temp ? detectBatteryTemp() : FF_BATTERY_TEMP_UNSET; CFRelease(properties); IOObjectRelease(registryEntry); diff --git a/src/detection/battery/battery_bsd.c b/src/detection/battery/battery_bsd.c index 2cfbe4b7bb..287f004a13 100644 --- a/src/detection/battery/battery_bsd.c +++ b/src/detection/battery/battery_bsd.c @@ -1,4 +1,6 @@ #include "fastfetch.h" +#include "common/sysctl.h" +#include "common/io/io.h" #include "battery.h" #include @@ -6,28 +8,28 @@ #include #include -const char* ffDetectBatteryImpl(FF_MAYBE_UNUSED FFinstance* instance, FFlist* results) +const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results) { //https://www.freebsd.org/cgi/man.cgi?acpi_battery(4) //https://gitlab.xfce.org/panel-plugins/xfce4-battery-plugin/-/blob/master/panel-plugin/libacpi.c - int acpifd = open("/dev/acpi", O_RDONLY); + int units = ffSysctlGetInt("hw.acpi.battery.units", -100); + if (units < 0) + return "sysctlbyname(\"hw.acpi.battery.units\") failed"; + + if(units == 0) + return NULL; + + FF_AUTO_CLOSE_FD int acpifd = open("/dev/acpi", O_RDONLY); if(acpifd < 0) return "open(\"/dev/acpi\", O_RDONLY) failed"; - int units = ioctl(acpifd, ACPIIO_BATT_GET_UNITS, 0); - if(units < 0) - { - close(acpifd); - return "No acpiio battery units found"; - } - for(int i = 0; i < units; ++i) { union acpi_battery_ioctl_arg battio; battio.unit = i; - if(ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) < 0 || (battio.battinfo.state & ACPI_BATT_STAT_NOT_PRESENT)) + if(ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) < 0 || (battio.battinfo.state == ACPI_BATT_STAT_NOT_PRESENT)) continue; BatteryResult* battery = ffListAdd(results); @@ -38,9 +40,9 @@ const char* ffDetectBatteryImpl(FF_MAYBE_UNUSED FFinstance* instance, FFlist* re ffStrbufInit(&battery->technology); battery->capacity = battio.battinfo.cap; - if(battio.battinfo.state & ACPI_BATT_STAT_INVALID) + if(battio.battinfo.state == ACPI_BATT_STAT_INVALID) { - ffStrbufAppendS(&battery->status, "Invalid"); + ffStrbufAppendS(&battery->status, "Unknown, "); } else { @@ -49,11 +51,27 @@ const char* ffDetectBatteryImpl(FF_MAYBE_UNUSED FFinstance* instance, FFlist* re else if(battio.battinfo.state & ACPI_BATT_STAT_CHARGING) ffStrbufAppendS(&battery->status, "Charging, "); if(battio.battinfo.state & ACPI_BATT_STAT_CRITICAL) - ffStrbufAppendS(&battery->status, "Ctritical"); + ffStrbufAppendS(&battery->status, "Ctritical, "); + } + + int acadStatus; + if (ioctl(acpifd, ACPIIO_ACAD_GET_STATUS, &acadStatus) >= 0 && acadStatus) + { + ffStrbufAppendS(&battery->status, "AC connected"); + } + else + { ffStrbufTrimRight(&battery->status, ' '); ffStrbufTrimRight(&battery->status, ','); } + + battio.unit = i; + if (ioctl(acpifd, ACPIIO_BATT_GET_BIX, &battio) >= 0) + { + ffStrbufAppendS(&battery->manufacturer, battio.bix.oeminfo); + ffStrbufAppendS(&battery->modelName, battio.bix.model); + ffStrbufAppendS(&battery->technology, battio.bix.type); + } } - close(acpifd); return NULL; } diff --git a/src/detection/battery/battery_linux.c b/src/detection/battery/battery_linux.c index b78a6cf7f6..41d49db625 100644 --- a/src/detection/battery/battery_linux.c +++ b/src/detection/battery/battery_linux.c @@ -1,6 +1,7 @@ #include "fastfetch.h" #include "common/io/io.h" #include "battery.h" +#include "util/stringUtils.h" #include @@ -8,8 +9,7 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) { uint32_t dirLength = dir->length; - FFstrbuf testBatteryBuffer; - ffStrbufInit(&testBatteryBuffer); + FF_STRBUF_AUTO_DESTROY testBatteryBuffer = ffStrbufCreate(); //type must exist and be "Battery" ffStrbufAppendS(dir, "/type"); @@ -17,10 +17,7 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) ffStrbufSubstrBefore(dir, dirLength); if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Battery") != 0) - { - ffStrbufDestroy(&testBatteryBuffer); return; - } //scope may not exist or must not be "Device" ffStrbufAppendS(dir, "/scope"); @@ -28,10 +25,7 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) ffStrbufSubstrBefore(dir, dirLength); if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Device") == 0) - { - ffStrbufDestroy(&testBatteryBuffer); return; - } BatteryResult* result = ffListAdd(results); @@ -41,7 +35,7 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) ffStrbufSubstrBefore(dir, dirLength); if(available) result->capacity = ffStrbufToDouble(&testBatteryBuffer); - ffStrbufDestroy(&testBatteryBuffer); + if(!available) { result->capacity = 0.0/0.0; @@ -74,12 +68,13 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) result->temperature = FF_BATTERY_TEMP_UNSET; } -const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) { - FFstrbuf baseDir; - ffStrbufInitA(&baseDir, 64); - if(instance->config.batteryDir.length > 0) +const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) +{ + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64); + + if(options->dir.length > 0) { - ffStrbufAppend(&baseDir, &instance->config.batteryDir); + ffStrbufAppend(&baseDir, &options->dir); ffStrbufEnsureEndsWithC(&baseDir, '/'); } else @@ -91,15 +86,12 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) { DIR* dirp = opendir(baseDir.chars); if(dirp == NULL) - { - ffStrbufDestroy(&baseDir); return "opendir(batteryDir) == NULL"; - } struct dirent* entry; while((entry = readdir(dirp)) != NULL) { - if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, "..")) continue; ffStrbufAppendS(&baseDir, entry->d_name); @@ -109,11 +101,8 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) { closedir(dirp); - if(results->length == 0) { - ffStrbufDestroy(&baseDir); + if(results->length == 0) return "batteryDir doesn't contain any battery folder"; - } - ffStrbufDestroy(&baseDir); return NULL; } diff --git a/src/detection/battery/battery_nosupport.c b/src/detection/battery/battery_nosupport.c index 40ca05241a..02f084748f 100644 --- a/src/detection/battery/battery_nosupport.c +++ b/src/detection/battery/battery_nosupport.c @@ -1,8 +1,8 @@ #include "fastfetch.h" #include "battery.h" -const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) +const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) { - FF_UNUSED(instance, results) + FF_UNUSED(options, results) return "Not supported on this platform"; } diff --git a/src/detection/battery/battery_windows.c b/src/detection/battery/battery_windows.c index fc89a335ad..66df36cf38 100644 --- a/src/detection/battery/battery_windows.c +++ b/src/detection/battery/battery_windows.c @@ -30,22 +30,19 @@ static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev) SetupDiDestroyDeviceInfoList(*hdev); } -const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) +const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) { - if(instance->config.allowSlowOperations) + if(instance.config.allowSlowOperations) { //https://learn.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices HDEVINFO hdev __attribute__((__cleanup__(wrapSetupDiDestroyDeviceInfoList))) = - SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + SetupDiGetClassDevsW(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(hdev == INVALID_HANDLE_VALUE) - return "SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY) failed"; + return "SetupDiGetClassDevsW(&GUID_DEVCLASS_BATTERY) failed"; - for(DWORD idev = 0;; idev++) + SP_DEVICE_INTERFACE_DATA did = { .cbSize = sizeof(did) }; + for(DWORD idev = 0; SetupDiEnumDeviceInterfaces(hdev, NULL, &GUID_DEVCLASS_BATTERY, idev, &did); idev++) { - SP_DEVICE_INTERFACE_DATA did = { .cbSize = sizeof(did) }; - if(!SetupDiEnumDeviceInterfaces(hdev, NULL, &GUID_DEVCLASS_BATTERY, idev, &did)) - break; - DWORD cbRequired = 0; SetupDiGetDeviceInterfaceDetailW(hdev, &did, NULL, 0, &cbRequired, NULL); //Fail with not enough buffer SP_DEVICE_INTERFACE_DETAIL_DATA_W* FF_AUTO_FREE pdidd = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*)malloc(cbRequired); @@ -111,7 +108,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) } battery->temperature = 0.0/0.0; - if(instance->config.batteryTemp) + if(options->temp) { bqi.InformationLevel = BatteryTemperature; ULONG temp; diff --git a/src/detection/bios/bios.h b/src/detection/bios/bios.h index 6f664b4b23..84046ad408 100644 --- a/src/detection/bios/bios.h +++ b/src/detection/bios/bios.h @@ -7,13 +7,12 @@ typedef struct FFBiosResult { - FFstrbuf biosDate; - FFstrbuf biosRelease; - FFstrbuf biosVendor; - FFstrbuf biosVersion; - FFstrbuf error; + FFstrbuf date; + FFstrbuf release; + FFstrbuf vendor; + FFstrbuf version; } FFBiosResult; -void ffDetectBios(FFBiosResult* bios); +const char* ffDetectBios(FFBiosResult* bios); #endif diff --git a/src/detection/bios/bios_android.c b/src/detection/bios/bios_android.c new file mode 100644 index 0000000000..737df08de5 --- /dev/null +++ b/src/detection/bios/bios_android.c @@ -0,0 +1,13 @@ +#include "bios.h" +#include "common/settings.h" + +const char* ffDetectBios(FFBiosResult* bios) +{ + if (!ffSettingsGetAndroidProperty("ro.bootloader", &bios->version)) + ffSettingsGetAndroidProperty("ro.boot.bootloader", &bios->version); + + if (ffStrbufIgnCaseEqualS(&bios->version, "unknown")) + ffStrbufClear(&bios->version); + + return NULL; +} diff --git a/src/detection/bios/bios_apple.c b/src/detection/bios/bios_apple.c index d20524297c..3ebc1f4688 100644 --- a/src/detection/bios/bios_apple.c +++ b/src/detection/bios/bios_apple.c @@ -3,14 +3,8 @@ #include -void ffDetectBios(FFBiosResult* bios) +const char* ffDetectBios(FFBiosResult* bios) { - ffStrbufInit(&bios->error); - ffStrbufInit(&bios->biosDate); - ffStrbufInit(&bios->biosRelease); - ffStrbufInit(&bios->biosVendor); - ffStrbufInit(&bios->biosVersion); - io_registry_entry_t registryEntry; #ifndef __aarch64__ @@ -23,20 +17,17 @@ void ffDetectBios(FFBiosResult* bios) if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) { IOObjectRelease(registryEntry); - ffStrbufAppendS(&bios->error, "IORegistryEntryCreateCFProperties(registryEntry) failed"); - return; + return "IORegistryEntryCreateCFProperties(registryEntry) failed"; } - ffCfDictGetString(properties, CFSTR("vendor"), &bios->biosVendor); - ffCfDictGetString(properties, CFSTR("version"), &bios->biosVersion); - ffCfDictGetString(properties, CFSTR("release-date"), &bios->biosDate); - if(!ffStrbufContainC(&bios->biosDate, '-')) - ffStrbufAppendS(&bios->biosRelease, "Efi-"); - ffStrbufAppend(&bios->biosRelease, &bios->biosVersion); + ffCfDictGetString(properties, CFSTR("vendor"), &bios->vendor); + ffCfDictGetString(properties, CFSTR("version"), &bios->version); + ffCfDictGetString(properties, CFSTR("release-date"), &bios->date); + ffStrbufAppendS(&bios->release, "Efi"); CFRelease(properties); IOObjectRelease(registryEntry); - return; + return NULL; } #else @@ -47,8 +38,8 @@ void ffDetectBios(FFBiosResult* bios) CFMutableDictionaryRef properties; if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) == kIOReturnSuccess) { - ffCfDictGetString(properties, CFSTR("manufacturer"), &bios->biosVendor); - ffCfDictGetString(properties, CFSTR("time-stamp"), &bios->biosDate); + ffCfDictGetString(properties, CFSTR("manufacturer"), &bios->vendor); + ffCfDictGetString(properties, CFSTR("time-stamp"), &bios->date); CFRelease(properties); } IOObjectRelease(registryEntry); @@ -59,13 +50,24 @@ void ffDetectBios(FFBiosResult* bios) CFMutableDictionaryRef properties; if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) == kIOReturnSuccess) { - ffCfDictGetString(properties, CFSTR("system-firmware-version"), &bios->biosRelease); - ffStrbufAppend(&bios->biosVersion, &bios->biosRelease); - ffStrbufSubstrAfterFirstC(&bios->biosVersion, '-'); + ffCfDictGetString(properties, CFSTR("system-firmware-version"), &bios->version); + uint32_t index = ffStrbufFirstIndexC(&bios->version, '-'); + if (index != bios->version.length) + { + ffStrbufAppendNS(&bios->release, index, bios->version.chars); + ffStrbufRemoveSubstr(&bios->version, 0, index + 1); + } + else + { + ffStrbufAppendS(&bios->release, "iBoot"); + } CFRelease(properties); } IOObjectRelease(registryEntry); + return NULL; } #endif + + return "Failed to query bios info"; } diff --git a/src/detection/bios/bios_bsd.c b/src/detection/bios/bios_bsd.c index 8c993f0a95..26c0dd1b56 100644 --- a/src/detection/bios/bios_bsd.c +++ b/src/detection/bios/bios_bsd.c @@ -1,26 +1,17 @@ #include "bios.h" -#include +#include "common/settings.h" +#include "util/smbiosHelper.h" -static void kenvLookup(const char* name, FFstrbuf* result) +const char* ffDetectBios(FFBiosResult* result) { - ffStrbufEnsureFree(result, 255); - int len = kenv(KENV_GET, name, result->chars, 256); - if(len > 0) - result->length = (uint32_t) len; -} - -void ffDetectBios(FFBiosResult* bios) -{ - ffStrbufInit(&bios->error); - ffStrbufInit(&bios->biosDate); - ffStrbufInit(&bios->biosRelease); - ffStrbufInit(&bios->biosVendor); - ffStrbufInit(&bios->biosVersion); - - //https://wiki.ghostbsd.org/index.php/Kenv - kenvLookup("smbios.bios.reldate", &bios->biosDate); - kenvLookup("smbios.system.product", &bios->biosRelease); - kenvLookup("smbios.bios.vendor", &bios->biosVendor); - kenvLookup("smbios.bios.version", &bios->biosVersion); + ffSettingsGetFreeBSDKenv("smbios.bios.reldate", &result->date); + ffCleanUpSmbiosValue(&result->date); + ffSettingsGetFreeBSDKenv("smbios.bios.revision", &result->release); + ffCleanUpSmbiosValue(&result->release); + ffSettingsGetFreeBSDKenv("smbios.bios.vendor", &result->vendor); + ffCleanUpSmbiosValue(&result->vendor); + ffSettingsGetFreeBSDKenv("smbios.bios.version", &result->version); + ffCleanUpSmbiosValue(&result->version); + return NULL; } diff --git a/src/detection/bios/bios_linux.c b/src/detection/bios/bios_linux.c index ce23edf892..fc8cba62b8 100644 --- a/src/detection/bios/bios_linux.c +++ b/src/detection/bios/bios_linux.c @@ -1,58 +1,27 @@ #include "bios.h" #include "common/io/io.h" +#include "util/smbiosHelper.h" #include -static bool hostValueSet(FFstrbuf* value) -{ - return - value->length > 0 && - ffStrbufStartsWithIgnCaseS(value, "To be filled") != true && - ffStrbufStartsWithIgnCaseS(value, "To be set") != true && - ffStrbufStartsWithIgnCaseS(value, "OEM") != true && - ffStrbufStartsWithIgnCaseS(value, "O.E.M.") != true && - ffStrbufIgnCaseCompS(value, "None") != 0 && - ffStrbufIgnCaseCompS(value, "System Product") != 0 && - ffStrbufIgnCaseCompS(value, "System Product Name") != 0 && - ffStrbufIgnCaseCompS(value, "System Product Version") != 0 && - ffStrbufIgnCaseCompS(value, "System Name") != 0 && - ffStrbufIgnCaseCompS(value, "System Version") != 0 && - ffStrbufIgnCaseCompS(value, "Default string") != 0 && - ffStrbufIgnCaseCompS(value, "Undefined") != 0 && - ffStrbufIgnCaseCompS(value, "Not Specified") != 0 && - ffStrbufIgnCaseCompS(value, "Not Applicable") != 0 && - ffStrbufIgnCaseCompS(value, "INVALID") != 0 && - ffStrbufIgnCaseCompS(value, "Type1ProductConfigId") != 0 && - ffStrbufIgnCaseCompS(value, "All Series") != 0 - ; -} - -static void getHostValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) +static void getSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) { ffReadFileBuffer(devicesPath, buffer); - if(hostValueSet(buffer)) + if(ffIsSmbiosValueSet(buffer)) return; ffReadFileBuffer(classPath, buffer); - if(hostValueSet(buffer)) + if(ffIsSmbiosValueSet(buffer)) return; ffStrbufClear(buffer); } -void ffDetectBios(FFBiosResult* bios) +const char* ffDetectBios(FFBiosResult* bios) { - ffStrbufInit(&bios->error); - - ffStrbufInit(&bios->biosDate); - getHostValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->biosDate); - - ffStrbufInit(&bios->biosRelease); - getHostValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->biosRelease); - - ffStrbufInit(&bios->biosVendor); - getHostValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &bios->biosVendor); - - ffStrbufInit(&bios->biosVersion); - getHostValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &bios->biosVersion); + getSmbiosValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->date); + getSmbiosValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->release); + getSmbiosValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &bios->vendor); + getSmbiosValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &bios->version); + return NULL; } diff --git a/src/detection/bios/bios_nosupport.c b/src/detection/bios/bios_nosupport.c deleted file mode 100644 index f8d886182c..0000000000 --- a/src/detection/bios/bios_nosupport.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "bios.h" - -void ffDetectBios(FFBiosResult* bios) -{ - ffStrbufInitS(&bios->error, "Not supported on this platform"); - - ffStrbufInit(&bios->biosDate); - ffStrbufInit(&bios->biosRelease); - ffStrbufInit(&bios->biosVendor); - ffStrbufInit(&bios->biosVersion); -} diff --git a/src/detection/bios/bios_windows.c b/src/detection/bios/bios_windows.c index 7facb2576d..69930a1783 100644 --- a/src/detection/bios/bios_windows.c +++ b/src/detection/bios/bios_windows.c @@ -1,28 +1,28 @@ #include "bios.h" #include "util/windows/registry.h" +#include "util/smbiosHelper.h" -void ffDetectBios(FFBiosResult* bios) +const char* ffDetectBios(FFBiosResult* bios) { - ffStrbufInit(&bios->error); - - ffStrbufInit(&bios->biosDate); - ffStrbufInit(&bios->biosRelease); - ffStrbufInit(&bios->biosVendor); - ffStrbufInit(&bios->biosVersion); - FF_HKEY_AUTO_DESTROY hKey = NULL; - if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &bios->error)) - return; + if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, NULL)) + return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"HARDWARE\\DESCRIPTION\\System\\BIOS\", &hKey, NULL) failed"; - if(!ffRegReadStrbuf(hKey, L"BIOSVersion", &bios->biosRelease, &bios->error)) - return; - ffRegReadStrbuf(hKey, L"BIOSVendor", &bios->biosVendor, NULL); - ffRegReadStrbuf(hKey, L"BIOSReleaseDate", &bios->biosDate, NULL); + if(!ffRegReadStrbuf(hKey, L"BIOSVersion", &bios->version, NULL)) + return "\"HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\BIOSVersion\" doesn't exist"; + + ffCleanUpSmbiosValue(&bios->version); + ffRegReadStrbuf(hKey, L"BIOSVendor", &bios->vendor, NULL); + ffCleanUpSmbiosValue(&bios->vendor); + ffRegReadStrbuf(hKey, L"BIOSReleaseDate", &bios->date, NULL); + ffCleanUpSmbiosValue(&bios->date); uint32_t major, minor; if( ffRegReadUint(hKey, L"BiosMajorRelease", &major, NULL) && ffRegReadUint(hKey, L"BiosMinorRelease", &minor, NULL) ) - ffStrbufAppendF(&bios->biosVersion, "%u.%u", (unsigned)major, (unsigned)minor); + ffStrbufAppendF(&bios->release, "%u.%u", (unsigned)major, (unsigned)minor); + + return NULL; } diff --git a/src/detection/bluetooth/bluetooth.c b/src/detection/bluetooth/bluetooth.c deleted file mode 100644 index f254fe5354..0000000000 --- a/src/detection/bluetooth/bluetooth.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "bluetooth.h" - -#include "../internal.h" - -void ffDetectBluetoothImpl(const FFinstance* instance, FFBluetoothResult* bluetooth); - -const FFBluetoothResult* ffDetectBluetooth(const FFinstance* instance) -{ - FF_DETECTION_INTERNAL_GUARD(FFBluetoothResult, - ffStrbufInit(&result.error); - ffListInit(&result.devices, sizeof(FFBluetoothDevice)); - - ffDetectBluetoothImpl(instance, &result); - ) -} diff --git a/src/detection/bluetooth/bluetooth.h b/src/detection/bluetooth/bluetooth.h index ccd6ecd22f..4aecdfc6f1 100644 --- a/src/detection/bluetooth/bluetooth.h +++ b/src/detection/bluetooth/bluetooth.h @@ -14,12 +14,6 @@ typedef struct FFBluetoothDevice bool connected; } FFBluetoothDevice; -typedef struct FFBluetoothResult -{ - FFstrbuf error; - FFlist devices; // List of FFBluetoothDevice -} FFBluetoothResult; - -const FFBluetoothResult* ffDetectBluetooth(const FFinstance* instance); +const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothDevice */); #endif diff --git a/src/detection/bluetooth/bluetooth_apple.m b/src/detection/bluetooth/bluetooth_apple.m index 8affb90747..d6f3e98784 100644 --- a/src/detection/bluetooth/bluetooth_apple.m +++ b/src/detection/bluetooth/bluetooth_apple.m @@ -2,18 +2,15 @@ #import -void ffDetectBluetoothImpl(FF_MAYBE_UNUSED const FFinstance* instance, FFBluetoothResult* bluetooth) +const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothDevice */) { NSArray* ioDevices = IOBluetoothDevice.pairedDevices; if(!ioDevices) - { - ffStrbufAppendS(&bluetooth->error, "IOBluetoothDevice.pairedDevices failed"); - return; - } + return "IOBluetoothDevice.pairedDevices failed"; for(IOBluetoothDevice* ioDevice in ioDevices) { - FFBluetoothDevice* device = ffListAdd(&bluetooth->devices); + FFBluetoothDevice* device = ffListAdd(devices); ffStrbufInitS(&device->name, ioDevice.name.UTF8String); ffStrbufInitS(&device->address, ioDevice.addressString.UTF8String); ffStrbufInit(&device->type); @@ -90,4 +87,6 @@ void ffDetectBluetoothImpl(FF_MAYBE_UNUSED const FFinstance* instance, FFBluetoo ffStrbufTrimRight(&device->type, ','); } } + + return NULL; } diff --git a/src/detection/bluetooth/bluetooth_linux.c b/src/detection/bluetooth/bluetooth_linux.c index bcfca6e7d5..79f61d5fbd 100644 --- a/src/detection/bluetooth/bluetooth_linux.c +++ b/src/detection/bluetooth/bluetooth_linux.c @@ -1,4 +1,5 @@ #include "bluetooth.h" +#include "util/stringUtils.h" #ifdef FF_HAVE_DBUS #include "common/dbus.h" @@ -59,15 +60,15 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue dbus->lib->ffdbus_message_iter_next(&dictIter); - if(strcmp(deviceProperty, "Address") == 0) + if(ffStrEquals(deviceProperty, "Address")) ffDBusGetValue(dbus, &dictIter, &device->address); - else if(strcmp(deviceProperty, "Name") == 0) + else if(ffStrEquals(deviceProperty, "Name")) ffDBusGetValue(dbus, &dictIter, &device->name); - else if(strcmp(deviceProperty, "Icon") == 0) + else if(ffStrEquals(deviceProperty, "Icon")) ffDBusGetValue(dbus, &dictIter, &device->type); - else if(strcmp(deviceProperty, "Percentage") == 0) + else if(ffStrEquals(deviceProperty, "Percentage")) ffDBusGetByte(dbus, &dictIter, &device->battery); - else if(strcmp(deviceProperty, "Connected") == 0) + else if(ffStrEquals(deviceProperty, "Connected")) ffDBusGetBool(dbus, &dictIter, &device->connected); } @@ -103,7 +104,7 @@ static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFB } } -static void detectBluetoothObject(FFBluetoothResult* bluetooth, FFDBusData* dbus, DBusMessageIter* iter) +static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter) { if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY) return; @@ -129,7 +130,7 @@ static void detectBluetoothObject(FFBluetoothResult* bluetooth, FFDBusData* dbus DBusMessageIter arrayIter; dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter); - FFBluetoothDevice* device = ffListAdd(&bluetooth->devices); + FFBluetoothDevice* device = ffListAdd(devices); ffStrbufInit(&device->name); ffStrbufInit(&device->address); ffStrbufInit(&device->type); @@ -147,11 +148,11 @@ static void detectBluetoothObject(FFBluetoothResult* bluetooth, FFDBusData* dbus ffStrbufDestroy(&device->name); ffStrbufDestroy(&device->address); ffStrbufDestroy(&device->type); - --bluetooth->devices.length; + --devices->length; } } -static void detectBluetoothRoot(FFBluetoothResult* bluetooth, FFDBusData* dbus, DBusMessageIter* iter) +static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter) { if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) return; @@ -161,15 +162,15 @@ static void detectBluetoothRoot(FFBluetoothResult* bluetooth, FFDBusData* dbus, while(true) { - detectBluetoothObject(bluetooth, dbus, &arrayIter); + detectBluetoothObject(devices, dbus, &arrayIter); FF_DBUS_ITER_CONTINUE(dbus, &arrayIter); } } -static const char* detectBluetooth(const FFinstance* instance, FFBluetoothResult* bluetooth) +static const char* detectBluetooth(FFlist* devices) { FFDBusData dbus; - const char* error = ffDBusLoadData(instance, DBUS_BUS_SYSTEM, &dbus); + const char* error = ffDBusLoadData(DBUS_BUS_SYSTEM, &dbus); if(error) return error; @@ -184,7 +185,7 @@ static const char* detectBluetooth(const FFinstance* instance, FFBluetoothResult return "Failed to get root iterator of GetManagedObjects"; } - detectBluetoothRoot(bluetooth, &dbus, &rootIter); + detectBluetoothRoot(devices, &dbus, &rootIter); dbus.lib->ffdbus_message_unref(managedObjects); return NULL; @@ -192,12 +193,11 @@ static const char* detectBluetooth(const FFinstance* instance, FFBluetoothResult #endif -void ffDetectBluetoothImpl(const FFinstance* instance, FFBluetoothResult* bluetooth) +const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothDevice */) { #ifdef FF_HAVE_DBUS - ffStrbufAppendS(&bluetooth->error, detectBluetooth(instance, bluetooth)); + return detectBluetooth(devices); #else - FF_UNUSED(instance); - ffStrbufAppendS(&bluetooth->error, "Fastfetch was compiled without DBus support"); + return "Fastfetch was compiled without DBus support"; #endif } diff --git a/src/detection/bluetooth/bluetooth_nosupport.c b/src/detection/bluetooth/bluetooth_nosupport.c index f8cafe0454..4ae74ac3e8 100644 --- a/src/detection/bluetooth/bluetooth_nosupport.c +++ b/src/detection/bluetooth/bluetooth_nosupport.c @@ -1,6 +1,6 @@ #include "bluetooth.h" -void ffDetectBluetoothImpl(FF_MAYBE_UNUSED const FFinstance* instance, FFBluetoothResult* bluetooth) +const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothDevice */) { - ffStrbufAppendS(&bluetooth->error, "Bluetooth not supported on this platform"); + return "Not supported on this platform"; } diff --git a/src/detection/bluetooth/bluetooth_windows.c b/src/detection/bluetooth/bluetooth_windows.c index 76f0c46d93..0066cebb3a 100644 --- a/src/detection/bluetooth/bluetooth_windows.c +++ b/src/detection/bluetooth/bluetooth_windows.c @@ -7,7 +7,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpointer-sign" -void ffDetectBluetoothImpl(FF_MAYBE_UNUSED const FFinstance* instance, FFBluetoothResult* bluetooth) +const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothDevice */) { BLUETOOTH_DEVICE_SEARCH_PARAMS btsp = { .fReturnConnected = TRUE, @@ -22,10 +22,10 @@ void ffDetectBluetoothImpl(FF_MAYBE_UNUSED const FFinstance* instance, FFBluetoo }; HBLUETOOTH_DEVICE_FIND hFind = BluetoothFindFirstDevice(&btsp, &btdi); if(!hFind) - ffStrbufAppendS(&bluetooth->error, "BluetoothFindFirstDevice() failed or no devices found"); + return "BluetoothFindFirstDevice() failed or no devices found"; do { - FFBluetoothDevice* device = ffListAdd(&bluetooth->devices); + FFBluetoothDevice* device = ffListAdd(devices); ffStrbufInit(&device->name); ffStrbufInit(&device->address); ffStrbufInit(&device->type); @@ -110,6 +110,8 @@ void ffDetectBluetoothImpl(FF_MAYBE_UNUSED const FFinstance* instance, FFBluetoo ffStrbufTrimRight(&device->type, ','); } } while (BluetoothFindNextDevice(hFind, &btdi)); + + return NULL; } #pragma GCC diagnostic pop diff --git a/src/detection/board/board.h b/src/detection/board/board.h index 15044469ea..bc232e244a 100644 --- a/src/detection/board/board.h +++ b/src/detection/board/board.h @@ -7,12 +7,11 @@ typedef struct FFBoardResult { - FFstrbuf boardName; - FFstrbuf boardVendor; - FFstrbuf boardVersion; - FFstrbuf error; + FFstrbuf name; + FFstrbuf vendor; + FFstrbuf version; } FFBoardResult; -void ffDetectBoard(FFBoardResult* result); +const char* ffDetectBoard(FFBoardResult* result); #endif diff --git a/src/detection/board/board_android.c b/src/detection/board/board_android.c new file mode 100644 index 0000000000..64e917e6ad --- /dev/null +++ b/src/detection/board/board_android.c @@ -0,0 +1,9 @@ +#include "board.h" +#include "common/settings.h" + +const char* ffDetectBoard(FFBoardResult* board) +{ + if (!ffSettingsGetAndroidProperty("ro.product.board", &board->name)) + ffSettingsGetAndroidProperty("ro.board.platform", &board->name); + return NULL; +} diff --git a/src/detection/board/board_bsd.c b/src/detection/board/board_bsd.c new file mode 100644 index 0000000000..871cf87aae --- /dev/null +++ b/src/detection/board/board_bsd.c @@ -0,0 +1,14 @@ +#include "board.h" +#include "common/settings.h" +#include "util/smbiosHelper.h" + +const char* ffDetectBoard(FFBoardResult* result) +{ + ffSettingsGetFreeBSDKenv("smbios.planar.product", &result->name); + ffCleanUpSmbiosValue(&result->name); + ffSettingsGetFreeBSDKenv("smbios.planar.maker", &result->vendor); + ffCleanUpSmbiosValue(&result->vendor); + ffSettingsGetFreeBSDKenv("smbios.planar.version", &result->version); + ffCleanUpSmbiosValue(&result->version); + return NULL; +} diff --git a/src/detection/board/board_linux.c b/src/detection/board/board_linux.c index 8f5bcd2ffa..a4d1225b7c 100644 --- a/src/detection/board/board_linux.c +++ b/src/detection/board/board_linux.c @@ -1,55 +1,26 @@ #include "board.h" #include "common/io/io.h" +#include "util/smbiosHelper.h" #include -static bool hostValueSet(FFstrbuf* value) -{ - return - value->length > 0 && - ffStrbufStartsWithIgnCaseS(value, "To be filled") != true && - ffStrbufStartsWithIgnCaseS(value, "To be set") != true && - ffStrbufStartsWithIgnCaseS(value, "OEM") != true && - ffStrbufStartsWithIgnCaseS(value, "O.E.M.") != true && - ffStrbufIgnCaseCompS(value, "None") != 0 && - ffStrbufIgnCaseCompS(value, "System Product") != 0 && - ffStrbufIgnCaseCompS(value, "System Product Name") != 0 && - ffStrbufIgnCaseCompS(value, "System Product Version") != 0 && - ffStrbufIgnCaseCompS(value, "System Name") != 0 && - ffStrbufIgnCaseCompS(value, "System Version") != 0 && - ffStrbufIgnCaseCompS(value, "Default string") != 0 && - ffStrbufIgnCaseCompS(value, "Undefined") != 0 && - ffStrbufIgnCaseCompS(value, "Not Specified") != 0 && - ffStrbufIgnCaseCompS(value, "Not Applicable") != 0 && - ffStrbufIgnCaseCompS(value, "INVALID") != 0 && - ffStrbufIgnCaseCompS(value, "Type1ProductConfigId") != 0 && - ffStrbufIgnCaseCompS(value, "All Series") != 0 - ; -} - -static void getHostValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) +static void getSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) { ffReadFileBuffer(devicesPath, buffer); - if(hostValueSet(buffer)) + if(ffIsSmbiosValueSet(buffer)) return; ffReadFileBuffer(classPath, buffer); - if(hostValueSet(buffer)) + if(ffIsSmbiosValueSet(buffer)) return; ffStrbufClear(buffer); } -void ffDetectBoard(FFBoardResult* board) +const char* ffDetectBoard(FFBoardResult* board) { - ffStrbufInit(&board->error); - - ffStrbufInit(&board->boardName); - getHostValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &board->boardName); - - ffStrbufInit(&board->boardVendor); - getHostValue("/sys/devices/virtual/dmi/id/board_vendor", "/sys/class/dmi/id/board_vendor", &board->boardVendor); - - ffStrbufInit(&board->boardVersion); - getHostValue("/sys/devices/virtual/dmi/id/board_version", "/sys/class/dmi/id/board_version", &board->boardVersion); + getSmbiosValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &board->name); + getSmbiosValue("/sys/devices/virtual/dmi/id/board_vendor", "/sys/class/dmi/id/board_vendor", &board->vendor); + getSmbiosValue("/sys/devices/virtual/dmi/id/board_version", "/sys/class/dmi/id/board_version", &board->version); + return NULL; } diff --git a/src/detection/board/board_nosupport.c b/src/detection/board/board_nosupport.c index 0b182ba3ea..bcf451d5b6 100644 --- a/src/detection/board/board_nosupport.c +++ b/src/detection/board/board_nosupport.c @@ -1,10 +1,6 @@ #include "board.h" -void ffDetectBoard(FFBoardResult* board) +const char* ffDetectBoard(FF_MAYBE_UNUSED FFBoardResult* board) { - ffStrbufInitS(&board->error, "Not supported on this platform"); - - ffStrbufInit(&board->boardName); - ffStrbufInit(&board->boardVendor); - ffStrbufInit(&board->boardVersion); + return "Not supported on this platform"; } diff --git a/src/detection/board/board_windows.c b/src/detection/board/board_windows.c index 4d02b679b7..a2bfce4ff6 100644 --- a/src/detection/board/board_windows.c +++ b/src/detection/board/board_windows.c @@ -1,21 +1,22 @@ #include "board.h" #include "util/windows/registry.h" +#include "util/smbiosHelper.h" -void ffDetectBoard(FFBoardResult* board) +const char* ffDetectBoard(FFBoardResult* board) { - ffStrbufInit(&board->error); + FF_HKEY_AUTO_DESTROY hKey = NULL; - ffStrbufInit(&board->boardName); - ffStrbufInit(&board->boardVendor); - ffStrbufInit(&board->boardVersion); + if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, NULL)) + return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"HARDWARE\\DESCRIPTION\\System\\BIOS\") failed"; - FF_HKEY_AUTO_DESTROY hKey = NULL; + if(!ffRegReadStrbuf(hKey, L"BaseBoardProduct", &board->name, NULL)) + return "ffRegReadStrbuf(hKey, L\"BaseBoardProduct\") failed"; - if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &board->error)) - return; + ffCleanUpSmbiosValue(&board->name); + ffRegReadStrbuf(hKey, L"BaseBoardManufacturer", &board->vendor, NULL); + ffCleanUpSmbiosValue(&board->vendor); + ffRegReadStrbuf(hKey, L"BaseBoardVersion", &board->version, NULL); + ffCleanUpSmbiosValue(&board->version); - if(!ffRegReadStrbuf(hKey, L"BaseBoardProduct", &board->boardName, &board->error)) - return; - ffRegReadStrbuf(hKey, L"BaseBoardManufacturer", &board->boardVendor, NULL); - ffRegReadStrbuf(hKey, L"BaseBoardVersion", &board->boardVersion, NULL); + return NULL; } diff --git a/src/detection/brightness/brightness_apple.c b/src/detection/brightness/brightness_apple.c index b318e0a6ad..eaa21cdf06 100644 --- a/src/detection/brightness/brightness_apple.c +++ b/src/detection/brightness/brightness_apple.c @@ -1,51 +1,115 @@ #include "brightness.h" +#include "detection/displayserver/displayserver.h" #include "util/apple/cf_helpers.h" - -#include +#include "util/apple/ddcci.h" +#include "util/edidHelper.h" extern int DisplayServicesGetBrightness(CGDirectDisplayID display, float *brightness) __attribute__((weak_import)); -extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import)); -const char* ffDetectBrightness(FFlist* result) +// Works for internal display +static const char* detectWithDisplayServices(const FFDisplayServerResult* displayServer, FFlist* result) { if(DisplayServicesGetBrightness == NULL) return "DisplayServices function DisplayServicesGetBrightness is not available"; - CGDirectDisplayID screens[128]; - uint32_t screenCount; - if(CGGetOnlineDisplayList(sizeof(screens) / sizeof(screens[0]), screens, &screenCount) != kCGErrorSuccess) - return "CGGetOnlineDisplayList() failed"; + FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays) + { + if (display->type == FF_DISPLAY_TYPE_BUILTIN || display->type == FF_DISPLAY_TYPE_UNKNOWN) + { + float value; + if(DisplayServicesGetBrightness((CGDirectDisplayID) display->id, &value) == kCGErrorSuccess) + { + FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result); + brightness->value = value * 100; + ffStrbufInitCopy(&brightness->name, &display->name); + } + } + } - for(uint32_t i = 0; i < screenCount; i++) + return NULL; +} + +// https://github.com/waydabber/m1ddc +// Works for Apple Silicon and USB-C adapter connection ( but not HTMI ) +static const char* detectWithDdcci(FFlist* result) +{ + if (!IOAVServiceCreate || !IOAVServiceReadI2C) + return "IOAVService is not available"; + + CFMutableDictionaryRef matchDict = IOServiceMatching("DCPAVServiceProxy"); + if (matchDict == NULL) + return "IOServiceMatching(\"DCPAVServiceProxy\") failed"; + + io_iterator_t iterator; + if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess) + return "IOServiceGetMatchingServices() failed"; + + FF_STRBUF_AUTO_DESTROY location = ffStrbufCreate(); + + io_registry_entry_t registryEntry; + while((registryEntry = IOIteratorNext(iterator)) != 0) { - CGDirectDisplayID screen = screens[i]; - float brightness; - if(DisplayServicesGetBrightness(screen, &brightness) != kCGErrorSuccess) + CFMutableDictionaryRef properties; + if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) + { + IOObjectRelease(registryEntry); continue; + } - FFBrightnessResult* display = (FFBrightnessResult*) ffListAdd(result); - display->value = brightness * 100; - ffStrbufInit(&display->name); + ffStrbufClear(&location); + if(ffCfDictGetString(properties, CFSTR("Location"), &location) || ffStrbufEqualS(&location, "Embedded")) + { + // Builtin display should be handled by DisplayServices + IOObjectRelease(registryEntry); + continue; + } + + FF_CFTYPE_AUTO_RELEASE IOAVServiceRef service = IOAVServiceCreateWithService(kCFAllocatorDefault, (io_service_t) registryEntry); + IOObjectRelease(registryEntry); + + if (!service) continue; - if(CoreDisplay_DisplayCreateInfoDictionary) { - CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary(screen); - if(displayInfo) + uint8_t i2cIn[4] = { 0x82, 0x01, 0x10 /* luminance */ }; + i2cIn[3] = 0x6e ^ i2cIn[0] ^ i2cIn[1] ^ i2cIn[2]; + + for (uint32_t i = 0; i < 2; ++i) { - CFDictionaryRef productNames; - if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames)) - { - if(!ffCfDictGetString(productNames, CFSTR("en_US"), &display->name)) - continue; - } + IOAVServiceWriteI2C(service, 0x37, 0x51, i2cIn, sizeof(i2cIn)); + usleep(10000); } } - if(CGDisplayIsBuiltin(screen)) - ffStrbufAppendS(&display->name, "built-in"); - else - ffStrbufAppendF(&display->name, "external-%u", (unsigned) screen); + uint8_t i2cOut[12] = {}; + if (IOAVServiceReadI2C(service, 0x37, 0x51, i2cOut, sizeof(i2cOut)) == KERN_SUCCESS) + { + if (i2cOut[2] != 0x02 || i2cOut[3] != 0x00) + continue; + + uint32_t current = ((uint32_t) i2cOut[8] << 8u) + (uint32_t) i2cOut[9]; + uint32_t max = ((uint32_t) i2cOut[6] << 8u) + (uint32_t) i2cOut[7]; + + FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result); + brightness->value = (float) current * 100.f / max; + ffStrbufInit(&brightness->name); + + uint8_t edid[128] = {}; + if (IOAVServiceReadI2C(service, 0x50, 0x00, edid, sizeof(edid)) == KERN_SUCCESS) + ffEdidGetName(edid, &brightness->name); + } } return NULL; } + +const char* ffDetectBrightness(FFlist* result) +{ + const FFDisplayServerResult* displayServer = ffConnectDisplayServer(); + + detectWithDisplayServices(displayServer, result); + + if (instance.config.allowSlowOperations && displayServer->displays.length > result->length) + detectWithDdcci(result); + + return NULL; +} diff --git a/src/detection/brightness/brightness_bsd.c b/src/detection/brightness/brightness_bsd.c new file mode 100644 index 0000000000..8c6a89e2f8 --- /dev/null +++ b/src/detection/brightness/brightness_bsd.c @@ -0,0 +1,47 @@ +#include "brightness.h" + +#if __has_include() + +#include "common/io/io.h" + +#include +#include +#include +#include + +const char* ffDetectBrightness(FFlist* result) +{ + // https://man.freebsd.org/cgi/man.cgi?query=backlight&sektion=9 + char path[] = "/dev/backlight/backlight0"; + + for (char i = '0'; i <= '9'; ++i) + { + path[sizeof(path) - 2] = i; + + FF_AUTO_CLOSE_FD int blfd = open(path, O_RDONLY); + if (blfd < 0) + continue; + + struct backlight_props status; + if(ioctl(blfd, BACKLIGHTGETSTATUS, &status) < 0) + continue; + + FFBrightnessResult* display = (FFBrightnessResult*) ffListAdd(result); + ffStrbufInit(&display->name); + display->value = (float) status.brightness / BACKLIGHTMAXLEVELS; + + struct backlight_info info; + if(ioctl(blfd, BACKLIGHTGETINFO, &info) < 0) + ffStrbufAppendS(&display->name, info.name); + } + return NULL; +} + +#else + +const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result) +{ + return "Backlight is supported only on FreeBSD 13 and newer"; +} + +#endif \ No newline at end of file diff --git a/src/detection/brightness/brightness_linux.c b/src/detection/brightness/brightness_linux.c index a8fd4ed4b3..5168dd0d6e 100644 --- a/src/detection/brightness/brightness_linux.c +++ b/src/detection/brightness/brightness_linux.c @@ -1,11 +1,13 @@ #include "brightness.h" #include "common/io/io.h" +#include "util/edidHelper.h" +#include "util/stringUtils.h" #include #include #include -const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result) +static const char* detectWithBacklight(FFlist* result) { //https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-class-backlight const char* backlightDirPath = "/sys/class/backlight/"; @@ -14,19 +16,17 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result) if(dirp == NULL) return "Failed to open `/sys/class/backlight/`"; - FF_STRBUF_AUTO_DESTROY backlightDir; - ffStrbufInitA(&backlightDir, 64); + FF_STRBUF_AUTO_DESTROY backlightDir = ffStrbufCreateA(64); ffStrbufAppendS(&backlightDir, backlightDirPath); uint32_t backlightDirLength = backlightDir.length; - FF_STRBUF_AUTO_DESTROY buffer; - ffStrbufInit(&buffer); + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); struct dirent* entry; while((entry = readdir(dirp)) != NULL) { - if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, "..")) continue; ffStrbufAppendS(&backlightDir, entry->d_name); @@ -39,21 +39,41 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result) ffStrbufAppendS(&backlightDir, "/max_brightness"); if(ffReadFileBuffer(backlightDir.chars, &buffer)) { - FFBrightnessResult* display = (FFBrightnessResult*) ffListAdd(result); + FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result); ffStrbufSubstrBeforeLastC(&backlightDir, '/'); ffStrbufAppendS(&backlightDir, "/device"); - ffStrbufInitA(&display->name, PATH_MAX + 1); - if(realpath(backlightDir.chars, display->name.chars)) + ffStrbufInitA(&brightness->name, PATH_MAX + 1); + if(realpath(backlightDir.chars, brightness->name.chars)) { - ffStrbufRecalculateLength(&display->name); - ffStrbufSubstrAfterLastC(&display->name, '/'); - if(ffStrbufStartsWithS(&display->name, "card") && isdigit(display->name.chars[4])) - ffStrbufSubstrAfterFirstC(&display->name, '-'); + ffStrbufRecalculateLength(&brightness->name); + // if we managed to get edid, use it + ffStrbufAppendS(&brightness->name, "/edid"); + uint8_t edidData[128]; + if(ffReadFileData(brightness->name.chars, sizeof(edidData), edidData) == sizeof(edidData)) + { + ffStrbufClear(&brightness->name); + ffEdidGetName(edidData, &brightness->name); + } + else + { + ffStrbufSubstrBeforeLastC(&brightness->name, '/'); // remove "/edid" + ffStrbufSubstrAfterLastC(&brightness->name, '/'); // try getting DRM connector name + if(ffStrbufStartsWithS(&brightness->name, "0000:")) + { + // PCI address, give up + ffStrbufSetS(&brightness->name, entry->d_name); + } + else + { + if(ffStrbufStartsWithS(&brightness->name, "card") && isdigit(brightness->name.chars[4])) + ffStrbufSubstrAfterFirstC(&brightness->name, '-'); + } + } } else - ffStrbufInitS(&display->name, entry->d_name); + ffStrbufInitS(&brightness->name, entry->d_name); double maxBrightness = ffStrbufToDouble(&buffer); - display->value = (float) (actualBrightness * 100 / maxBrightness); + brightness->value = (float) (actualBrightness * 100 / maxBrightness); } } ffStrbufSubstrBefore(&backlightDir, backlightDirLength); @@ -63,3 +83,69 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result) return NULL; } + +#ifdef FF_HAVE_DDCUTIL +#include "detection/displayserver/displayserver.h" +#include "common/library.h" +#include "util/mallocHelper.h" + +#include + +static const char* detectWithDdcci(FFlist* result) +{ + FF_LIBRARY_LOAD(libddcutil, &instance.config.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 4); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info_list2) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_open_display2) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_any_vcp_value_using_explicit_type) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_free_any_vcp_value) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_close_display) + libddcutil = NULL; // Don't dlclose libddcutil. See https://github.com/rockowitz/ddcutil/issues/330 + + FF_AUTO_FREE DDCA_Display_Info_List* infoList = NULL; + if (__builtin_expect(ffddca_get_display_info_list2(false, &infoList) < 0, 0)) + return "ddca_get_display_info_list2(false, &infoList) failed"; + + if (infoList->ct == 0) + return "No DDC/CI compatible displays found"; + + for (int index = 0; index < infoList->ct; ++index) + { + const DDCA_Display_Info* display = &infoList->info[index]; + + DDCA_Display_Handle handle; + if (ffddca_open_display2(display->dref, false, &handle) >= 0) + { + DDCA_Any_Vcp_Value* vcpValue = NULL; + if (ffddca_get_any_vcp_value_using_explicit_type(handle, 0x10 /*brightness*/, DDCA_NON_TABLE_VCP_VALUE, &vcpValue) >= 0) + { + assert(vcpValue->value_type == DDCA_NON_TABLE_VCP_VALUE); + int current = VALREC_CUR_VAL(vcpValue), max = VALREC_MAX_VAL(vcpValue); + ffddca_free_any_vcp_value(vcpValue); + + FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result); + brightness->value = (float) current * 100.f / (float) max; + ffStrbufInitS(&brightness->name, display->model_name); + } + ffddca_close_display(handle); + } + } + + return NULL; +} +#endif + +const char* ffDetectBrightness(FFlist* result) +{ + detectWithBacklight(result); + + #ifdef FF_HAVE_DDCUTIL + if (instance.config.allowSlowOperations) + { + const FFDisplayServerResult* displayServer = ffConnectDisplayServer(); + if (result->length < displayServer->displays.length) + detectWithDdcci(result); + } + #endif + + return NULL; +} diff --git a/src/detection/brightness/brightness_windows.cpp b/src/detection/brightness/brightness_windows.cpp index 3139fef4c7..dcde38502d 100644 --- a/src/detection/brightness/brightness_windows.cpp +++ b/src/detection/brightness/brightness_windows.cpp @@ -1,11 +1,15 @@ extern "C" { #include "brightness.h" +#include "detection/displayserver/displayserver.h" } #include "util/windows/wmi.hpp" +#include "util/windows/unicode.hpp" -extern "C" -const char* ffDetectBrightness(FFlist* result) +#include +#include + +static const char* detectWithWmi(FFlist* result) { FFWmiQuery query(L"SELECT CurrentBrightness, InstanceName FROM WmiMonitorBrightness WHERE Active = true", nullptr, FFWmiNamespace::WMI); if(!query) @@ -13,15 +17,66 @@ const char* ffDetectBrightness(FFlist* result) while(FFWmiRecord record = query.next()) { - FFBrightnessResult* display = (FFBrightnessResult*) ffListAdd(result); - ffStrbufInit(&display->name); - record.getString(L"InstanceName", &display->name); - ffStrbufSubstrAfterFirstC(&display->name, '\\'); - ffStrbufSubstrBeforeFirstC(&display->name, '\\'); - - uint64_t brightness; - record.getUnsigned(L"CurrentBrightness", &brightness); - display->value = (float) brightness; + if(FFWmiVariant vtValue = record.get(L"CurrentBrightness")) + { + FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result); + brightness->value = vtValue.get(); + + ffStrbufInit(&brightness->name); + if (FFWmiVariant vtName = record.get(L"InstanceName")) + { + ffStrbufSetWSV(&brightness->name, vtName.get()); + ffStrbufSubstrAfterFirstC(&brightness->name, '\\'); + ffStrbufSubstrBeforeFirstC(&brightness->name, '\\'); + } + } } return NULL; } + +static char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFlist* result) +{ + FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays) + { + PHYSICAL_MONITOR physicalMonitor; + if (GetPhysicalMonitorsFromHMONITOR((HMONITOR)(uintptr_t) display->id, 1, &physicalMonitor)) + { + DWORD min = 0, curr = 0, max = 0; + if (GetMonitorBrightness(physicalMonitor.hPhysicalMonitor, &min, &curr, &max)) + { + FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result); + + if (display->name.length) + ffStrbufInitCopy(&brightness->name, &display->name); + else + ffStrbufInitWS(&brightness->name, physicalMonitor.szPhysicalMonitorDescription); + + brightness->value = (float) (curr - min) * 100.f / (float) (max - min); + } + } + } + return NULL; +} + +static bool hasBuiltinDisplay(const FFDisplayServerResult* displayServer) +{ + FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays) + { + if (display->type == FF_DISPLAY_TYPE_BUILTIN || display->type == FF_DISPLAY_TYPE_UNKNOWN) + return true; + } + return false; +} + +extern "C" +const char* ffDetectBrightness(FFlist* result) +{ + const FFDisplayServerResult* displayServer = ffConnectDisplayServer(); + + if (hasBuiltinDisplay(displayServer)) + detectWithWmi(result); + + if (instance.config.allowSlowOperations && result->length < displayServer->displays.length) + detectWithDdcci(displayServer, result); + return NULL; +} diff --git a/src/detection/chassis/chassis.c b/src/detection/chassis/chassis.c new file mode 100644 index 0000000000..f2ebc2da1d --- /dev/null +++ b/src/detection/chassis/chassis.c @@ -0,0 +1,46 @@ +#include "chassis.h" + +const char* ffChassisTypeToString(uint32_t type) +{ + // https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.2.0.pdf + // 7.4.1 System Enclosure or Chassis Types + switch (type) + { + case 0x01: return "Other"; + case 0x02: return "Unknown"; + case 0x03: return "Desktop"; + case 0x04: return "Low Profile Desktop"; + case 0x05: return "Pizza Box"; + case 0x06: return "Mini Tower"; + case 0x07: return "Tower"; + case 0x08: return "Portable"; + case 0x09: return "Laptop"; + case 0x0A: return "Notebook"; + case 0x0B: return "Hand Held"; + case 0x0C: return "Docking Station"; + case 0x0D: return "All in One"; + case 0x0E: return "Sub Notebook"; + case 0x0F: return "Space-saving"; + case 0x10: return "Lunch Box"; + case 0x11: return "Main Server Chassis"; + case 0x12: return "Expansion Chassis"; + case 0x13: return "SubChassis"; + case 0x14: return "Bus Expansion Chassis"; + case 0x15: return "Peripheral Chassis"; + case 0x16: return "RAID Chassis"; + case 0x17: return "Rack Mount Chassis"; + case 0x18: return "Sealed-case PC"; + case 0x19: return "Multi-system chassis"; + case 0x1A: return "Compact PCI"; + case 0x1B: return "Advanced TCA"; + case 0x1C: return "Blade"; + case 0x1E: return "Tablet"; + case 0x1F: return "Convertible"; + case 0x20: return "Detachable"; + case 0x21: return "IoT Gateway"; + case 0x22: return "Embedded PC"; + case 0x23: return "Mini PC"; + case 0x24: return "Stick PC"; + default: return NULL; + } +} diff --git a/src/detection/chassis/chassis.h b/src/detection/chassis/chassis.h index eb6ce4c6ca..876936c8db 100644 --- a/src/detection/chassis/chassis.h +++ b/src/detection/chassis/chassis.h @@ -7,12 +7,12 @@ typedef struct FFChassisResult { - FFstrbuf chassisType; - FFstrbuf chassisVendor; - FFstrbuf chassisVersion; - FFstrbuf error; + FFstrbuf type; + FFstrbuf vendor; + FFstrbuf version; } FFChassisResult; -void ffDetectChassis(FFChassisResult* result); +const char* ffDetectChassis(FFChassisResult* result); +const char* ffChassisTypeToString(uint32_t type); #endif diff --git a/src/detection/chassis/chassis_bsd.c b/src/detection/chassis/chassis_bsd.c new file mode 100644 index 0000000000..c38b562c2d --- /dev/null +++ b/src/detection/chassis/chassis_bsd.c @@ -0,0 +1,15 @@ +#include "chassis.h" +#include "common/settings.h" +#include "util/smbiosHelper.h" + +const char* ffDetectChassis(FFChassisResult* result) +{ + // Unlike other platforms, `smbios.chassis.type` return display string directly on my machine + ffSettingsGetFreeBSDKenv("smbios.chassis.type", &result->type); + ffCleanUpSmbiosValue(&result->type); + ffSettingsGetFreeBSDKenv("smbios.chassis.maker", &result->vendor); + ffCleanUpSmbiosValue(&result->vendor); + ffSettingsGetFreeBSDKenv("smbios.chassis.version", &result->version); + ffCleanUpSmbiosValue(&result->version); + return NULL; +} diff --git a/src/detection/chassis/chassis_linux.c b/src/detection/chassis/chassis_linux.c index 0898fa4b82..deace35d91 100644 --- a/src/detection/chassis/chassis_linux.c +++ b/src/detection/chassis/chassis_linux.c @@ -1,55 +1,33 @@ #include "chassis.h" #include "common/io/io.h" +#include "util/smbiosHelper.h" #include -static bool hostValueSet(FFstrbuf* value) -{ - return - value->length > 0 && - ffStrbufStartsWithIgnCaseS(value, "To be filled") != true && - ffStrbufStartsWithIgnCaseS(value, "To be set") != true && - ffStrbufStartsWithIgnCaseS(value, "OEM") != true && - ffStrbufStartsWithIgnCaseS(value, "O.E.M.") != true && - ffStrbufIgnCaseCompS(value, "None") != 0 && - ffStrbufIgnCaseCompS(value, "System Product") != 0 && - ffStrbufIgnCaseCompS(value, "System Product Name") != 0 && - ffStrbufIgnCaseCompS(value, "System Product Version") != 0 && - ffStrbufIgnCaseCompS(value, "System Name") != 0 && - ffStrbufIgnCaseCompS(value, "System Version") != 0 && - ffStrbufIgnCaseCompS(value, "Default string") != 0 && - ffStrbufIgnCaseCompS(value, "Undefined") != 0 && - ffStrbufIgnCaseCompS(value, "Not Specified") != 0 && - ffStrbufIgnCaseCompS(value, "Not Applicable") != 0 && - ffStrbufIgnCaseCompS(value, "INVALID") != 0 && - ffStrbufIgnCaseCompS(value, "Type1ProductConfigId") != 0 && - ffStrbufIgnCaseCompS(value, "All Series") != 0 - ; -} - -static void getHostValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) +static void getSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) { ffReadFileBuffer(devicesPath, buffer); - if(hostValueSet(buffer)) + if(ffIsSmbiosValueSet(buffer)) return; ffReadFileBuffer(classPath, buffer); - if(hostValueSet(buffer)) + if(ffIsSmbiosValueSet(buffer)) return; ffStrbufClear(buffer); } -void ffDetectChassis(FFChassisResult* result) +const char* ffDetectChassis(FFChassisResult* result) { - ffStrbufInit(&result->error); - - ffStrbufInit(&result->chassisType); - getHostValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &result->chassisType); - - ffStrbufInit(&result->chassisVendor); - getHostValue("/sys/devices/virtual/dmi/id/chassis_vendor", "/sys/class/dmi/id/chassis_vendor", &result->chassisVendor); - - ffStrbufInit(&result->chassisVersion); - getHostValue("/sys/devices/virtual/dmi/id/chassis_version", "/sys/class/dmi/id/chassis_version", &result->chassisVersion); + getSmbiosValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &result->type); + getSmbiosValue("/sys/devices/virtual/dmi/id/chassis_vendor", "/sys/class/dmi/id/chassis_vendor", &result->vendor); + getSmbiosValue("/sys/devices/virtual/dmi/id/chassis_version", "/sys/class/dmi/id/chassis_version", &result->version); + + if(result->type.length) + { + const char* typeStr = ffChassisTypeToString(ffStrbufToUInt16(&result->type, 9999)); + if(typeStr) + ffStrbufSetS(&result->type, typeStr); + } + return NULL; } diff --git a/src/detection/chassis/chassis_nosupport.c b/src/detection/chassis/chassis_nosupport.c index 42c182567f..c2acd75790 100644 --- a/src/detection/chassis/chassis_nosupport.c +++ b/src/detection/chassis/chassis_nosupport.c @@ -1,10 +1,6 @@ #include "chassis.h" -void ffDetectChassis(FFChassisResult* result) +const char* ffDetectChassis(FF_MAYBE_UNUSED FFChassisResult* result) { - ffStrbufInitS(&result->error, "Not supported on this platform"); - - ffStrbufInit(&result->chassisType); - ffStrbufInit(&result->chassisVendor); - ffStrbufInit(&result->chassisVersion); + return "Not supported on this platform"; } diff --git a/src/detection/chassis/chassis_windows.cpp b/src/detection/chassis/chassis_windows.cpp new file mode 100644 index 0000000000..2332c5b31c --- /dev/null +++ b/src/detection/chassis/chassis_windows.cpp @@ -0,0 +1,73 @@ +extern "C" { +#include "chassis.h" +#include "util/windows/registry.h" +#include "util/smbiosHelper.h" +} +#include "util/windows/unicode.hpp" +#include "util/windows/wmi.hpp" + +static const char* detectWithRegistry(FFChassisResult* result) +{ + FF_HKEY_AUTO_DESTROY hKey = NULL; + if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, NULL)) // SMBIOS + return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"HARDWARE\\DESCRIPTION\\System\\BIOS\", &hKey, NULL) failed"; + + uint32_t type = 0; + if(!ffRegReadUint(hKey, L"EnclosureType", &type, NULL)) + return "\"HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\EnclosureType\" doesn't exist"; + + const char* typeStr = ffChassisTypeToString(type); + if(!typeStr) + return "Unknown chassis type"; + + ffStrbufAppendS(&result->type, typeStr); + return NULL; +} + +FF_MAYBE_UNUSED static const char* detectWithWmi(FFChassisResult* result) +{ + FFWmiQuery query(L"SELECT Version, ChassisTypes, Manufacturer FROM Win32_SystemEnclosure"); + if (!query) + return "Query WMI service failed"; + + if (FFWmiRecord record = query.next()) + { + if (auto vtProp = record.get(L"ChassisTypes")) + { + auto [arr, len] = vtProp.get>(); + if(len == 0) + return "ChassisTypes contain no data failed"; + for (uint32_t i = 0; i < len; ++i) + { + if (i > 0) + ffStrbufAppendS(&result->type, ", "); + ffStrbufAppendS(&result->type, ffChassisTypeToString((uint32_t) arr[i])); + } + } + else + return "Get ChassisTypes failed"; + + if (auto vtProp = record.get(L"Version")) + { + ffStrbufSetWSV(&result->version, vtProp.get()); + ffCleanUpSmbiosValue(&result->version); + } + + if (auto vtProp = record.get(L"Manufacturer")) + { + ffStrbufSetWSV(&result->vendor, vtProp.get()); + ffCleanUpSmbiosValue(&result->vendor); + } + + return NULL; + } + return "No WMI result returned"; +} + +extern "C" +const char* ffDetectChassis(FFChassisResult* result) +{ + if (instance.config.allowSlowOperations) + return detectWithWmi(result); + return detectWithRegistry(result); +} diff --git a/src/detection/cpu/cpu.c b/src/detection/cpu/cpu.c index 62537aaa80..b95a354ad4 100644 --- a/src/detection/cpu/cpu.c +++ b/src/detection/cpu/cpu.c @@ -1,13 +1,12 @@ #include "cpu.h" #include "detection/internal.h" -void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu); -static void detectCPU(const FFinstance* instance, FFCPUResult* cpu) -{ - ffStrbufInit(&cpu->name); - ffStrbufInit(&cpu->vendor); +const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu); - ffDetectCPUImpl(instance, cpu); +const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu) +{ + const char* error = ffDetectCPUImpl(options, cpu); + if (error) return error; const char* removeStrings[] = { " CPU", " FPU", " APU", " Processor", @@ -15,14 +14,8 @@ static void detectCPU(const FFinstance* instance, FFCPUResult* cpu) " 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core", " with Radeon Graphics" }; - ffStrbufRemoveStringsA(&cpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings); + ffStrbufRemoveStrings(&cpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings); ffStrbufSubstrBeforeFirstC(&cpu->name, '@'); //Cut the speed output in the name as we append our own ffStrbufTrimRight(&cpu->name, ' '); //If we removed the @ in previous step there was most likely a space before it -} - -const FFCPUResult* ffDetectCPU(const FFinstance* instance) -{ - FF_DETECTION_INTERNAL_GUARD(FFCPUResult, - detectCPU(instance, &result); - ); + return NULL; } diff --git a/src/detection/cpu/cpu.h b/src/detection/cpu/cpu.h index afe05909e3..7dd1c29d26 100644 --- a/src/detection/cpu/cpu.h +++ b/src/detection/cpu/cpu.h @@ -22,6 +22,6 @@ typedef struct FFCPUResult double temperature; } FFCPUResult; -const FFCPUResult* ffDetectCPU(const FFinstance* instance); +const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu); #endif diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index 3de61f93dc..9dcb07edd1 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -15,37 +15,26 @@ static double getFrequency(const char* propName) static double detectCpuTemp(const FFstrbuf* cpuName) { - FF_LIST_AUTO_DESTROY temps; - ffListInit(&temps, sizeof(FFTempValue)); + double result = 0; + const char* error = NULL; if(ffStrbufStartsWithS(cpuName, "Apple M1")) - ffDetectCoreTemps(FF_TEMP_CPU_M1X, &temps); + error = ffDetectCoreTemps(FF_TEMP_CPU_M1X, &result); else if(ffStrbufStartsWithS(cpuName, "Apple M2")) - ffDetectCoreTemps(FF_TEMP_CPU_M2X, &temps); - else //TODO: PPC? - ffDetectCoreTemps(FF_TEMP_CPU_X64, &temps); + error = ffDetectCoreTemps(FF_TEMP_CPU_M2X, &result); + else // PPC? + error = ffDetectCoreTemps(FF_TEMP_CPU_X64, &result); - if(temps.length == 0) + if(error) return FF_CPU_TEMP_UNSET; - double result = 0; - for(uint32_t i = 0; i < temps.length; ++i) - { - FFTempValue* tempValue = (FFTempValue*)ffListGet(&temps, i); - result += tempValue->value; - //TODO: do we really need this? - ffStrbufDestroy(&tempValue->name); - ffStrbufDestroy(&tempValue->deviceClass); - } - result /= temps.length; return result; } -void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) +const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) { - FF_UNUSED(instance); - - ffSysctlGetString("machdep.cpu.brand_string", &cpu->name); + if (ffSysctlGetString("machdep.cpu.brand_string", &cpu->name) != NULL) + return "sysctlbyname(machdep.cpu.brand_string) failed"; ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor); cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu_max", 1); @@ -65,8 +54,7 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) if(cpu->frequencyMax == 0.0) cpu->frequencyMax = getFrequency("hw.cpufrequency"); - if (instance->config.cpuTemp) - cpu->temperature = detectCpuTemp(&cpu->name); - else - cpu->temperature = FF_CPU_TEMP_UNSET; + cpu->temperature = options->temp ? detectCpuTemp(&cpu->name) : FF_CPU_TEMP_UNSET; + + return NULL; } diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index 0ae8010b1c..835bdd4f6a 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -1,22 +1,11 @@ #include "cpu.h" #include "common/sysctl.h" +#include "detection/temps/temps_bsd.h" -void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) +const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) { - FF_UNUSED(instance); - - if (instance->config.cpuTemp) - { - FF_STRBUF_AUTO_DESTROY cpuTemp = ffStrbufCreate(); - if(ffSysctlGetString("hw.acpi.thermal.tz0.temperature", &cpuTemp)) - cpu->temperature = FF_CPU_TEMP_UNSET; - else - cpu->temperature = ffStrbufToDouble(&cpuTemp); - } - else - cpu->temperature = FF_CPU_TEMP_UNSET; - - ffSysctlGetString("hw.model", &cpu->name); + if (ffSysctlGetString("hw.model", &cpu->name)) + return "sysctlbyname(hw.model) failed"; cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1); cpu->coresLogical = cpu->coresPhysical; @@ -24,4 +13,10 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) cpu->frequencyMin = ffSysctlGetInt("hw.clockrate", 0) / 1000.0; cpu->frequencyMax = cpu->frequencyMin; + cpu->temperature = FF_CPU_TEMP_UNSET; + + if (options->temp) + ffDetectThermalTemp(&cpu->temperature); + + return NULL; } diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 202317033d..bdffc755ff 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -2,18 +2,34 @@ #include "common/io/io.h" #include "common/properties.h" #include "detection/temps/temps_linux.h" +#include "util/mallocHelper.h" #include #include #include -static void parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuMHz, FFstrbuf* cpuIsa, FFstrbuf* cpuUarch) +#ifdef __ANDROID__ +#include "common/settings.h" + +static void detectAndroid(FFCPUResult* cpu) +{ + if (cpu->name.length == 0) + ffSettingsGetAndroidProperty("ro.soc.model", &cpu->name); + if (cpu->vendor.length == 0) + { + if (!ffSettingsGetAndroidProperty("ro.soc.manufacturer", &cpu->vendor)) + ffSettingsGetAndroidProperty("ro.product.product.manufacturer", &cpu->vendor); + } +} +#endif + +static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuMHz, FFstrbuf* cpuIsa, FFstrbuf* cpuUarch) { - FILE* cpuinfo = fopen("/proc/cpuinfo", "r"); + FF_AUTO_CLOSE_FILE FILE* cpuinfo = fopen("/proc/cpuinfo", "r"); if(cpuinfo == NULL) - return; + return "fopen(\"/proc/cpuinfo\", \"r\") failed"; - char* line = NULL; + FF_AUTO_FREE char* line = NULL; size_t len = 0; while(getline(&line, &len, cpuinfo) != -1) @@ -29,24 +45,20 @@ static void parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrb ffParsePropLine(line, "cpu MHz :", cpuMHz) || ffParsePropLine(line, "isa :", cpuIsa) || ffParsePropLine(line, "uarch :", cpuUarch) || - (cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) //For Android devices + (cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices + (cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) //For POWER ); } - if(line != NULL) - free(line); - - fclose(cpuinfo); + return NULL; } static double getGHz(const char* file) { - FFstrbuf content; - ffStrbufInit(&content); + FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate(); if(ffAppendFileBuffer(file, &content)) { double herz = ffStrbufToDouble(&content); - ffStrbufDestroy(&content); //ffStrbufToDouble failed if(herz != herz) @@ -104,26 +116,17 @@ static void parseIsa(FFstrbuf* cpuIsa) } } -void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) +const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) { - if(instance->config.cpuTemp) - cpu->temperature = detectCPUTemp(); - else - cpu->temperature = FF_CPU_TEMP_UNSET; - - FFstrbuf physicalCoresBuffer; - ffStrbufInit(&physicalCoresBuffer); + cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET; - FFstrbuf cpuMHz; - ffStrbufInit(&cpuMHz); + FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate(); - FFstrbuf cpuIsa; - ffStrbufInit(&cpuIsa); - - FFstrbuf cpuUarch; - ffStrbufInit(&cpuUarch); - - parseCpuInfo(cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch); + const char* error = parseCpuInfo(cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch); + if (error) return error; cpu->coresPhysical = ffStrbufToUInt16(&physicalCoresBuffer, 1); @@ -156,8 +159,9 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) ffStrbufAppend(&cpu->name, &cpuIsa); } - ffStrbufDestroy(&physicalCoresBuffer); - ffStrbufDestroy(&cpuMHz); - ffStrbufDestroy(&cpuIsa); - ffStrbufDestroy(&cpuUarch); + #ifdef __ANDROID__ + detectAndroid(cpu); + #endif + + return NULL; } diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index b38d5bb637..231ea342e4 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -3,23 +3,18 @@ #include "util/windows/registry.h" #include "util/mallocHelper.h" -void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) +const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) { - FF_UNUSED(instance); - - cpu->temperature = FF_CPU_TEMP_UNSET; - cpu->coresPhysical = cpu->coresLogical = cpu->coresOnline = 0; - cpu->frequencyMax = cpu->frequencyMin = 0; - ffStrbufInit(&cpu->name); - ffStrbufInit(&cpu->vendor); - { DWORD length = 0; GetLogicalProcessorInformationEx(RelationAll, NULL, &length); + if (length == 0) + return "GetLogicalProcessorInformationEx(RelationAll, NULL, &length) failed"; + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* FF_AUTO_FREE pProcessorInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(length); - if(pProcessorInfo && GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length)) + if (pProcessorInfo && GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length)) { for( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* ptr = pProcessorInfo; @@ -36,11 +31,13 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) } } } + else + return "GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length) failed"; } FF_HKEY_AUTO_DESTROY hKey; if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey, NULL)) - return; + return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\", &hKey, NULL) failed"; { uint32_t mhz; @@ -51,6 +48,8 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) ffRegReadStrbuf(hKey, L"ProcessorNameString", &cpu->name, NULL); ffRegReadStrbuf(hKey, L"VendorIdentifier", &cpu->vendor, NULL); - if(instance->config.cpuTemp) + if(options->temp) ffDetectSmbiosTemp(&cpu->temperature, NULL); + + return NULL; } diff --git a/src/detection/cpuUsage/cpuUsage.h b/src/detection/cpuUsage/cpuUsage.h deleted file mode 100644 index 250b30570f..0000000000 --- a/src/detection/cpuUsage/cpuUsage.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#ifndef FF_INCLUDED_detection_cpu_cpuUsage -#define FF_INCLUDED_detection_cpu_cpuUsage - -const char* ffGetCpuUsageResult(double* result); - -#endif diff --git a/src/detection/cpuUsage/cpuUsage.c b/src/detection/cpuusage/cpuusage.c similarity index 93% rename from src/detection/cpuUsage/cpuUsage.c rename to src/detection/cpuusage/cpuusage.c index 88355668dc..f12cec2578 100644 --- a/src/detection/cpuUsage/cpuUsage.c +++ b/src/detection/cpuusage/cpuusage.c @@ -1,6 +1,5 @@ #include "fastfetch.h" -#include "cpuUsage.h" - +#include "detection/cpuusage/cpuusage.h" #include "common/time.h" #include @@ -10,7 +9,7 @@ const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll); static uint64_t inUseAll1, totalAll1; -void ffPrepareCPUUsage() +void ffPrepareCPUUsage(void) { ffGetCpuUsageInfo(&inUseAll1, &totalAll1); } diff --git a/src/detection/cpuusage/cpuusage.h b/src/detection/cpuusage/cpuusage.h new file mode 100644 index 0000000000..fb3c81e8e5 --- /dev/null +++ b/src/detection/cpuusage/cpuusage.h @@ -0,0 +1,8 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_cpuusage_cpuusage +#define FF_INCLUDED_detection_cpuusage_cpuusage + +const char* ffGetCpuUsageResult(double* result); + +#endif diff --git a/src/detection/cpuUsage/cpuUsage_apple.c b/src/detection/cpuusage/cpuusage_apple.c similarity index 94% rename from src/detection/cpuUsage/cpuUsage_apple.c rename to src/detection/cpuusage/cpuusage_apple.c index d3b533f481..b946152193 100644 --- a/src/detection/cpuUsage/cpuUsage_apple.c +++ b/src/detection/cpuusage/cpuusage_apple.c @@ -1,5 +1,5 @@ #include "fastfetch.h" -#include "cpuUsage.h" +#include "detection/cpuusage/cpuusage.h" #include #include diff --git a/src/detection/cpuUsage/cpuUsage_bsd.c b/src/detection/cpuusage/cpuusage_bsd.c similarity index 93% rename from src/detection/cpuUsage/cpuUsage_bsd.c rename to src/detection/cpuusage/cpuusage_bsd.c index d96064fd4a..fa1945aaa5 100644 --- a/src/detection/cpuUsage/cpuUsage_bsd.c +++ b/src/detection/cpuusage/cpuusage_bsd.c @@ -1,4 +1,4 @@ -#include "cpuUsage.h" +#include "detection/cpuusage/cpuusage.h" #include #include diff --git a/src/detection/cpuUsage/cpuUsage_linux.c b/src/detection/cpuusage/cpuusage_linux.c similarity index 95% rename from src/detection/cpuUsage/cpuUsage_linux.c rename to src/detection/cpuusage/cpuusage_linux.c index 1888b2b132..78c64215ea 100644 --- a/src/detection/cpuUsage/cpuUsage_linux.c +++ b/src/detection/cpuusage/cpuusage_linux.c @@ -1,5 +1,5 @@ #include "fastfetch.h" -#include "cpuUsage.h" +#include "detection/cpuusage/cpuusage.h" #include #include diff --git a/src/detection/cpuUsage/cpuUsage_windows.c b/src/detection/cpuusage/cpuusage_windows.c similarity index 97% rename from src/detection/cpuUsage/cpuUsage_windows.c rename to src/detection/cpuusage/cpuusage_windows.c index 60ebef4be9..a22250d834 100644 --- a/src/detection/cpuUsage/cpuUsage_windows.c +++ b/src/detection/cpuusage/cpuusage_windows.c @@ -1,5 +1,5 @@ #include "fastfetch.h" -#include "cpuUsage.h" +#include "detection/cpuusage/cpuusage.h" #include "util/mallocHelper.h" diff --git a/src/detection/cursor/cursor.h b/src/detection/cursor/cursor.h index 2686312400..793721f0b3 100644 --- a/src/detection/cursor/cursor.h +++ b/src/detection/cursor/cursor.h @@ -12,6 +12,6 @@ typedef struct FFCursorResult FFstrbuf error; } FFCursorResult; -void ffDetectCursor(const FFinstance* instance, FFCursorResult* result); +void ffDetectCursor(FFCursorResult* result); #endif diff --git a/src/detection/cursor/cursor_apple.m b/src/detection/cursor/cursor_apple.m index 3873e979ac..40d4b90c93 100644 --- a/src/detection/cursor/cursor_apple.m +++ b/src/detection/cursor/cursor_apple.m @@ -17,10 +17,10 @@ static void appendColor(FFstrbuf* str, NSDictionary* color) ffStrbufAppendF(str, "#%02X%02X%02X%02X", r, g, b, a); } -void ffDetectCursor(const FFinstance* instance, FFCursorResult* result) +void ffDetectCursor(FFCursorResult* result) { NSError* error; - NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/com.apple.universalaccess.plist", instance->state.platform.homeDir.chars]; + NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/com.apple.universalaccess.plist", instance.state.platform.homeDir.chars]; NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName] error:&error]; if(error) diff --git a/src/detection/cursor/cursor_linux.c b/src/detection/cursor/cursor_linux.c index 3ca696091d..17ff047657 100644 --- a/src/detection/cursor/cursor_linux.c +++ b/src/detection/cursor/cursor_linux.c @@ -9,15 +9,15 @@ #include -static bool detectCursorGTK(const FFinstance* instance, FFCursorResult* result) +static bool detectCursorGTK(FFCursorResult* result) { - const FFGTKResult* gtk = ffDetectGTK4(instance); + const FFGTKResult* gtk = ffDetectGTK4(); if(gtk->cursor.length == 0) - gtk = ffDetectGTK3(instance); + gtk = ffDetectGTK3(); if(gtk->cursor.length == 0) - gtk = ffDetectGTK2(instance); + gtk = ffDetectGTK2(); if(gtk->cursor.length == 0) return false; @@ -27,9 +27,9 @@ static bool detectCursorGTK(const FFinstance* instance, FFCursorResult* result) return true; } -static void detectCursorFromConfigFile(const FFinstance* instance, const char* relativeFilePath, const char* themeStart, const char* themeDefault, const char* sizeStart, const char* sizeDefault, FFCursorResult* result) +static void detectCursorFromConfigFile(const char* relativeFilePath, const char* themeStart, const char* themeDefault, const char* sizeStart, const char* sizeDefault, FFCursorResult* result) { - if(ffParsePropFileConfigValues(instance, relativeFilePath, 2, (FFpropquery[]) { + if(ffParsePropFileConfigValues(relativeFilePath, 2, (FFpropquery[]) { {themeStart, &result->theme}, {sizeStart, &result->size} })) { @@ -45,9 +45,9 @@ static void detectCursorFromConfigFile(const FFinstance* instance, const char* r ffStrbufAppendF(&result->error, "Couldn't find cursor in %s", relativeFilePath); } -static bool detectCursorFromXResources(const FFinstance* instance, FFCursorResult* result) +static bool detectCursorFromXResources(FFCursorResult* result) { - ffParsePropFileHomeValues(instance, ".Xresources", 2, (FFpropquery[]) { + ffParsePropFileHomeValues(".Xresources", 2, (FFpropquery[]) { {"Xcursor.theme :", &result->theme}, {"Xcursor.size :", &result->size} }); @@ -55,9 +55,8 @@ static bool detectCursorFromXResources(const FFinstance* instance, FFCursorResul return result->theme.length > 0; } -static bool detectCursorFromEnv(const FFinstance* instance, FFCursorResult* result) +static bool detectCursorFromEnv(FFCursorResult* result) { - FF_UNUSED(instance); const char* xcursor_theme = getenv("XCURSOR_THEME"); if(!ffStrSet(xcursor_theme)) @@ -69,23 +68,23 @@ static bool detectCursorFromEnv(const FFinstance* instance, FFCursorResult* resu return true; } -void ffDetectCursor(const FFinstance* instance, FFCursorResult* result) +void ffDetectCursor(FFCursorResult* result) { - const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance); + const FFDisplayServerResult* wmde = ffConnectDisplayServer(); if(ffStrbufCompS(&wmde->wmPrettyName, FF_WM_PRETTY_WSLG) == 0) ffStrbufAppendS(&result->error, "WSLg uses native windows cursor"); else if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY) == 0) ffStrbufAppendS(&result->error, "Cursor isn't supported in TTY"); else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA) == 0) - detectCursorFromConfigFile(instance, "kcminputrc", "cursorTheme =", "Breeze", "cursorSize =", "24", result); + detectCursorFromConfigFile("kcminputrc", "cursorTheme =", "Breeze", "cursorSize =", "24", result); else if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT)) - detectCursorFromConfigFile(instance, "lxqt/session.conf", "cursor_theme =", "Adwaita", "cursor_size =", "24", result); + detectCursorFromConfigFile("lxqt/session.conf", "cursor_theme =", "Adwaita", "cursor_size =", "24", result); else if( - !detectCursorGTK(instance, result) && - !detectCursorFromEnv(instance, result) && - !ffParsePropFileHome(instance, ".icons/default/index.theme", "Inherits =", &result->theme) && - !detectCursorFromXResources(instance, result) && - !ffParsePropFileData(instance, "icons/default/index.theme", "Inherits =", &result->theme) + !detectCursorGTK(result) && + !detectCursorFromEnv(result) && + !ffParsePropFileHome(".icons/default/index.theme", "Inherits =", &result->theme) && + !detectCursorFromXResources(result) && + !ffParsePropFileData("icons/default/index.theme", "Inherits =", &result->theme) ) ffStrbufAppendS(&result->error, "Couldn't find cursor"); } diff --git a/src/detection/cursor/cursor_nosupport.c b/src/detection/cursor/cursor_nosupport.c index c54637c969..6e36e55cad 100644 --- a/src/detection/cursor/cursor_nosupport.c +++ b/src/detection/cursor/cursor_nosupport.c @@ -1,7 +1,6 @@ #include "cursor.h" -void ffDetectCursor(const FFinstance* instance, FFCursorResult* result) +void ffDetectCursor(FF_MAYBE_UNUSED FFCursorResult* result) { - FF_UNUSED(instance, result); ffStrbufInitS(&result->error, "Not supported on this platform"); } diff --git a/src/detection/cursor/cursor_windows.c b/src/detection/cursor/cursor_windows.c index c3d6c644a5..d992ff83c9 100644 --- a/src/detection/cursor/cursor_windows.c +++ b/src/detection/cursor/cursor_windows.c @@ -1,19 +1,17 @@ -#include "cursor.h" - -#include "util/windows/registry.h" - -void ffDetectCursor(const FFinstance* instance, FFCursorResult* result) -{ - FF_UNUSED(instance); - - FF_HKEY_AUTO_DESTROY hKey; - if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Cursors", &hKey, &result->error)) - { - if (!ffRegReadStrbuf(hKey, NULL, &result->theme, &result->error)) - return; - - uint32_t cursorBaseSize; - ffRegReadUint(hKey, L"CursorBaseSize", &cursorBaseSize, &result->error); - ffStrbufAppendF(&result->size, "%u", (unsigned) cursorBaseSize); - } -} +#include "cursor.h" + +#include "util/windows/registry.h" + +void ffDetectCursor(FFCursorResult* result) +{ + FF_HKEY_AUTO_DESTROY hKey; + if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Cursors", &hKey, &result->error)) + { + if (!ffRegReadStrbuf(hKey, NULL, &result->theme, &result->error)) + return; + + uint32_t cursorBaseSize; + if (ffRegReadUint(hKey, L"CursorBaseSize", &cursorBaseSize, NULL)) + ffStrbufAppendF(&result->size, "%u", (unsigned) cursorBaseSize); + } +} diff --git a/src/detection/datetime/datetime.c b/src/detection/datetime/datetime.c index 317fdcf85a..60cc1f6582 100644 --- a/src/detection/datetime/datetime.c +++ b/src/detection/datetime/datetime.c @@ -4,10 +4,8 @@ #include -const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance) +const FFDateTimeResult* ffDetectDateTime(void) { - FF_UNUSED(instance); //We may need it later for additional configuration - static FFDateTimeResult result; static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static bool init = false; diff --git a/src/detection/datetime/datetime.h b/src/detection/datetime/datetime.h index 418f14fb21..fd47ba03bd 100644 --- a/src/detection/datetime/datetime.h +++ b/src/detection/datetime/datetime.h @@ -30,6 +30,6 @@ typedef struct FFDateTimeResult FFstrbuf secondPretty; //37 } FFDateTimeResult; -const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance); +const FFDateTimeResult* ffDetectDateTime(); #endif diff --git a/src/detection/disk/disk.c b/src/detection/disk/disk.c index 55cfec7de7..e033f6c937 100644 --- a/src/detection/disk/disk.c +++ b/src/detection/disk/disk.c @@ -1,35 +1,29 @@ #include "disk.h" -#include "detection/internal.h" -void ffDetectDisksImpl(FFDiskResult* disks); +const char* ffDetectDisksImpl(FFlist* disks); static int compareDisks(const void* disk1, const void* disk2) { return ffStrbufCompAlphabetically(&((const FFDisk*) disk1)->mountpoint, &((const FFDisk*) disk2)->mountpoint); } -const FFDiskResult* ffDetectDisks() +const char* ffDetectDisks(FFlist* disks) { - FF_DETECTION_INTERNAL_GUARD(FFDiskResult, - ffStrbufInit(&result.error); - ffListInitA(&result.disks, sizeof(FFDisk), 4); + const char* error = ffDetectDisksImpl(disks); - ffDetectDisksImpl(&result); + if (error) return error; + if (disks->length == 0) return "No disks found"; - if(result.disks.length == 0 && result.error.length == 0) - ffStrbufAppendS(&result.error, "No disks found"); - else - { - //We need to sort the disks, so that we can detect, which disk a path resides on - // For example for /boot/efi/bootmgr we need to check /boot/efi before /boot - //Note that we sort alphabetically here for a better ordering when printing the list, - // so the check must be done in reverse order - ffListSort(&result.disks, compareDisks); - FF_LIST_FOR_EACH(FFDisk, disk, result.disks) - { - if(disk->bytesTotal == 0) - disk->type |= FF_DISK_TYPE_UNKNOWN_BIT; - } - } - ); + //We need to sort the disks, so that we can detect, which disk a path resides on + // For example for /boot/efi/bootmgr we need to check /boot/efi before /boot + //Note that we sort alphabetically here for a better ordering when printing the list, + // so the check must be done in reverse order + ffListSort(disks, compareDisks); + FF_LIST_FOR_EACH(FFDisk, disk, *disks) + { + if(disk->bytesTotal == 0) + disk->type |= FF_DISK_TYPE_UNKNOWN_BIT; + } + + return NULL; } diff --git a/src/detection/disk/disk.h b/src/detection/disk/disk.h index 9572f267ff..b4d9e53e79 100644 --- a/src/detection/disk/disk.h +++ b/src/detection/disk/disk.h @@ -19,18 +19,10 @@ typedef struct FFDisk uint32_t filesTotal; } FFDisk; -typedef struct FFDiskResult -{ - FFstrbuf error; - FFlist disks; //List of FFDisk -} FFDiskResult; - /** * Returns a List of FFDisk, sorted alphabetically by mountpoint. * If error is not set, disks contains at least one disk. - * - * @return const FFDiskResult* */ -const FFDiskResult* ffDetectDisks(); +const char* ffDetectDisks(FFlist* result /* list of FFDisk */); #endif diff --git a/src/detection/disk/disk_bsd.c b/src/detection/disk/disk_bsd.c index 3ff71925ae..746a17052d 100644 --- a/src/detection/disk/disk_bsd.c +++ b/src/detection/disk/disk_bsd.c @@ -11,7 +11,8 @@ static void detectFsInfo(struct statfs* fs, FFDisk* disk) ffStrbufStartsWithS(&disk->mountpoint, "/var") || ffStrbufStartsWithS(&disk->mountpoint, "/tmp") || ffStrbufStartsWithS(&disk->mountpoint, "/proc") || - ffStrbufStartsWithS(&disk->mountpoint, "/zroot") + ffStrbufStartsWithS(&disk->mountpoint, "/zroot") || + ffStrbufStartsWithS(&disk->mountpoint, "/compat/linux/") ) disk->type = FF_DISK_TYPE_HIDDEN_BIT; else if((fs->f_flags & MNT_NOSUID) || !(fs->f_flags & MNT_LOCAL)) @@ -25,17 +26,17 @@ static void detectFsInfo(struct statfs* fs, FFDisk* disk) void detectFsInfo(struct statfs* fs, FFDisk* disk); #endif -void ffDetectDisksImpl(FFDiskResult* disks) +const char* ffDetectDisksImpl(FFlist* disks) { struct statfs* buf; int size = getmntinfo(&buf, MNT_WAIT); if(size <= 0) - ffStrbufAppendS(&disks->error, "getmntinfo() failed"); + return "getmntinfo(&buf, MNT_WAIT) failed"; for(struct statfs* fs = buf; fs < buf + size; ++fs) { - FFDisk* disk = ffListAdd(&disks->disks); + FFDisk* disk = ffListAdd(disks); #ifdef __FreeBSD__ // f_bavail and f_ffree are signed on FreeBSD... @@ -44,7 +45,7 @@ void ffDetectDisksImpl(FFDiskResult* disks) #endif disk->bytesTotal = fs->f_blocks * fs->f_bsize; - disk->bytesUsed = disk->bytesTotal - ((uint64_t)fs->f_bavail * fs->f_bsize); + disk->bytesUsed = disk->bytesTotal - ((uint64_t)fs->f_bfree * fs->f_bsize); disk->filesTotal = (uint32_t) fs->f_files; disk->filesUsed = (uint32_t) (disk->filesTotal - (uint64_t)fs->f_ffree); @@ -53,4 +54,6 @@ void ffDetectDisksImpl(FFDiskResult* disks) ffStrbufInitS(&disk->filesystem, fs->f_fstypename); detectFsInfo(fs, disk); } + + return NULL; } diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index a3c7ca52a9..afde1887e0 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -19,6 +19,10 @@ static bool isPhysicalDevice(FFstrbuf* device) { #ifndef __ANDROID__ //On Android, `/dev` is not accessable, so that the following checks always fail + //https://askubuntu.com/a/1289123 + if(ffStrbufEqualS(device, "/cow")) + return true; + //DrvFs is a filesystem plugin to WSL that was designed to support interop between WSL and the Windows filesystem. if(ffStrbufEqualS(device, "drvfs")) return true; @@ -116,8 +120,7 @@ static void detectName(FFDisk* disk, const FFstrbuf* device) if(stat(device->chars, &deviceStat) != 0) return; - FF_STRBUF_AUTO_DESTROY basePath; - ffStrbufInit(&basePath); + FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreate(); //Try partlabel first ffStrbufSetS(&basePath, "/dev/disk/by-partlabel/"); @@ -194,23 +197,19 @@ static void detectStats(FFDisk* disk) memset(&fs, 0, sizeof(struct statvfs)); //Set all values to 0, so our values get initialized to 0 too disk->bytesTotal = fs.f_blocks * fs.f_frsize; - disk->bytesUsed = disk->bytesTotal - (fs.f_bavail * fs.f_frsize); + disk->bytesUsed = disk->bytesTotal - (fs.f_bfree * fs.f_frsize); disk->filesTotal = (uint32_t) fs.f_files; disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree); } -void ffDetectDisksImpl(FFDiskResult* disks) +const char* ffDetectDisksImpl(FFlist* disks) { FILE* mountsFile = fopen("/proc/mounts", "r"); if(mountsFile == NULL) - { - ffStrbufAppendS(&disks->error, "fopen(\"/proc/mounts\", \"r\") == NULL"); - return; - } + return "fopen(\"/proc/mounts\", \"r\") == NULL"; - FF_LIST_AUTO_DESTROY devices; - ffListInit(&devices, sizeof(FFstrbuf)); + FF_LIST_AUTO_DESTROY devices = ffListCreate(sizeof(FFstrbuf)); char* line = NULL; size_t len = 0; @@ -233,7 +232,7 @@ void ffDetectDisksImpl(FFDiskResult* disks) } //We have a valid device, add it to the list - FFDisk* disk = ffListAdd(&disks->disks); + FFDisk* disk = ffListAdd(disks); //detect mountpoint ffStrbufInit(&disk->mountpoint); @@ -261,4 +260,6 @@ void ffDetectDisksImpl(FFDiskResult* disks) ffStrbufDestroy(device); fclose(mountsFile); + + return NULL; } diff --git a/src/detection/disk/disk_windows.c b/src/detection/disk/disk_windows.c index d983626943..472b9730f6 100644 --- a/src/detection/disk/disk_windows.c +++ b/src/detection/disk/disk_windows.c @@ -4,11 +4,12 @@ #include #include -void ffDetectDisksImpl(FFDiskResult* disks) +const char* ffDetectDisksImpl(FFlist* disks) { wchar_t buf[MAX_PATH + 1]; uint32_t length = GetLogicalDriveStringsW(sizeof(buf) / sizeof(*buf), buf); - assert(length < sizeof(buf) / sizeof(*buf)); + if (length == 0 || length >= sizeof(buf) / sizeof(*buf)) + return "GetLogicalDriveStringsW(sizeof(buf) / sizeof(*buf), buf) failed"; for(uint32_t i = 0; i < length; i++) { @@ -21,7 +22,7 @@ void ffDetectDisksImpl(FFDiskResult* disks) continue; } - FFDisk* disk = ffListAdd(&disks->disks); + FFDisk* disk = ffListAdd(disks); ffStrbufInitWS(&disk->mountpoint, mountpoint); uint64_t bytesFree; @@ -61,10 +62,12 @@ void ffDetectDisksImpl(FFDiskResult* disks) ffStrbufSetWS(&disk->name, diskName); } - //TODO: implement + //Unsupported disk->filesUsed = 0; disk->filesTotal = 0; i += disk->mountpoint.length; } + + return NULL; } diff --git a/src/detection/displayserver/displayserver.c b/src/detection/displayserver/displayserver.c index 270f4a93cd..0b0db7833a 100644 --- a/src/detection/displayserver/displayserver.c +++ b/src/detection/displayserver/displayserver.c @@ -8,8 +8,11 @@ bool ffdsAppendDisplay( double refreshRate, uint32_t scaledWidth, uint32_t scaledHeight, + uint32_t rotation, FFstrbuf* name, - FFDisplayType type) + FFDisplayType type, + bool primary, + uint64_t id) { if(width == 0 || height == 0) return false; @@ -20,17 +23,20 @@ bool ffdsAppendDisplay( display->refreshRate = refreshRate; display->scaledWidth = scaledWidth; display->scaledHeight = scaledHeight; + display->rotation = rotation; ffStrbufInitMove(&display->name, name); display->type = type; + display->primary = primary; + display->id = id; return true; } -void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance); +void ffConnectDisplayServerImpl(FFDisplayServerResult* ds); -const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance) +const FFDisplayServerResult* ffConnectDisplayServer() { FF_DETECTION_INTERNAL_GUARD(FFDisplayServerResult, - ffConnectDisplayServerImpl(&result, instance); + ffConnectDisplayServerImpl(&result); ); } diff --git a/src/detection/displayserver/displayserver.h b/src/detection/displayserver/displayserver.h index e75181b714..b4ab5283b7 100644 --- a/src/detection/displayserver/displayserver.h +++ b/src/detection/displayserver/displayserver.h @@ -7,6 +7,7 @@ #define FF_DE_PRETTY_PLASMA "KDE Plasma" #define FF_DE_PRETTY_GNOME "Gnome" +#define FF_DE_PRETTY_GNOME_CLASSIC "Gnome Classic" #define FF_DE_PRETTY_XFCE4 "Xfce4" #define FF_DE_PRETTY_CINNAMON "Cinnamon" #define FF_DE_PRETTY_MATE "Mate" @@ -29,6 +30,12 @@ #define FF_WM_PRETTY_WESTON "Weston" #define FF_WM_PRETTY_XMONAD "XMonad" #define FF_WM_PRETTY_WSLG "WSLg" +#define FF_WM_PRETTY_TINYWM "TinyWM" +#define FF_WM_PRETTY_QTILE "Qtile" +#define FF_WM_PRETTY_HERBSTLUFTWM "herbstluftwm" +#define FF_WM_PRETTY_ICEWM "IceWM" +#define FF_WM_PRETTY_SPECTRWM "spectrwm" + #define FF_WM_PROTOCOL_TTY "TTY" #define FF_WM_PROTOCOL_X11 "X11" @@ -49,6 +56,9 @@ typedef struct FFDisplayResult uint32_t scaledHeight; FFstrbuf name; FFDisplayType type; + uint32_t rotation; + bool primary; + uint64_t id; // platform dependent } FFDisplayResult; typedef struct FFDisplayServerResult @@ -62,7 +72,7 @@ typedef struct FFDisplayServerResult FFlist displays; //List of FFDisplayResult } FFDisplayServerResult; -const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance); +const FFDisplayServerResult* ffConnectDisplayServer(); bool ffdsAppendDisplay( FFDisplayServerResult* result, @@ -71,7 +81,10 @@ bool ffdsAppendDisplay( double refreshRate, uint32_t scaledWidth, uint32_t scaledHeight, + uint32_t rotation, FFstrbuf* name, - FFDisplayType type); + FFDisplayType type, + bool primary, + uint64_t id); #endif diff --git a/src/detection/displayserver/displayserver_android.c b/src/detection/displayserver/displayserver_android.c new file mode 100644 index 0000000000..af57a06283 --- /dev/null +++ b/src/detection/displayserver/displayserver_android.c @@ -0,0 +1,115 @@ +#include "displayserver.h" +#include "common/settings.h" + +#include "common/processing.h" + +static void detectWithDumpsys(FFDisplayServerResult* ds) +{ + FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate(); + if (ffProcessAppendStdOut(&buf, (char* []) { + "/system/bin/dumpsys", + "display", + NULL, + }) != NULL || buf.length == 0) + return; // Only works in `adb shell`, or when rooted + + uint32_t index = 0; + while ((index = ffStrbufNextIndexS(&buf, index, "DisplayDeviceInfo")) < buf.length) + { + index += strlen("DisplayDeviceInfo"); + uint32_t nextIndex = ffStrbufNextIndexC(&buf, index, '\n'); + buf.chars[nextIndex] = '\0'; + const char* info = buf.chars + index; + + // {"Builtin display": uniqueId="local:4630947134992368259", 1440 x 3200, modeId 2, defaultModeId 1, supportedModes [{id=1, width=1440, height=3200, fps=60.000004, alternativeRefreshRates=[24.000002, 30.000002, 40.0, 120.00001, 120.00001, 120.00001, 120.00001, 120.00001]}, + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateA(64); + unsigned width = 0, height = 0, modeId = 0; + double refreshRate = 0; + // {"Builtin display": uniqueId="local:4630947134992368259", 1440 x 3200, modeId 2 + int res = sscanf(info, "{\"%63[^\"]\":%*s%u x %u, modeId%u", name.chars, &width, &height, &modeId); + if (res >= 3) + { + if (res == 4) + { + ++info; // skip first '{' + while ((info = strchr(info, '{'))) + { + ++info; + + unsigned id; + double fps; + // id=1, width=1440, height=3200, fps=60.000004, + if (sscanf(info, "id=%u, %*s%*s fps=%lf", &id, &fps) >= 2) + { + if (id == modeId) + { + refreshRate = fps; + break; + } + } + else + break; + } + } + + ffStrbufRecalculateLength(&name); + ffdsAppendDisplay(ds, + (uint32_t)width, + (uint32_t)height, + refreshRate, + 0, + 0, + 0, + &name, + FF_DISPLAY_TYPE_UNKNOWN, + false, + 0 + ); + } + + index = nextIndex + 1; + } +} + +static bool detectWithGetprop(FFDisplayServerResult* ds) +{ + // Only for MiUI + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); + ; + if (ffSettingsGetAndroidProperty("persist.sys.miui_resolution", &buffer) && + ffStrbufContainC(&buffer, ',')) + { + // 1440,3200,560 => width,height,ppi + uint32_t width = ffStrbufToUInt16(&buffer, 0); + ffStrbufSubstrAfterFirstC(&buffer, ','); + uint32_t height = ffStrbufToUInt16(&buffer, 0); + return ffdsAppendDisplay(ds, + width, + height, + 0, + 0, + 0, + 0, + 0, + FF_DISPLAY_TYPE_BUILTIN, + false, + 0 + ); + } + + return false; +} + +void ffConnectDisplayServerImpl(FFDisplayServerResult* ds) +{ + ffStrbufInitStatic(&ds->wmProcessName, "WindowManager"); + ffStrbufInitStatic(&ds->wmPrettyName, "Window Manager"); + ffStrbufInit(&ds->wmProtocolName); + ffStrbufInit(&ds->deProcessName); + ffStrbufInit(&ds->dePrettyName); + ffStrbufInit(&ds->deVersion); + ffListInitA(&ds->displays, sizeof(FFDisplayResult), 0); + + if (!detectWithGetprop(ds)) + detectWithDumpsys(ds); +} diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index 8943a6a544..dfd2fe77f4 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -12,7 +12,7 @@ extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import)); -static void detectDisplays(FFDisplayServerResult* ds, bool detectName) +static void detectDisplays(FFDisplayServerResult* ds) { CGDirectDisplayID screens[128]; uint32_t screenCount; @@ -40,9 +40,8 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName) } } - FF_STRBUF_AUTO_DESTROY name; - ffStrbufInit(&name); - if(detectName && CoreDisplay_DisplayCreateInfoDictionary) + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); + if(CoreDisplay_DisplayCreateInfoDictionary) { CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary(screen); if(displayInfo) @@ -59,8 +58,11 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName) refreshRate, (uint32_t)CGDisplayModeGetWidth(mode), (uint32_t)CGDisplayModeGetHeight(mode), + (uint32_t)CGDisplayRotation(screen), &name, - CGDisplayIsBuiltin(screen) ? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL + CGDisplayIsBuiltin(screen) ? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL, + CGDisplayIsMain(screen), + (uint64_t)screen ); CGDisplayModeRelease(mode); } @@ -97,15 +99,24 @@ static void detectWMPlugin(FFstrbuf* name) } } -void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance) +void ffConnectDisplayServerImpl(FFDisplayServerResult* ds) { - FF_UNUSED(instance); - - ffStrbufInitS(&ds->wmProcessName, "WindowServer"); - ffStrbufInitS(&ds->wmPrettyName, "Quartz Compositor"); + { + FF_CFTYPE_AUTO_RELEASE CFMachPortRef port = CGWindowServerCreateServerPort(); + if (port) + { + ffStrbufInitStatic(&ds->wmProcessName, "WindowServer"); + ffStrbufInitStatic(&ds->wmPrettyName, "Quartz Compositor"); + } + else + { + ffStrbufInit(&ds->wmProcessName); + ffStrbufInit(&ds->wmPrettyName); + } + } ffStrbufInit(&ds->wmProtocolName); - if(instance->config.allowSlowOperations) + if(instance.config.allowSlowOperations) { FF_STRBUF_AUTO_DESTROY name; ffStrbufInit(&name); @@ -115,10 +126,9 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins } ffStrbufInit(&ds->deProcessName); - ffStrbufInit(&ds->dePrettyName); + ffStrbufInitStatic(&ds->dePrettyName, "Aqua"); ffStrbufInit(&ds->deVersion); - ffStrbufAppendS(&ds->dePrettyName, "Aqua"); ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4); - detectDisplays(ds, instance->config.displayDetectName); + detectDisplays(ds); } diff --git a/src/detection/displayserver/displayserver_nosupport.c b/src/detection/displayserver/displayserver_nosupport.c deleted file mode 100644 index 359ebc6345..0000000000 --- a/src/detection/displayserver/displayserver_nosupport.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "displayserver.h" - -void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance) -{ - FF_UNUSED(instance); - - ffStrbufInitA(&ds->wmProcessName, 0); - ffStrbufInitA(&ds->wmPrettyName, 0); - ffStrbufInitA(&ds->wmProtocolName, 0); - ffStrbufInitA(&ds->deProcessName, 0); - ffStrbufInitA(&ds->dePrettyName, 0); - ffStrbufInitA(&ds->deVersion, 0); - ffListInitA(&ds->displays, sizeof(FFDisplayResult), 0); -} diff --git a/src/detection/displayserver/displayserver_windows.c b/src/detection/displayserver/displayserver_windows.c index 73bc668f32..b4945436b1 100644 --- a/src/detection/displayserver/displayserver_windows.c +++ b/src/detection/displayserver/displayserver_windows.c @@ -4,9 +4,34 @@ #include #include +#include -static void detectDisplays(FFDisplayServerResult* ds, bool detectName) +typedef struct FFMonitorInfo { + HMONITOR handle; + MONITORINFOEXW info; +} FFMonitorInfo; + +static CALLBACK BOOL MonitorEnumProc( + HMONITOR hMonitor, + FF_MAYBE_UNUSED HDC hdc, + FF_MAYBE_UNUSED LPRECT lpRect, + LPARAM lParam +) +{ + FFlist* monitors = (FFlist*) lParam; + FFMonitorInfo* newMonitor = ffListAdd(monitors); + newMonitor->handle = hMonitor; + newMonitor->info.cbSize = sizeof(newMonitor->info); + + return GetMonitorInfoW(hMonitor, (MONITORINFO*) &newMonitor->info); +} + +static void detectDisplays(FFDisplayServerResult* ds) +{ + FF_LIST_AUTO_DESTROY monitors = ffListCreate(sizeof(FFMonitorInfo)); + EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM) &monitors); + DISPLAYCONFIG_PATH_INFO paths[128]; uint32_t pathCount = sizeof(paths) / sizeof(paths[0]); DISPLAYCONFIG_MODE_INFO modes[256]; @@ -33,38 +58,39 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName) }, }; - uint32_t scaledWidth = 0, scaledHeight = 0; + FFMonitorInfo* monitorInfo = NULL; if (DisplayConfigGetDeviceInfo(&sourceName.header) == ERROR_SUCCESS) { - HDC hdc = CreateICW(sourceName.viewGdiDeviceName, NULL, NULL, NULL); - scaledWidth = (uint32_t) GetDeviceCaps(hdc, HORZRES); - scaledHeight = (uint32_t) GetDeviceCaps(hdc, VERTRES); - DeleteDC(hdc); + FF_LIST_FOR_EACH(FFMonitorInfo, item, monitors) + { + if (wcsncmp(item->info.szDevice, sourceName.viewGdiDeviceName, sizeof(sourceName.viewGdiDeviceName) / sizeof(wchar_t)) == 0) + { + monitorInfo = item; + break; + } + } } + if (!monitorInfo) continue; - FF_STRBUF_AUTO_DESTROY name; - ffStrbufInit(&name); + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); - if (detectName) + DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = { + .header = { + .type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME, + .size = sizeof(targetName), + .adapterId = path->targetInfo.adapterId, + .id = path->targetInfo.id, + }, + }; + if(DisplayConfigGetDeviceInfo(&targetName.header) == ERROR_SUCCESS) { - DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = { - .header = { - .type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME, - .size = sizeof(targetName), - .adapterId = path->targetInfo.adapterId, - .id = path->targetInfo.id, - }, - }; - if(DisplayConfigGetDeviceInfo(&targetName.header) == ERROR_SUCCESS) + if (targetName.flags.friendlyNameFromEdid) + ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName); + else { - if (targetName.flags.friendlyNameFromEdid) - ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName); - else - { - ffStrbufSetWS(&name, targetName.monitorDevicePath); - ffStrbufSubstrAfterFirstC(&name, '#'); - ffStrbufSubstrBeforeFirstC(&name, '#'); - } + ffStrbufSetWS(&name, targetName.monitorDevicePath); + ffStrbufSubstrAfterFirstC(&name, '#'); + ffStrbufSubstrBeforeFirstC(&name, '#'); } } @@ -78,34 +104,54 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName) height = temp; } + uint32_t rotation; + switch (path->targetInfo.rotation) + { + case DISPLAYCONFIG_ROTATION_ROTATE90: + rotation = 90; + break; + case DISPLAYCONFIG_ROTATION_ROTATE180: + rotation = 180; + break; + case DISPLAYCONFIG_ROTATION_ROTATE270: + rotation = 270; + break; + default: + rotation = 0; + break; + } + ffdsAppendDisplay(ds, width, height, path->targetInfo.refreshRate.Numerator / (double) path->targetInfo.refreshRate.Denominator, - scaledWidth, - scaledHeight, + (uint32_t) (monitorInfo->info.rcMonitor.right - monitorInfo->info.rcMonitor.left), + (uint32_t) (monitorInfo->info.rcMonitor.bottom - monitorInfo->info.rcMonitor.top), + rotation, &name, path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL || path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED || path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED - ? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL + ? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL, + !!(monitorInfo->info.dwFlags & MONITORINFOF_PRIMARY), + (uint64_t)(uintptr_t) monitorInfo->handle ); } } } -void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance) +void ffConnectDisplayServerImpl(FFDisplayServerResult* ds) { BOOL enabled; if(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled == TRUE) { - ffStrbufInitS(&ds->wmProcessName, "dwm.exe"); - ffStrbufInitS(&ds->wmPrettyName, "Desktop Window Manager"); + ffStrbufInitStatic(&ds->wmProcessName, "dwm.exe"); + ffStrbufInitStatic(&ds->wmPrettyName, "Desktop Window Manager"); } else { - ffStrbufInitS(&ds->wmProcessName, "internal"); - ffStrbufInitS(&ds->wmPrettyName, "internal"); + ffStrbufInitStatic(&ds->wmProcessName, "explorer.exe"); + ffStrbufInitStatic(&ds->wmPrettyName, "Windows Explorer"); } ffStrbufInit(&ds->wmProtocolName); ffStrbufInit(&ds->deProcessName); @@ -113,23 +159,23 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins ffStrbufInit(&ds->deVersion); ffListInit(&ds->displays, sizeof(FFDisplayResult)); - detectDisplays(ds, instance->config.displayDetectName); + detectDisplays(ds); //https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L2067 - const FFOSResult* os = ffDetectOS(instance); + const FFOSResult* os = ffDetectOS(); if( ffStrbufEqualS(&os->version, "11") || ffStrbufEqualS(&os->version, "10") || ffStrbufEqualS(&os->version, "2022") || ffStrbufEqualS(&os->version, "2019") || ffStrbufEqualS(&os->version, "2016") - ) ffStrbufSetS(&ds->dePrettyName, "Fluent"); + ) ffStrbufSetStatic(&ds->dePrettyName, "Fluent"); else if( ffStrbufEqualS(&os->version, "8") || ffStrbufEqualS(&os->version, "8.1") || ffStrbufEqualS(&os->version, "2012 R2") || ffStrbufEqualS(&os->version, "2012") - ) ffStrbufSetS(&ds->dePrettyName, "Metro"); + ) ffStrbufSetStatic(&ds->dePrettyName, "Metro"); else - ffStrbufSetS(&ds->dePrettyName, "Aero"); + ffStrbufSetStatic(&ds->dePrettyName, "Aero"); } diff --git a/src/detection/displayserver/linux/displayserver_linux.c b/src/detection/displayserver/linux/displayserver_linux.c index 257c60cc1b..3c93d29c02 100644 --- a/src/detection/displayserver/linux/displayserver_linux.c +++ b/src/detection/displayserver/linux/displayserver_linux.c @@ -1,4 +1,7 @@ #include "displayserver_linux.h" +#include "common/io/io.h" +#include "util/edidHelper.h" +#include "util/stringUtils.h" #include @@ -10,8 +13,7 @@ static void parseDRM(FFDisplayServerResult* result) if(dirp == NULL) return; - FFstrbuf drmDir; - ffStrbufInitA(&drmDir, 64); + FF_STRBUF_AUTO_DESTROY drmDir = ffStrbufCreateA(64); ffStrbufAppendS(&drmDir, drmDirPath); uint32_t drmDirLength = drmDir.length; @@ -19,7 +21,7 @@ static void parseDRM(FFDisplayServerResult* result) struct dirent* entry; while((entry = readdir(dirp)) != NULL) { - if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, "..")) continue; ffStrbufAppendS(&drmDir, entry->d_name); @@ -32,26 +34,51 @@ static void parseDRM(FFDisplayServerResult* result) continue; } - FFDisplayResult* display = ffListAdd(&result->displays); - display->width = 0; - display->height = 0; - display->refreshRate = 0; - display->scaledWidth = 0; - display->scaledHeight = 0; + uint32_t width = 0, height = 0; - int scanned = fscanf(modeFile, "%ux%u", &display->width, &display->height); - if(scanned < 2 || display->width == 0 || display->height == 0) - --result->displays.length; + int scanned = fscanf(modeFile, "%ux%u", &width, &height); + if(scanned == 2 && width > 0 && height > 0) + { + ffStrbufSubstrBefore(&drmDir, drmDirLength); + ffStrbufAppendS(&drmDir, entry->d_name); + ffStrbufAppendS(&drmDir, "/edid"); + + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); + uint8_t edidData[128]; + if(ffReadFileData(drmDir.chars, sizeof(edidData), edidData) == sizeof(edidData)) + ffEdidGetName(edidData, &name); + else + { + const char* plainName = entry->d_name; + if (ffStrStartsWith(plainName, "card")) + { + const char* tmp = strchr(plainName + strlen("card"), '-'); + if (tmp) plainName = tmp + 1; + } + ffStrbufAppendS(&name, plainName); + } + + ffdsAppendDisplay( + result, + width, height, + 0, + 0, 0, + 0, + &name, + FF_DISPLAY_TYPE_UNKNOWN, + false, + 0 + ); + } fclose(modeFile); ffStrbufSubstrBefore(&drmDir, drmDirLength); } closedir(dirp); - ffStrbufDestroy(&drmDir); } -void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance) +void ffConnectDisplayServerImpl(FFDisplayServerResult* ds) { ffStrbufInit(&ds->wmProcessName); ffStrbufInit(&ds->wmPrettyName); @@ -61,25 +88,28 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins ffStrbufInit(&ds->deVersion); ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4); - //We try wayland as our prefered display server, as it supports the most features. - //This method can't detect the name of our WM / DE - ffdsConnectWayland(instance, ds); + if (!instance.config.dsForceDrm) + { + //We try wayland as our prefered display server, as it supports the most features. + //This method can't detect the name of our WM / DE + ffdsConnectWayland(ds); - //Try the x11 libs, from most feature rich to least. - //We use the display list to detect if a connection is needed. - //They respect wmProtocolName, and only detect display if it is set. + //Try the x11 libs, from most feature rich to least. + //We use the display list to detect if a connection is needed. + //They respect wmProtocolName, and only detect display if it is set. - if(ds->displays.length == 0) - ffdsConnectXcbRandr(instance, ds); + if(ds->displays.length == 0) + ffdsConnectXcbRandr(ds); - if(ds->displays.length == 0) - ffdsConnectXrandr(instance, ds); + if(ds->displays.length == 0) + ffdsConnectXrandr(ds); - if(ds->displays.length == 0) - ffdsConnectXcb(instance, ds); + if(ds->displays.length == 0) + ffdsConnectXcb(ds); - if(ds->displays.length == 0) - ffdsConnectXlib(instance, ds); + if(ds->displays.length == 0) + ffdsConnectXlib(ds); + } //This display detection method is display server independent. //Use it if all connections failed @@ -87,5 +117,5 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins parseDRM(ds); //This fills in missing information about WM / DE by using env vars and iterating processes - ffdsDetectWMDE(instance, ds); + ffdsDetectWMDE(ds); } diff --git a/src/detection/displayserver/linux/displayserver_linux.h b/src/detection/displayserver/linux/displayserver_linux.h index aee7c25ff5..695fcede98 100644 --- a/src/detection/displayserver/linux/displayserver_linux.h +++ b/src/detection/displayserver/linux/displayserver_linux.h @@ -5,14 +5,14 @@ #include "detection/displayserver/displayserver.h" -void ffdsConnectWayland(const FFinstance* instance, FFDisplayServerResult* result); +void ffdsConnectWayland(FFDisplayServerResult* result); -void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* result); -void ffdsConnectXcb(const FFinstance* instance, FFDisplayServerResult* result); +void ffdsConnectXcbRandr(FFDisplayServerResult* result); +void ffdsConnectXcb(FFDisplayServerResult* result); -void ffdsConnectXrandr(const FFinstance* instance, FFDisplayServerResult* result); -void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result); +void ffdsConnectXrandr(FFDisplayServerResult* result); +void ffdsConnectXlib(FFDisplayServerResult* result); -void ffdsDetectWMDE(const FFinstance* instance, FFDisplayServerResult* result); +void ffdsDetectWMDE(FFDisplayServerResult* result); #endif diff --git a/src/detection/displayserver/linux/wayland.c b/src/detection/displayserver/linux/wayland.c index fbf0a211ef..06d7c7f750 100644 --- a/src/detection/displayserver/linux/wayland.c +++ b/src/detection/displayserver/linux/wayland.c @@ -1,4 +1,5 @@ #include "displayserver_linux.h" +#include "util/stringUtils.h" #include #include @@ -7,9 +8,11 @@ #include "common/library.h" #include "common/io/io.h" #include "common/thread.h" +#include "util/edidHelper.h" #include #include #include +#include typedef struct WaylandData { @@ -20,7 +23,6 @@ typedef struct WaylandData FF_LIBRARY_SYMBOL(wl_display_roundtrip) struct wl_display* display; const struct wl_interface* ffwl_output_interface; - bool detectName; } WaylandData; typedef struct WaylandDisplay @@ -32,7 +34,9 @@ typedef struct WaylandDisplay enum wl_output_transform transform; FFDisplayType type; FFstrbuf name; - bool detectName; + FFstrbuf description; + FFstrbuf vendorAndModelId; + FFstrbuf edidName; } WaylandDisplay; #ifndef __FreeBSD__ @@ -43,13 +47,11 @@ static void waylandDetectWM(int fd, FFDisplayServerResult* result) if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) return; - FFstrbuf procPath; - ffStrbufInit(&procPath); + FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreate(); ffStrbufAppendF(&procPath, "/proc/%d/cmdline", ucred.pid); //We check the cmdline for the process name, because it is not trimmed. ffReadFileBuffer(procPath.chars, &result->wmProcessName); ffStrbufSubstrBeforeFirstC(&result->wmProcessName, '\0'); //Trim the arguments ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path - ffStrbufDestroy(&procPath); } #else static void waylandDetectWM(int fd, FFDisplayServerResult* result) @@ -93,26 +95,70 @@ static void waylandOutputGeometryListener(void *data, { WaylandDisplay* display = data; display->transform = (enum wl_output_transform) transform; - if(display->detectName) + if (make && !ffStrEqualsIgnCase(make, "unknown") && model && !ffStrEqualsIgnCase(model, "unknown")) { - if(make && strcmp(make, "unknown") != 0) - ffStrbufAppendS(&display->name, make); - if(model && strcmp(model, "unknown") != 0) + ffStrbufAppendS(&display->vendorAndModelId, make); + ffStrbufAppendS(&display->vendorAndModelId, model); + } +} + +static bool matchDrmConnector(const char* wlName, FFstrbuf* edidName) +{ + // https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_output-event-name + // The doc says that "do not assume that the name is a reflection of an underlying DRM connector, X11 connection, etc." + // However I can't find a better method to get the edid data + const char* drmDirPath = "/sys/class/drm/"; + + DIR* dirp = opendir(drmDirPath); + if(dirp == NULL) + return false; + + struct dirent* entry; + while((entry = readdir(dirp)) != NULL) + { + const char* plainName = entry->d_name; + if (ffStrStartsWith(plainName, "card")) { - if(display->name.length > 0) - ffStrbufAppendC(&display->name, '-'); - ffStrbufAppendS(&display->name, model); + const char* tmp = strchr(plainName + strlen("card"), '-'); + if (tmp) plainName = tmp + 1; + } + if (ffStrEquals(plainName, wlName)) + { + ffStrbufAppendF(edidName, "%s%s/edid", drmDirPath, entry->d_name); + + uint8_t edidData[128]; + if(ffReadFileData(edidName->chars, sizeof(edidData), edidData) == sizeof(edidData)) + { + ffStrbufClear(edidName); + ffEdidGetName(edidData, edidName); + closedir(dirp); + return true; + } + break; } } + ffStrbufClear(edidName); + closedir(dirp); + return false; } static void waylandOutputNameListener(void *data, FF_MAYBE_UNUSED struct wl_output *output, const char *name) { WaylandDisplay* display = data; - if(strncmp(name, "eDP-", strlen("eDP-")) == 0) + if(ffStrStartsWith(name, "eDP-")) display->type = FF_DISPLAY_TYPE_BUILTIN; - else if(strncmp(name, "HDMI-", strlen("HDMI-")) == 0 || strncmp(name, "DP-", strlen("DP-")) == 0) + else if(ffStrStartsWith(name, "HDMI-")) display->type = FF_DISPLAY_TYPE_EXTERNAL; + matchDrmConnector(name, &display->edidName); + ffStrbufAppendS(&display->name, name); +} + +static void waylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED struct wl_output* wl_output, const char* description) +{ + WaylandDisplay* display = data; + while (*description == ' ') ++description; + if (!ffStrEquals(description, "Unknown Display")) + ffStrbufAppendS(&display->description, description); } static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) @@ -122,7 +168,6 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist return; WaylandDisplay display = { - .detectName = wldata->detectName, .width = 0, .height = 0, .refreshRate = 0, @@ -131,6 +176,9 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist .type = FF_DISPLAY_TYPE_UNKNOWN, }; ffStrbufInit(&display.name); + ffStrbufInit(&display.description); + ffStrbufInit(&display.vendorAndModelId); + ffStrbufInit(&display.edidName); // Dirty hack for #477 // The order of these callbacks MUST follow `struct wl_output_listener` @@ -140,7 +188,7 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist stubListener, // done waylandOutputScaleListener, // scale waylandOutputNameListener, // name - stubListener, // description + waylandOutputDescriptionListener, // description }; static_assert( sizeof(outputListener) >= sizeof(struct wl_output_listener), @@ -172,16 +220,49 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist break; } + uint32_t rotation; + switch(display.transform) + { + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + case WL_OUTPUT_TRANSFORM_90: + rotation = 90; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + case WL_OUTPUT_TRANSFORM_180: + rotation = 180; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + case WL_OUTPUT_TRANSFORM_270: + rotation = 270; + break; + default: + rotation = 0; + break; + } + ffdsAppendDisplay(wldata->result, (uint32_t) display.width, (uint32_t) display.height, display.refreshRate / 1000.0, (uint32_t) (display.width / display.scale), (uint32_t) (display.height / display.scale), - &display.name, - display.type + rotation, + display.edidName.length + ? &display.edidName + : display.description.length + ? &display.description + : display.vendorAndModelId.length + ? &display.vendorAndModelId : &display.name, + display.type, + false, + 0 ); + ffStrbufDestroy(&display.description); + ffStrbufDestroy(&display.vendorAndModelId); + ffStrbufDestroy(&display.name); + ffStrbufDestroy(&display.edidName); + ffThreadMutexUnlock(&mutex); } @@ -189,13 +270,13 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u { WaylandData* wldata = data; - if(strcmp(interface, wldata->ffwl_output_interface->name) == 0) + if(ffStrEquals(interface, wldata->ffwl_output_interface->name)) waylandOutputHandler(wldata, registry, name, version); } -bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result) +bool detectWayland(FFDisplayServerResult* result) { - FF_LIBRARY_LOAD(wayland, &instance->config.libWayland, false, "libwayland-client" FF_LIBRARY_EXTENSION, 1) + FF_LIBRARY_LOAD(wayland, &instance.config.libWayland, false, "libwayland-client" FF_LIBRARY_EXTENSION, 1) FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_connect, false) FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_get_fd, false) @@ -216,8 +297,6 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result) if(data.display == NULL) return false; - data.detectName = instance->config.displayDetectName; - waylandDetectWM(ffwl_display_get_fd(data.display), result); struct wl_proxy* registry = ffwl_proxy_marshal_constructor((struct wl_proxy*) data.display, WL_DISPLAY_GET_REGISTRY, ffwl_registry_interface, NULL); @@ -249,17 +328,15 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result) } #endif -void ffdsConnectWayland(const FFinstance* instance, FFDisplayServerResult* result) +void ffdsConnectWayland(FFDisplayServerResult* result) { //Wayland requires this to be set if(getenv("XDG_RUNTIME_DIR") == NULL) return; #ifdef FF_HAVE_WAYLAND - if(detectWayland(instance, result)) + if(detectWayland(result)) return; - #else - FF_UNUSED(instance); #endif const char* xdgSessionType = getenv("XDG_SESSION_TYPE"); diff --git a/src/detection/displayserver/linux/wmde.c b/src/detection/displayserver/linux/wmde.c index 12c9185bf3..f1bcea4eee 100644 --- a/src/detection/displayserver/linux/wmde.c +++ b/src/detection/displayserver/linux/wmde.c @@ -11,7 +11,7 @@ #include #include -static const char* parseEnv() +static const char* parseEnv(void) { const char* env; @@ -55,52 +55,64 @@ static const char* parseEnv() return NULL; } -static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* processName) +static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name) { - if(!ffStrSet(processName)) + if(!ffStrSet(name)) return; if( - strcasecmp(processName, "kwin_wayland") == 0 || - strcasecmp(processName, "kwin_wayland_wrapper") == 0 || - strcasecmp(processName, "kwin_x11") == 0 || - strcasecmp(processName, "kwin_x11_wrapper") == 0 || - strcasecmp(processName, "kwin") == 0 + strcasecmp(name, "kwin_wayland") == 0 || + strcasecmp(name, "kwin_wayland_wrapper") == 0 || + strcasecmp(name, "kwin_x11") == 0 || + strcasecmp(name, "kwin_x11_wrapper") == 0 || + strcasecmp(name, "kwin") == 0 ) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_KWIN); else if( - strcasecmp(processName, "gnome-shell") == 0 || - strcasecmp(processName, "gnome shell") == 0 || - strcasecmp(processName, "gnome-session-binary") == 0 || - strcasecmp(processName, "Mutter") == 0 + strcasecmp(name, "gnome-shell") == 0 || + strcasecmp(name, "gnome shell") == 0 || + strcasecmp(name, "gnome-session-binary") == 0 || + strcasecmp(name, "Mutter") == 0 ) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUTTER); else if( - strcasecmp(processName, "cinnamon-session") == 0 || - strcasecmp(processName, "Muffin") == 0 || - strcasecmp(processName, "Mutter (Muffin)") == 0 + strcasecmp(name, "cinnamon-session") == 0 || + strcasecmp(name, "Muffin") == 0 || + strcasecmp(name, "Mutter (Muffin)") == 0 ) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUFFIN); - else if(strcasecmp(processName, "sway") == 0) + else if(strcasecmp(name, "sway") == 0) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_SWAY); - else if(strcasecmp(processName, "weston") == 0) + else if(strcasecmp(name, "weston") == 0) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WESTON); - else if(strcasecmp(processName, "wayfire") == 0) + else if(strcasecmp(name, "wayfire") == 0) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WAYFIRE); - else if(strcasecmp(processName, "openbox") == 0) + else if(strcasecmp(name, "openbox") == 0) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_OPENBOX); - else if(strcasecmp(processName, "xfwm4") == 0) + else if(strcasecmp(name, "xfwm4") == 0) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XFWM4); - else if(strcasecmp(processName, "Marco") == 0) + else if(strcasecmp(name, "Marco") == 0 || + strcasecmp(name, "Metacity (Marco)") == 0) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MARCO); - else if(strcasecmp(processName, "xmonad") == 0) + else if(strcasecmp(name, "xmonad") == 0) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XMONAD); - else if(strcasecmp(processName, "WSLg") == 0) + else if(strcasecmp(name, "WSLg") == 0) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WSLG); - else if( // WMs where the pretty name matches the process name - strcasecmp(processName, "dwm") == 0 || - strcasecmp(processName, "bspwm") == 0 || - strcasecmp(processName, "tinywm") == 0 - ) ffStrbufSetS(&result->wmPrettyName, processName); + else if(strcasecmp(name, "dwm") == 0) + ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DWM); + else if(strcasecmp(name, "bspwm") == 0) + ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_BSPWM); + else if(strcasecmp(name, "tinywm") == 0) + ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_TINYWM); + else if(strcasecmp(name, "qtile") == 0) + ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_QTILE); + else if(strcasecmp(name, "herbstluftwm") == 0) + ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_HERBSTLUFTWM); + else if(strcasecmp(name, "icewm") == 0) + ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_ICEWM); +} - if(result->wmPrettyName.length > 0 && result->wmProcessName.length == 0) +static void applyNameIfWM(FFDisplayServerResult* result, const char* processName) +{ + applyPrettyNameIfWM(result, processName); + if(result->wmPrettyName.length > 0) ffStrbufSetS(&result->wmProcessName, processName); } @@ -109,18 +121,17 @@ static void applyBetterWM(FFDisplayServerResult* result, const char* processName if(!ffStrSet(processName)) return; + ffStrbufSetS(&result->wmProcessName, processName); + //If it is a known wm, this will set the pretty name applyPrettyNameIfWM(result, processName); - //If it isn't a known wm, we have to set the process name our self - ffStrbufSetS(&result->wmProcessName, processName); - //If it isn't a known wm, set the pretty name to the process name if(result->wmPrettyName.length == 0) ffStrbufAppend(&result->wmPrettyName, &result->wmProcessName); } -static void getKDE(const FFinstance* instance, FFDisplayServerResult* result) +static void getKDE(FFDisplayServerResult* result) { ffStrbufSetS(&result->deProcessName, "plasmashell"); ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_PLASMA); @@ -129,9 +140,9 @@ static void getKDE(const FFinstance* instance, FFDisplayServerResult* result) {"X-KDE-PluginInfo-Version =", &result->deVersion} }); if(result->deVersion.length == 0) - ffParsePropFileData(instance, "xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion); + ffParsePropFileData("xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion); if(result->deVersion.length == 0) - ffParsePropFileData(instance, "xsessions/plasma5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion); + ffParsePropFileData("xsessions/plasma5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion); if(result->deVersion.length == 0) { ffParsePropFileValues("/usr/share/wayland-sessions/plasma.desktop", 1, (FFpropquery[]) { @@ -139,11 +150,11 @@ static void getKDE(const FFinstance* instance, FFDisplayServerResult* result) }); } if(result->deVersion.length == 0) - ffParsePropFileData(instance, "wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion); + ffParsePropFileData("wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion); if(result->deVersion.length == 0) - ffParsePropFileData(instance, "wayland-sessions/plasmawayland5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion); + ffParsePropFileData("wayland-sessions/plasmawayland5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion); - if(result->deVersion.length == 0 && instance->config.allowSlowOperations) + if(result->deVersion.length == 0 && instance.config.allowSlowOperations) { if (ffProcessAppendStdOut(&result->deVersion, (char* const[]){ "plasmashell", @@ -157,11 +168,16 @@ static void getKDE(const FFinstance* instance, FFDisplayServerResult* result) applyBetterWM(result, getenv("KDEWM")); } -static void getGnome(const FFinstance* instance, FFDisplayServerResult* result) +static void getGnome(FFDisplayServerResult* result) { ffStrbufSetS(&result->deProcessName, "gnome-shell"); - ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_GNOME); - ffParsePropFileData(instance, "gnome-shell/org.gnome.Extensions", "version :", &result->deVersion); + const char* sessionMode = getenv("GNOME_SHELL_SESSION_MODE"); + if (sessionMode && ffStrEquals(sessionMode, "classic")) + ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_GNOME_CLASSIC); + else + ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_GNOME); + + ffParsePropFileData("gnome-shell/org.gnome.Extensions", "version :", &result->deVersion); if (result->deVersion.length == 0) { @@ -174,28 +190,23 @@ static void getGnome(const FFinstance* instance, FFDisplayServerResult* result) } } -static void getCinnamon(const FFinstance* instance, FFDisplayServerResult* result) +static void getCinnamon(FFDisplayServerResult* result) { ffStrbufSetS(&result->deProcessName, "cinnamon"); ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CINNAMON); - ffParsePropFileData(instance, "applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", &result->deVersion); + ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", &result->deVersion); } -static void getMate(const FFinstance* instance, FFDisplayServerResult* result) +static void getMate(FFDisplayServerResult* result) { ffStrbufSetS(&result->deProcessName, "mate-session"); ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_MATE); - FFstrbuf major; - ffStrbufInit(&major); - - FFstrbuf minor; - ffStrbufInit(&minor); + FF_STRBUF_AUTO_DESTROY major = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY minor = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY micro = ffStrbufCreate(); - FFstrbuf micro; - ffStrbufInit(µ); - - ffParsePropFileDataValues(instance, "mate-about/mate-version.xml", 3, (FFpropquery[]) { + ffParsePropFileDataValues("mate-about/mate-version.xml", 3, (FFpropquery[]) { {"", &major}, {"", &minor}, {"", µ} @@ -203,11 +214,7 @@ static void getMate(const FFinstance* instance, FFDisplayServerResult* result) ffParseSemver(&result->deVersion, &major, &minor, µ); - ffStrbufDestroy(&major); - ffStrbufDestroy(&minor); - ffStrbufDestroy(µ); - - if(result->deVersion.length == 0 && instance->config.allowSlowOperations) + if(result->deVersion.length == 0 && instance.config.allowSlowOperations) { ffProcessAppendStdOut(&result->deVersion, (char* const[]){ "mate-session", @@ -220,13 +227,13 @@ static void getMate(const FFinstance* instance, FFDisplayServerResult* result) } } -static void getXFCE4(const FFinstance* instance, FFDisplayServerResult* result) +static void getXFCE4(FFDisplayServerResult* result) { ffStrbufSetS(&result->deProcessName, "xfce4-session"); ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_XFCE4); - ffParsePropFileData(instance, "gtk-doc/html/libxfce4ui/index.html", "

Version", &result->deVersion); + ffParsePropFileData("gtk-doc/html/libxfce4ui/index.html", "

Version", &result->deVersion); - if(result->deVersion.length == 0 && instance->config.allowSlowOperations) + if(result->deVersion.length == 0 && instance.config.allowSlowOperations) { //This is somewhat slow ffProcessAppendStdOut(&result->deVersion, (char* const[]){ @@ -241,18 +248,18 @@ static void getXFCE4(const FFinstance* instance, FFDisplayServerResult* result) } } -static void getLXQt(const FFinstance* instance, FFDisplayServerResult* result) +static void getLXQt(FFDisplayServerResult* result) { ffStrbufSetS(&result->deProcessName, "lxqt-session"); ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_LXQT); - ffParsePropFileData(instance, "gconfig/lxqt.pc", "Version:", &result->deVersion); + ffParsePropFileData("gconfig/lxqt.pc", "Version:", &result->deVersion); if(result->deVersion.length == 0) - ffParsePropFileData(instance, "cmake/lxqt/lxqt-config.cmake", "set ( LXQT_VERSION", &result->deVersion); + ffParsePropFileData("cmake/lxqt/lxqt-config.cmake", "set ( LXQT_VERSION", &result->deVersion); if(result->deVersion.length == 0) - ffParsePropFileData(instance, "cmake/lxqt/lxqt-config-version.cmake", "set ( PACKAGE_VERSION", &result->deVersion); + ffParsePropFileData("cmake/lxqt/lxqt-config-version.cmake", "set ( PACKAGE_VERSION", &result->deVersion); - if(result->deVersion.length == 0 && instance->config.allowSlowOperations) + if(result->deVersion.length == 0 && instance.config.allowSlowOperations) { //This is really, really, really slow. Thank you, LXQt developers ffProcessAppendStdOut(&result->deVersion, (char* const[]){ @@ -265,23 +272,20 @@ static void getLXQt(const FFinstance* instance, FFDisplayServerResult* result) ffParsePropLines(result->deVersion.chars , "liblxqt", &result->deVersion); } - FFstrbuf wmProcessNameBuffer; - ffStrbufInit(&wmProcessNameBuffer); + FF_STRBUF_AUTO_DESTROY wmProcessNameBuffer = ffStrbufCreate(); - ffParsePropFileConfig(instance, "lxqt/session.conf", "window_manager =", &wmProcessNameBuffer); + ffParsePropFileConfig("lxqt/session.conf", "window_manager =", &wmProcessNameBuffer); applyBetterWM(result, wmProcessNameBuffer.chars); - - ffStrbufDestroy(&wmProcessNameBuffer); } -static void getBudgie(const FFinstance* instance, FFDisplayServerResult* result) +static void getBudgie(FFDisplayServerResult* result) { ffStrbufSetS(&result->deProcessName, "budgie-desktop"); ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_BUDGIE); - ffParsePropFileData(instance, "budgie/budgie-version.xml", "", &result->deVersion); + ffParsePropFileData("budgie/budgie-version.xml", "", &result->deVersion); } -static void applyPrettyNameIfDE(const FFinstance* instance, FFDisplayServerResult* result, const char* name) +static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name) { if(!ffStrSet(name)) return; @@ -291,19 +295,19 @@ static void applyPrettyNameIfDE(const FFinstance* instance, FFDisplayServerResul strcasecmp(name, "plasma") == 0 || strcasecmp(name, "plasmashell") == 0 || strcasecmp(name, "plasmawayland") == 0 - ) getKDE(instance, result); + ) getKDE(result); else if( strcasecmp(name, "Gnome") == 0 || strcasecmp(name, "ubuntu:GNOME") == 0 || strcasecmp(name, "ubuntu") == 0 || strcasecmp(name, "gnome-shell") == 0 - ) getGnome(instance, result); + ) getGnome(result); else if( strcasecmp(name, "X-Cinnamon") == 0 || strcasecmp(name, "Cinnamon") == 0 - ) getCinnamon(instance, result); + ) getCinnamon(result); else if( strcasecmp(name, "XFCE") == 0 || @@ -311,26 +315,26 @@ static void applyPrettyNameIfDE(const FFinstance* instance, FFDisplayServerResul strcasecmp(name, "XFCE4") == 0 || strcasecmp(name, "X-XFCE4") == 0 || strcasecmp(name, "xfce4-session") == 0 - ) getXFCE4(instance, result); + ) getXFCE4(result); else if( strcasecmp(name, "MATE") == 0 || strcasecmp(name, "X-MATE") == 0 || strcasecmp(name, "mate-session") == 0 - ) getMate(instance, result); + ) getMate(result); else if( strcasecmp(name, "LXQt") == 0 || strcasecmp(name, "X-LXQT") == 0 || strcasecmp(name, "lxqt-session") == 0 - ) getLXQt(instance, result); + ) getLXQt(result); else if( strcasecmp(name, "Budgie") == 0 || strcasecmp(name, "X-Budgie") == 0 || strcasecmp(name, "budgie-desktop") == 0 || strcasecmp(name, "Budgie:GNOME") == 0 - ) getBudgie(instance, result); + ) getBudgie(result); } static void getWMProtocolNameFromEnv(FFDisplayServerResult* result) @@ -366,27 +370,20 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result) } } -static void getFromProcDir(const FFinstance* instance, FFDisplayServerResult* result) +static void getFromProcDir(FFDisplayServerResult* result) { DIR* proc = opendir("/proc"); if(proc == NULL) return; - FFstrbuf procPath; - ffStrbufInitA(&procPath, 64); + FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreateA(64); ffStrbufAppendS(&procPath, "/proc/"); uint32_t procPathLength = procPath.length; - FFstrbuf userID; - ffStrbufInit(&userID); - ffStrbufAppendF(&userID, "%i", getuid()); - - FFstrbuf loginuid; - ffStrbufInit(&loginuid); - - FFstrbuf processName; - ffStrbufInitA(&processName, 256); //Some processes have large command lines (looking at you chrome) + FF_STRBUF_AUTO_DESTROY userID = ffStrbufCreateF("%i", getuid()); + FF_STRBUF_AUTO_DESTROY loginuid = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY processName = ffStrbufCreateA(256); //Some processes have large command lines (looking at you chrome) struct dirent* dirent; while((dirent = readdir(proc)) != NULL) @@ -418,24 +415,19 @@ static void getFromProcDir(const FFinstance* instance, FFDisplayServerResult* re ffStrbufSubstrBefore(&procPath, procPathLength); if(result->dePrettyName.length == 0) - applyPrettyNameIfDE(instance, result, processName.chars); + applyPrettyNameIfDE(result, processName.chars); if(result->wmPrettyName.length == 0) - applyPrettyNameIfWM(result, processName.chars); + applyNameIfWM(result, processName.chars); if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0) break; } closedir(proc); - - ffStrbufDestroy(&processName); - ffStrbufDestroy(&loginuid); - ffStrbufDestroy(&userID); - ffStrbufDestroy(&procPath); } -void ffdsDetectWMDE(const FFinstance* instance, FFDisplayServerResult* result) +void ffdsDetectWMDE(FFDisplayServerResult* result) { //If all connections failed, use the environment variables to detect protocol name if(result->wmProtocolName.length == 0) @@ -459,12 +451,12 @@ void ffdsDetectWMDE(const FFinstance* instance, FFDisplayServerResult* result) else { //if env is a known WM, use it - applyPrettyNameIfWM(result, env); + applyNameIfWM(result, env); } //Connecting to a display server only gives WM results, not DE results. //If we find it in the environment, use that. - applyPrettyNameIfDE(instance, result, env); + applyPrettyNameIfDE(result, env); //If WM was found by connection to the sever, and DE in the environment, we can return //This way we never call getFromProcDir(), which has slow initalization time @@ -472,7 +464,7 @@ void ffdsDetectWMDE(const FFinstance* instance, FFDisplayServerResult* result) return; //Get missing WM / DE from processes. - getFromProcDir(instance, result); + getFromProcDir(result); //Return if both wm and de are set, or if env doesn't contain anything if( diff --git a/src/detection/displayserver/linux/xcb.c b/src/detection/displayserver/linux/xcb.c index 447c76bb27..d968bfbad4 100644 --- a/src/detection/displayserver/linux/xcb.c +++ b/src/detection/displayserver/linux/xcb.c @@ -1,4 +1,5 @@ #include "displayserver_linux.h" +#include "util/mallocHelper.h" #ifdef FF_HAVE_XCB #include "common/library.h" @@ -14,6 +15,10 @@ typedef struct XcbPropertyData FF_LIBRARY_SYMBOL(xcb_get_property_reply) FF_LIBRARY_SYMBOL(xcb_get_property_value) FF_LIBRARY_SYMBOL(xcb_get_property_value_length) + FF_LIBRARY_SYMBOL(xcb_get_atom_name) + FF_LIBRARY_SYMBOL(xcb_get_atom_name_name) + FF_LIBRARY_SYMBOL(xcb_get_atom_name_name_length) + FF_LIBRARY_SYMBOL(xcb_get_atom_name_reply) } XcbPropertyData; static bool xcbInitPropertyData(void* libraryHandle, XcbPropertyData* propertyData) @@ -24,6 +29,10 @@ static bool xcbInitPropertyData(void* libraryHandle, XcbPropertyData* propertyDa FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_get_property_reply, false) FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_get_property_value, false) FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_get_property_value_length, false) + FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_get_atom_name, false) + FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_get_atom_name_name, false) + FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_get_atom_name_name_length, false) + FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_get_atom_name_reply, false) return true; } @@ -89,9 +98,9 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect free(wmName); } -void ffdsConnectXcb(const FFinstance* instance, FFDisplayServerResult* result) +void ffdsConnectXcb(FFDisplayServerResult* result) { - FF_LIBRARY_LOAD(xcb, &instance->config.libXcb, , "libxcb" FF_LIBRARY_EXTENSION, 2) + FF_LIBRARY_LOAD(xcb, &instance.config.libXcb, , "libxcb" FF_LIBRARY_EXTENSION, 2) FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_connect,) FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_get_setup,) FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_setup_roots_iterator,) @@ -118,8 +127,11 @@ void ffdsConnectXcb(const FFinstance* instance, FFDisplayServerResult* result) 0, (uint32_t) iterator.data->width_in_pixels, (uint32_t) iterator.data->height_in_pixels, + 0, NULL, - FF_DISPLAY_TYPE_UNKNOWN + FF_DISPLAY_TYPE_UNKNOWN, + false, + 0 ); ffxcb_screen_next(&iterator); } @@ -133,15 +145,16 @@ void ffdsConnectXcb(const FFinstance* instance, FFDisplayServerResult* result) #else -void ffdsConnectXcb(const FFinstance* instance, FFDisplayServerResult* result) +void ffdsConnectXcb(FFDisplayServerResult* result) { //Do nothing. There are other implementations coming - FF_UNUSED(instance, result) + FF_UNUSED(result) } #endif #ifdef FF_HAVE_XCB_RANDR +#include "util/edidHelper.h" #include typedef struct XcbRandrData @@ -163,17 +176,25 @@ typedef struct XcbRandrData FF_LIBRARY_SYMBOL(xcb_randr_get_output_info_reply) FF_LIBRARY_SYMBOL(xcb_randr_get_crtc_info) FF_LIBRARY_SYMBOL(xcb_randr_get_crtc_info_reply) + FF_LIBRARY_SYMBOL(xcb_randr_get_output_property) + FF_LIBRARY_SYMBOL(xcb_randr_get_output_property_reply) + FF_LIBRARY_SYMBOL(xcb_randr_get_output_property_data) + FF_LIBRARY_SYMBOL(xcb_randr_get_output_property_data_length) + FF_LIBRARY_SYMBOL(xcb_intern_atom) + FF_LIBRARY_SYMBOL(xcb_intern_atom_reply) //init once xcb_connection_t* connection; FFDisplayServerResult* result; + XcbPropertyData propData; //init per screen uint32_t defaultRefreshRate; + uint32_t defaultRotation; xcb_randr_get_screen_resources_reply_t* screenResources; } XcbRandrData; -static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo) +static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo, FFstrbuf* name, uint32_t rotation, bool primary) { double refreshRate = (double) modeInfo->dot_clock / (double) (modeInfo->htotal * modeInfo->vtotal); @@ -184,12 +205,15 @@ static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* mo refreshRate == 0 ? data->defaultRefreshRate : refreshRate, (uint32_t) modeInfo->width, (uint32_t) modeInfo->height, - NULL, - FF_DISPLAY_TYPE_UNKNOWN + rotation, + name, + FF_DISPLAY_TYPE_UNKNOWN, + primary, + 0 ); } -static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode) +static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrbuf* name, uint32_t rotation, bool primary) { //We do the check here, because we want the best fallback display if this call failed if(data->screenResources == NULL) @@ -200,7 +224,7 @@ static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode) while(modesIterator.rem > 0) { if(modesIterator.data->id == mode) - return xcbRandrHandleModeInfo(data, modesIterator.data); + return xcbRandrHandleModeInfo(data, modesIterator.data, name, rotation, primary); data->ffxcb_randr_mode_info_next(&modesIterator); } @@ -208,14 +232,30 @@ static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode) return false; } -static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc) +static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrbuf* name, bool primary) { xcb_randr_get_crtc_info_cookie_t crtcInfoCookie = data->ffxcb_randr_get_crtc_info(data->connection, crtc, XCB_CURRENT_TIME); xcb_randr_get_crtc_info_reply_t* crtcInfoReply = data->ffxcb_randr_get_crtc_info_reply(data->connection, crtcInfoCookie, NULL); if(crtcInfoReply == NULL) return false; - bool res = xcbRandrHandleMode(data, crtcInfoReply->mode); + uint32_t rotation; + switch (crtcInfoReply->rotation) + { + case XCB_RANDR_ROTATION_ROTATE_90: + rotation = 90; + break; + case XCB_RANDR_ROTATION_ROTATE_180: + rotation = 180; + break; + case XCB_RANDR_ROTATION_ROTATE_270: + rotation = 270; + break; + default: + rotation = 0; + break; + } + bool res = xcbRandrHandleMode(data, crtcInfoReply->mode, name, rotation, primary); res = res ? true : ffdsAppendDisplay( data->result, (uint32_t) crtcInfoReply->width, @@ -223,24 +263,41 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc) data->defaultRefreshRate, (uint32_t) crtcInfoReply->width, (uint32_t) crtcInfoReply->height, - NULL, - FF_DISPLAY_TYPE_UNKNOWN + rotation, + name, + FF_DISPLAY_TYPE_UNKNOWN, + primary, + 0 ); free(crtcInfoReply); return res; } -static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output) +static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, FFstrbuf* name, bool primary) { xcb_randr_get_output_info_cookie_t outputInfoCookie = data->ffxcb_randr_get_output_info(data->connection, output, XCB_CURRENT_TIME); - xcb_randr_get_output_info_reply_t* outputInfoReply = data->ffxcb_randr_get_output_info_reply(data->connection, outputInfoCookie, NULL); + FF_AUTO_FREE xcb_randr_get_output_info_reply_t* outputInfoReply = data->ffxcb_randr_get_output_info_reply(data->connection, outputInfoCookie, NULL); if(outputInfoReply == NULL) return false; - bool res = xcbRandrHandleCrtc(data, outputInfoReply->crtc); + xcb_intern_atom_cookie_t requestAtomCookie = data->ffxcb_intern_atom(data->connection, true, (uint16_t) strlen("EDID"), "EDID"); + FF_AUTO_FREE xcb_intern_atom_reply_t* requestAtomReply = data->ffxcb_intern_atom_reply(data->connection, requestAtomCookie, NULL); + if(requestAtomReply) + { + xcb_randr_get_output_property_cookie_t outputPropertyCookie = data->ffxcb_randr_get_output_property(data->connection, output, requestAtomReply->atom, XCB_GET_PROPERTY_TYPE_ANY, 0, 100, false, false); + FF_AUTO_FREE xcb_randr_get_output_property_reply_t* outputPropertyReply = data->ffxcb_randr_get_output_property_reply(data->connection, outputPropertyCookie, NULL); + if(outputPropertyReply) + { + if(data->ffxcb_randr_get_output_property_data_length(outputPropertyReply) >= 128) + { + ffStrbufClear(name); + ffEdidGetName(data->ffxcb_randr_get_output_property_data(outputPropertyReply), name); + } + } + } - free(outputInfoReply); + bool res = xcbRandrHandleCrtc(data, outputInfoReply->crtc, name, primary); return res; } @@ -254,11 +311,21 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t* .rem = data->ffxcb_randr_monitor_info_outputs_length(monitor) }; + FF_AUTO_FREE xcb_get_atom_name_reply_t* nameReply = data->propData.ffxcb_get_atom_name_reply( + data->connection, + data->propData.ffxcb_get_atom_name(data->connection, monitor->name), + NULL + ); + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateNS( + (uint32_t) data->propData.ffxcb_get_atom_name_name_length(nameReply), + data->propData.ffxcb_get_atom_name_name(nameReply) + ); + bool foundOutput = false; while(outputIterator.rem > 0) { - if(xcbRandrHandleOutput(data, *outputIterator.data)) + if(xcbRandrHandleOutput(data, *outputIterator.data, &name, monitor->primary)) foundOutput = true; data->ffxcb_randr_output_next(&outputIterator); }; @@ -270,8 +337,11 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t* data->defaultRefreshRate, (uint32_t) monitor->width, (uint32_t) monitor->height, - NULL, - FF_DISPLAY_TYPE_UNKNOWN + data->defaultRotation, + &name, + FF_DISPLAY_TYPE_UNKNOWN, + !!monitor->primary, + 0 ); } @@ -307,11 +377,28 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen) if(screenInfoReply != NULL) { data->defaultRefreshRate = screenInfoReply->rate; + switch (screenInfoReply->rotation) + { + case XCB_RANDR_ROTATION_ROTATE_90: + data->defaultRotation = 90; + break; + case XCB_RANDR_ROTATION_ROTATE_180: + data->defaultRotation = 180; + break; + case XCB_RANDR_ROTATION_ROTATE_270: + data->defaultRotation = 270; + break; + default: + data->defaultRotation = 0; + break; + } free(screenInfoReply); } else + { data->defaultRefreshRate = 0; - + data->defaultRotation = 0; + } //Init screen resources. They are used to iterate over all modes. xcbRandrHandleMode checks for " == NULL", to fail as late as possible. xcb_randr_get_screen_resources_cookie_t screenResourcesCookie = data->ffxcb_randr_get_screen_resources(data->connection, screen->root); data->screenResources = data->ffxcb_randr_get_screen_resources_reply(data->connection, screenResourcesCookie, NULL); @@ -332,14 +419,17 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen) data->defaultRefreshRate, (uint32_t) screen->width_in_pixels, (uint32_t) screen->height_in_pixels, + data->defaultRotation, NULL, - FF_DISPLAY_TYPE_UNKNOWN + FF_DISPLAY_TYPE_UNKNOWN, + false, + 0 ); } -void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* result) +void ffdsConnectXcbRandr(FFDisplayServerResult* result) { - FF_LIBRARY_LOAD(xcbRandr, &instance->config.libXcbRandr, , "libxcb-randr" FF_LIBRARY_EXTENSION, 1) + FF_LIBRARY_LOAD(xcbRandr, &instance.config.libXcbRandr, , "libxcb-randr" FF_LIBRARY_EXTENSION, 1) FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_connect,) FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_get_setup,) FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_setup_roots_iterator,) @@ -348,6 +438,8 @@ void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* resu XcbRandrData data; + FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_intern_atom,) + FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_intern_atom_reply,) FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources,) FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_reply,) FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_modes_iterator,) @@ -363,11 +455,14 @@ void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* resu FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_output_next,) FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_info,) FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_info_reply,) + FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property,) + FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property_reply,) + FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property_data,) + FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property_data_length,) FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_crtc_info,) FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_crtc_info_reply,) - XcbPropertyData propertyData; - bool propertyDataInitialized = xcbInitPropertyData(xcbRandr, &propertyData); + bool propertyDataInitialized = xcbInitPropertyData(xcbRandr, &data.propData); data.connection = ffxcb_connect(NULL, NULL); if(data.connection == NULL) @@ -378,7 +473,7 @@ void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* resu xcb_screen_iterator_t iterator = ffxcb_setup_roots_iterator(ffxcb_get_setup(data.connection)); if(iterator.rem > 0 && propertyDataInitialized) - xcbDetectWMfromEWMH(&propertyData, data.connection, iterator.data->root, result); + xcbDetectWMfromEWMH(&data.propData, data.connection, iterator.data->root, result); while(iterator.rem > 0) { @@ -395,10 +490,10 @@ void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* resu #else -void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* result) +void ffdsConnectXcbRandr(FFDisplayServerResult* result) { //Do nothing. There are other implementations coming - FF_UNUSED(instance, result) + FF_UNUSED(result) } #endif diff --git a/src/detection/displayserver/linux/xlib.c b/src/detection/displayserver/linux/xlib.c index 13a08b2a5e..19b6fee374 100644 --- a/src/detection/displayserver/linux/xlib.c +++ b/src/detection/displayserver/linux/xlib.c @@ -58,9 +58,9 @@ static void x11DetectWMFromEWMH(X11PropertyData* data, Display* display, FFDispl data->ffXFree(wmWindow); } -void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result) +void ffdsConnectXlib(FFDisplayServerResult* result) { - FF_LIBRARY_LOAD(x11, &instance->config.libX11, , "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2) + FF_LIBRARY_LOAD(x11, &instance.config.libX11, , "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2) FF_LIBRARY_LOAD_SYMBOL(x11, XOpenDisplay,) FF_LIBRARY_LOAD_SYMBOL(x11, XCloseDisplay,) @@ -83,8 +83,11 @@ void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result) 0, (uint32_t) WidthOfScreen(screen), (uint32_t) HeightOfScreen(screen), + 0, NULL, - FF_DISPLAY_TYPE_UNKNOWN + FF_DISPLAY_TYPE_UNKNOWN, + false, + 0 ); } @@ -97,25 +100,29 @@ void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result) #else -void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result) +void ffdsConnectXlib(FFDisplayServerResult* result) { //Do nothing. WM / DE detection will use environment vars to detect as much as possible. - FF_UNUSED(instance, result); + FF_UNUSED(result); } #endif //FF_HAVE_X11 #ifdef FF_HAVE_XRANDR +#include "util/edidHelper.h" #include typedef struct XrandrData { + FF_LIBRARY_SYMBOL(XInternAtom) + FF_LIBRARY_SYMBOL(XGetAtomName); 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(XRRGetOutputProperty) FF_LIBRARY_SYMBOL(XRRGetCrtcInfo) FF_LIBRARY_SYMBOL(XRRFreeCrtcInfo) FF_LIBRARY_SYMBOL(XRRFreeOutputInfo) @@ -129,36 +136,24 @@ typedef struct XrandrData //Init per screen uint32_t defaultRefreshRate; + uint32_t defaultRotation; XRRScreenResources* screenResources; } XrandrData; -static bool xrandrHandleModeInfo(XrandrData* data, XRRModeInfo* modeInfo) -{ - double refreshRate = (double) modeInfo->dotClock / (double) (modeInfo->hTotal * modeInfo->vTotal); - - return ffdsAppendDisplay( - data->result, - (uint32_t) modeInfo->width, - (uint32_t) modeInfo->height, - refreshRate == 0 ? data->defaultRefreshRate : refreshRate, - (uint32_t) modeInfo->width, - (uint32_t) modeInfo->height, - NULL, - FF_DISPLAY_TYPE_UNKNOWN - ); -} - -static bool xrandrHandleMode(XrandrData* data, RRMode mode) +static double xrandrHandleMode(XrandrData* data, RRMode mode) { for(int i = 0; i < data->screenResources->nmode; i++) { if(data->screenResources->modes[i].id == mode) - return xrandrHandleModeInfo(data, &data->screenResources->modes[i]); + { + XRRModeInfo* modeInfo = &data->screenResources->modes[i]; + return (double) modeInfo->dotClock / (double) (modeInfo->hTotal * modeInfo->vTotal); + } } - return false; + return data->defaultRefreshRate; } -static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc) +static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool primary) { //We do the check here, because we want the best fallback display if this call failed if(data->screenResources == NULL) @@ -168,29 +163,62 @@ static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc) if(crtcInfo == NULL) return false; - bool res = xrandrHandleMode(data, crtcInfo->mode); - res = res ? true : ffdsAppendDisplay( + uint32_t rotation; + switch (crtcInfo->rotation) + { + case RR_Rotate_90: + rotation = 90; + break; + case RR_Rotate_180: + rotation = 180; + break; + case RR_Rotate_270: + rotation = 270; + break; + default: + rotation = 0; + break; + } + + bool res = ffdsAppendDisplay( data->result, (uint32_t) crtcInfo->width, (uint32_t) crtcInfo->height, - data->defaultRefreshRate, + xrandrHandleMode(data, crtcInfo->mode), (uint32_t) crtcInfo->width, (uint32_t) crtcInfo->height, - NULL, - FF_DISPLAY_TYPE_UNKNOWN + rotation, + name, + FF_DISPLAY_TYPE_UNKNOWN, + primary, + 0 ); data->ffXRRFreeCrtcInfo(crtcInfo); return res; } -static bool xrandrHandleOutput(XrandrData* data, RROutput output) +static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name, bool primary) { XRROutputInfo* outputInfo = data->ffXRRGetOutputInfo(data->display, data->screenResources, output); if(outputInfo == NULL) return false; - bool res = xrandrHandleCrtc(data, outputInfo->crtc); + Atom atomEdid = data->ffXInternAtom(data->display, "EDID", true); + if (atomEdid != None) + { + unsigned long nitems = 0; + uint8_t* edidData = NULL; + if (data->ffXRRGetOutputProperty(data->display, output, atomEdid, 0, 100, 0, 0, AnyPropertyType, NULL, NULL, &nitems, NULL, &edidData) == Success) + { + if (nitems >= 128) + { + ffStrbufClear(name); + ffEdidGetName(edidData, name); + } + } + } + bool res = xrandrHandleCrtc(data, outputInfo->crtc, name, primary); data->ffXRRFreeOutputInfo(outputInfo); @@ -201,9 +229,10 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo) { bool foundOutput = false; + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(data->ffXGetAtomName(data->display, monitorInfo->name)); for(int i = 0; i < monitorInfo->noutput; i++) { - if(xrandrHandleOutput(data, monitorInfo->outputs[i])) + if(xrandrHandleOutput(data, monitorInfo->outputs[i], &name, monitorInfo->primary)) foundOutput = true; } @@ -214,8 +243,11 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo) data->defaultRefreshRate, (uint32_t) monitorInfo->width, (uint32_t) monitorInfo->height, - NULL, - FF_DISPLAY_TYPE_UNKNOWN + data->defaultRotation, + &name, + FF_DISPLAY_TYPE_UNKNOWN, + !!monitorInfo->primary, + 0 ); } @@ -247,10 +279,30 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen) if(screenConfiguration != NULL) { data->defaultRefreshRate = (uint32_t) data->ffXRRConfigCurrentRate(screenConfiguration); + Rotation rotation = 0; + data->ffXRRConfigCurrentConfiguration(screenConfiguration, &rotation); + switch (rotation) + { + case RR_Rotate_90: + data->defaultRotation = 90; + break; + case RR_Rotate_180: + data->defaultRotation = 180; + break; + case RR_Rotate_270: + data->defaultRotation = 270; + break; + default: + data->defaultRotation = 0; + break; + } data->ffXRRFreeScreenConfigInfo(screenConfiguration); } else + { data->defaultRefreshRate = 0; + data->defaultRotation = 0; + } //Init screen resources data->screenResources = data->ffXRRGetScreenResources(data->display, RootWindowOfScreen(screen)); @@ -270,25 +322,32 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen) data->defaultRefreshRate, (uint32_t) WidthOfScreen(screen), (uint32_t) HeightOfScreen(screen), + data->defaultRotation, NULL, - FF_DISPLAY_TYPE_UNKNOWN + FF_DISPLAY_TYPE_UNKNOWN, + false, + 0 ); } -void ffdsConnectXrandr(const FFinstance* instance, FFDisplayServerResult* result) +void ffdsConnectXrandr(FFDisplayServerResult* result) { - FF_LIBRARY_LOAD(xrandr, &instance->config.libXrandr, , "libXrandr" FF_LIBRARY_EXTENSION, 3) + FF_LIBRARY_LOAD(xrandr, &instance.config.libXrandr, , "libXrandr" FF_LIBRARY_EXTENSION, 3) FF_LIBRARY_LOAD_SYMBOL(xrandr, XOpenDisplay,) FF_LIBRARY_LOAD_SYMBOL(xrandr, XCloseDisplay,) XrandrData data; + FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XInternAtom,); + FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XGetAtomName,); FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenInfo,) FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRConfigCurrentRate,); + FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRConfigCurrentConfiguration,); FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetMonitors,); FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenResources,); FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputInfo,); + FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputProperty,); FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetCrtcInfo,); FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeCrtcInfo,); FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeOutputInfo,); @@ -320,10 +379,10 @@ void ffdsConnectXrandr(const FFinstance* instance, FFDisplayServerResult* result #else -void ffdsConnectXrandr(const FFinstance* instance, FFDisplayServerResult* result) +void ffdsConnectXrandr(FFDisplayServerResult* result) { //Do nothing here. There are more x11 implementaions to come. - FF_UNUSED(instance, result); + FF_UNUSED(result); } #endif // FF_HAVE_XRANDR diff --git a/src/detection/font/font.c b/src/detection/font/font.c index 865c830d1a..6de21cfdfb 100644 --- a/src/detection/font/font.c +++ b/src/detection/font/font.c @@ -1,33 +1,19 @@ #include "font.h" #include "detection/internal.h" -void ffDetectFontImpl(const FFinstance* instance, FFFontResult* font); +const char* ffDetectFontImpl(FFFontResult* font); -static void detectFont(const FFinstance* instance, FFFontResult* font) +const char* ffDetectFont(FFFontResult* font) { - ffStrbufInit(&font->error); + const char* error = ffDetectFontImpl(font); - for(uint32_t i = 0; i < FF_DETECT_FONT_NUM_FONTS; ++i) - ffStrbufInit(&font->fonts[i]); - ffStrbufInit(&font->display); - - ffDetectFontImpl(instance, font); - - if(font->error.length > 0) - return; + if(error) return error; for(uint32_t i = 0; i < FF_DETECT_FONT_NUM_FONTS; ++i) { if(font->fonts[i].length > 0) - return; + return NULL; } - ffStrbufAppendS(&font->error, "No fonts found"); -} - -const FFFontResult* ffDetectFont(const FFinstance* instance) -{ - FF_DETECTION_INTERNAL_GUARD(FFFontResult, - detectFont(instance, &result); - ); + return "No fonts found"; } diff --git a/src/detection/font/font.h b/src/detection/font/font.h index 5922375bba..22e4026520 100644 --- a/src/detection/font/font.h +++ b/src/detection/font/font.h @@ -9,8 +9,6 @@ typedef struct FFFontResult { - FFstrbuf error; - /** * Linux / BSD: QT, GTK2, GTK3, GTK4 * MacOS: System, User, System Mono, User Mono @@ -21,6 +19,6 @@ typedef struct FFFontResult FFstrbuf display; } FFFontResult; -const FFFontResult* ffDetectFont(const FFinstance* instance); +const char* ffDetectFont(FFFontResult* font); #endif diff --git a/src/detection/font/font_apple.m b/src/detection/font/font_apple.m index 471fad4307..9a9888e5f7 100644 --- a/src/detection/font/font_apple.m +++ b/src/detection/font/font_apple.m @@ -21,12 +21,13 @@ static void generateString(FFFontResult* font) } } -void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) +const char* ffDetectFontImpl(FFFontResult* result) { - FF_UNUSED(instance); ffStrbufAppendS(&result->fonts[0], [NSFont systemFontOfSize:12].familyName.UTF8String); ffStrbufAppendS(&result->fonts[1], [NSFont userFontOfSize:12].familyName.UTF8String); ffStrbufAppendS(&result->fonts[2], [NSFont monospacedSystemFontOfSize:12 weight:400].familyName.UTF8String); ffStrbufAppendS(&result->fonts[3], [NSFont userFixedPitchFontOfSize:12].familyName.UTF8String); generateString(result); + + return NULL; } diff --git a/src/detection/font/font_linux.c b/src/detection/font/font_linux.c index b0d70dd257..7cee52ccd3 100644 --- a/src/detection/font/font_linux.c +++ b/src/detection/font/font_linux.c @@ -24,35 +24,34 @@ static void generateString(FFFontResult* font) ffParseGTK(&font->display, &font->fonts[1], &font->fonts[2], &font->fonts[3]); } -void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) +const char* ffDetectFontImpl(FFFontResult* result) { - const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance); + const FFDisplayServerResult* wmde = ffConnectDisplayServer(); if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY) == 0) - { - ffStrbufAppendS(&result->error, "Font isn't supported in TTY"); - return; - } + return "Font isn't supported in TTY"; FFfont qt; - ffFontInitQt(&qt, ffDetectQt(instance)->font.chars); + ffFontInitQt(&qt, ffDetectQt()->font.chars); ffStrbufAppend(&result->fonts[0], &qt.pretty); ffFontDestroy(&qt); FFfont gtk2; - ffFontInitPango(>k2, ffDetectGTK2(instance)->font.chars); + ffFontInitPango(>k2, ffDetectGTK2()->font.chars); ffStrbufAppend(&result->fonts[1], >k2.pretty); ffFontDestroy(>k2); FFfont gtk3; - ffFontInitPango(>k3, ffDetectGTK3(instance)->font.chars); + ffFontInitPango(>k3, ffDetectGTK3()->font.chars); ffStrbufAppend(&result->fonts[2], >k3.pretty); ffFontDestroy(>k3); FFfont gtk4; - ffFontInitPango(>k4, ffDetectGTK4(instance)->font.chars); + ffFontInitPango(>k4, ffDetectGTK4()->font.chars); ffStrbufAppend(&result->fonts[3], >k4.pretty); ffFontDestroy(>k4); generateString(result); + + return NULL; } diff --git a/src/detection/font/font_nosupport.c b/src/detection/font/font_nosupport.c index f88ad83953..cce3904ff4 100644 --- a/src/detection/font/font_nosupport.c +++ b/src/detection/font/font_nosupport.c @@ -1,8 +1,8 @@ #include "fastfetch.h" #include "font.h" -void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) +const char* ffDetectFontImpl(FF_MAYBE_UNUSED FFFontResult* result) { - FF_UNUSED(instance); - ffStrbufAppendS(&result->error, "Not supported on this platform"); + FF_UNUSED(result); + return "Not supported on this platform"; } diff --git a/src/detection/font/font_windows.c b/src/detection/font/font_windows.c index 6a31b07eb4..46a63f5205 100644 --- a/src/detection/font/font_windows.c +++ b/src/detection/font/font_windows.c @@ -23,13 +23,11 @@ static void generateString(FFFontResult* font) ffStrbufAppendC(&font->display, ']'); } -void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) +const char* ffDetectFontImpl(FFFontResult* result) { - FF_UNUSED(instance); - NONCLIENTMETRICSW info = { .cbSize = sizeof(info) }; if(!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0)) - ffStrbufAppendS(&result->error, "SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed"); + return "SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed"; LOGFONTW* fonts[4] = { &info.lfCaptionFont, &info.lfMenuFont, &info.lfMessageFont, &info.lfStatusFont }; @@ -41,4 +39,6 @@ void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) } generateString(result); + + return NULL; } diff --git a/src/detection/gamepad/gamepad.h b/src/detection/gamepad/gamepad.h index 1def1b430b..59519bb164 100644 --- a/src/detection/gamepad/gamepad.h +++ b/src/detection/gamepad/gamepad.h @@ -11,6 +11,6 @@ typedef struct FFGamepadDevice FFstrbuf name; } FFGamepadDevice; -const char* ffDetectGamepad(const FFinstance* instance, FFlist* devices /* List of FFGamepadDevice */); +const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */); #endif diff --git a/src/detection/gamepad/gamepad_apple.c b/src/detection/gamepad/gamepad_apple.c index 154f1c5870..b1a8436cae 100644 --- a/src/detection/gamepad/gamepad_apple.c +++ b/src/detection/gamepad/gamepad_apple.c @@ -15,7 +15,7 @@ static void enumSet(const void* value, void *context) ffCfStrGetString(product, &device->name); } -const char* ffDetectGamepad(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* devices /* List of FFGamepadDevice */) +const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */) { IOHIDManagerRef FF_CFTYPE_AUTO_RELEASE manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (IOHIDManagerOpen(manager, kIOHIDOptionsTypeNone) != kIOReturnSuccess) diff --git a/src/detection/gamepad/gamepad_bsd.c b/src/detection/gamepad/gamepad_bsd.c new file mode 100644 index 0000000000..9ede2280b0 --- /dev/null +++ b/src/detection/gamepad/gamepad_bsd.c @@ -0,0 +1,55 @@ +#include "gamepad.h" +#include "common/io/io.h" + +#include +#include +#include +#include + +#define MAX_UHID_JOYS 64 + +const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */) +{ + char path[16]; + for (int i = 0; i < MAX_UHID_JOYS; i++) + { + snprintf(path, sizeof(path), "/dev/uhid%d", i); + FF_AUTO_CLOSE_FD int fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd < 0) continue; + + report_desc_t repDesc = hid_get_report_desc(fd); + if (!repDesc) continue; + + int repId = hid_get_report_id(fd); + + struct hid_data* hData = hid_start_parse(repDesc, 0, repId); + if (hData) + { + struct hid_item hItem; + while (hid_get_item(hData, &hItem) > 0) + { + if (HID_PAGE(hItem.usage) != 1) continue; + switch (HID_USAGE(hItem.usage)) + { + case 1: // FreeBSD returns 1 for my Pro Controller for some reason + case 5: + break; + default: + continue; + } + + struct usb_device_info di; + if (ioctl(fd, USB_GET_DEVICEINFO, &di) != -1) + { + FFGamepadDevice* device = (FFGamepadDevice*) ffListAdd(devices); + ffStrbufInitS(&device->identifier, di.udi_serial); + ffStrbufInitF(&device->name, "%s %s", di.udi_vendor, di.udi_product); + } + } + } + + hid_dispose_report_desc(repDesc); + } + + return NULL; +} diff --git a/src/detection/gamepad/gamepad_linux.c b/src/detection/gamepad/gamepad_linux.c index ce61a57113..c68a31d74c 100644 --- a/src/detection/gamepad/gamepad_linux.c +++ b/src/detection/gamepad/gamepad_linux.c @@ -1,23 +1,23 @@ #include "gamepad.h" #include "common/io/io.h" +#include "util/stringUtils.h" #include #include -const char* ffDetectGamepad(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* devices /* List of FFGamepadDevice */) +const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */) { DIR* dirp = opendir("/sys/class/input/"); if(dirp == NULL) return "opendir(\"/sys/class/input/\") == NULL"; - FF_STRBUF_AUTO_DESTROY path; - ffStrbufInitS(&path, "/sys/class/input/"); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/sys/class/input/"); uint32_t baseLen = path.length; struct dirent* entry; while((entry = readdir(dirp)) != NULL) { - if(strncmp(entry->d_name, "js", 2) != 0) + if(!ffStrStartsWith(entry->d_name, "js")) continue; if(!isdigit(entry->d_name[2])) continue; diff --git a/src/detection/gamepad/gamepad_nosupport.c b/src/detection/gamepad/gamepad_nosupport.c index d921d35523..7c323142a0 100644 --- a/src/detection/gamepad/gamepad_nosupport.c +++ b/src/detection/gamepad/gamepad_nosupport.c @@ -1,6 +1,6 @@ #include "gamepad.h" -const char* ffDetectGamepad(FF_MAYBE_UNUSED const FFinstance* instance, FF_MAYBE_UNUSED FFlist* devices /* List of FFGamepadDevice */) +const char* ffDetectGamepad(FF_MAYBE_UNUSED FFlist* devices /* List of FFGamepadDevice */) { return "Not supported on this platform"; } diff --git a/src/detection/gamepad/gamepad_windows.c b/src/detection/gamepad/gamepad_windows.c index 216bde8e8a..e115782aa9 100644 --- a/src/detection/gamepad/gamepad_windows.c +++ b/src/detection/gamepad/gamepad_windows.c @@ -87,7 +87,7 @@ static const char* detectKnownGamepad(uint32_t vendorId, uint32_t productId) } } -const char* ffDetectGamepad(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* devices /* List of FFGamepadDevice */) +const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */) { UINT nDevices = 0; if (GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST))) diff --git a/src/detection/gpu/gpu.c b/src/detection/gpu/gpu.c index b50560dfe7..9300b24845 100644 --- a/src/detection/gpu/gpu.c +++ b/src/detection/gpu/gpu.c @@ -2,8 +2,6 @@ #include "detection/internal.h" #include "detection/vulkan/vulkan.h" -const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance); - const char* FF_GPU_VENDOR_NAME_APPLE = "Apple"; const char* FF_GPU_VENDOR_NAME_AMD = "AMD"; const char* FF_GPU_VENDOR_NAME_INTEL = "Intel"; @@ -32,14 +30,17 @@ const char* ffGetGPUVendorString(unsigned vendorId) return NULL; } -const FFlist* ffDetectGPU(const FFinstance* instance) +const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result) { - FF_DETECTION_INTERNAL_GUARD(FFlist, - ffListInit(&result, sizeof(FFGPUResult)); - if(instance->config.gpuForceVulkan || ffDetectGPUImpl(&result, instance) != NULL) - { - const FFVulkanResult* vulkan = ffDetectVulkan(instance); - result = vulkan->gpus; - } - ); + if (!options->forceVulkan) + { + const char* error = ffDetectGPUImpl(options, result); + if (!error) return NULL; + } + FFVulkanResult* vulkan = ffDetectVulkan(); + if (vulkan->error) return "GPU detection failed"; + ffListDestroy(result); + ffListInitMove(result, &vulkan->gpus); + + return NULL; } diff --git a/src/detection/gpu/gpu.h b/src/detection/gpu/gpu.h index 1d34958bf4..c0f5dfaa85 100644 --- a/src/detection/gpu/gpu.h +++ b/src/detection/gpu/gpu.h @@ -14,13 +14,6 @@ extern const char* FF_GPU_VENDOR_NAME_AMD; extern const char* FF_GPU_VENDOR_NAME_INTEL; extern const char* FF_GPU_VENDOR_NAME_NVIDIA; -typedef enum FFGpuType -{ - FF_GPU_TYPE_UNKNOWN, - FF_GPU_TYPE_INTEGRATED, - FF_GPU_TYPE_DISCRETE, -} FFGpuType; - typedef struct FFGPUMemory { uint64_t total; @@ -29,7 +22,7 @@ typedef struct FFGPUMemory typedef struct FFGPUResult { - FFGpuType type; + FFGPUType type; FFstrbuf vendor; FFstrbuf name; FFstrbuf driver; @@ -40,7 +33,8 @@ typedef struct FFGPUResult uint32_t vulkanDeviceId; // Only used for vulkan } FFGPUResult; -const FFlist* ffDetectGPU(const FFinstance* instance); +const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result); +const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus); const char* ffGetGPUVendorString(unsigned vendorId); diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c index b37f2f457e..6cb786d6a3 100644 --- a/src/detection/gpu/gpu_apple.c +++ b/src/detection/gpu/gpu_apple.c @@ -8,40 +8,28 @@ static double detectGpuTemp(const FFstrbuf* gpuName) { - FF_LIST_AUTO_DESTROY temps; - ffListInit(&temps, sizeof(FFTempValue)); + double result = 0; + const char* error; if(ffStrbufStartsWithS(gpuName, "Apple M1")) - ffDetectCoreTemps(FF_TEMP_GPU_M1X, &temps); + error = ffDetectCoreTemps(FF_TEMP_GPU_M1X, &result); else if(ffStrbufStartsWithS(gpuName, "Apple M2")) - ffDetectCoreTemps(FF_TEMP_GPU_M2X, &temps); + error = ffDetectCoreTemps(FF_TEMP_GPU_M2X, &result); else if(ffStrbufStartsWithS(gpuName, "Intel")) - ffDetectCoreTemps(FF_TEMP_GPU_INTEL, &temps); + error = ffDetectCoreTemps(FF_TEMP_GPU_INTEL, &result); else if(ffStrbufStartsWithS(gpuName, "Radeon") || ffStrbufStartsWithS(gpuName, "AMD")) - ffDetectCoreTemps(FF_TEMP_GPU_AMD, &temps); + error = ffDetectCoreTemps(FF_TEMP_GPU_AMD, &result); else - ffDetectCoreTemps(FF_TEMP_GPU_UNKNOWN, &temps); + error = ffDetectCoreTemps(FF_TEMP_GPU_UNKNOWN, &result); - if(temps.length == 0) + if(error) return FF_GPU_TEMP_UNSET; - double result = 0; - for(uint32_t i = 0; i < temps.length; ++i) - { - FFTempValue* tempValue = (FFTempValue*)ffListGet(&temps, i); - result += tempValue->value; - //TODO: do we really need this? - ffStrbufDestroy(&tempValue->name); - ffStrbufDestroy(&tempValue->deviceClass); - } - result /= temps.length; return result; } -const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) +const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus) { - FF_UNUSED(instance); - CFMutableDictionaryRef matchDict = IOServiceMatching(kIOAcceleratorClassName); io_iterator_t iterator; if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess) @@ -102,10 +90,7 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) gpu->type = FF_GPU_TYPE_DISCRETE; } - if(instance->config.gpuTemp) - gpu->temperature = detectGpuTemp(&gpu->name); - else - gpu->temperature = FF_GPU_TEMP_UNSET; + gpu->temperature = options->temp ? detectGpuTemp(&gpu->name) : FF_GPU_TEMP_UNSET; CFRelease(properties); IOObjectRelease(registryEntry); diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index 6845a939d2..749072f467 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -12,6 +12,14 @@ #include #include +// Fix building on Ubuntu 20.04 +#ifndef PCI_IORESOURCE_MEM + #define PCI_IORESOURCE_MEM 0x00000200 +#endif +#ifndef PCI_IORESOURCE_PREFETCH + #define PCI_IORESOURCE_PREFETCH 0x00002000 +#endif + typedef struct PCIData { struct pci_access* access; @@ -44,7 +52,7 @@ static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA); } -static void drmDetectDeviceName(const FFinstance* instance, FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) +static void drmDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) { u8 revId = 0; bool revIdSet = false; @@ -64,27 +72,22 @@ static void drmDetectDeviceName(const FFinstance* instance, FFGPUResult* gpu, PC #endif } - FFstrbuf query; - ffStrbufInit(&query); - ffStrbufAppendF(&query, "%X, %X,", device->device_id, revId); - - ffParsePropFileData(instance, "libdrm/amdgpu.ids", query.chars, &gpu->name); - - ffStrbufDestroy(&query); + FF_STRBUF_AUTO_DESTROY query = ffStrbufCreateF("%X, %X,", device->device_id, revId); + ffParsePropFileData("libdrm/amdgpu.ids", query.chars, &gpu->name); const char* removeStrings[] = { "AMD ", "ATI ", " (TM)", "(TM)", " Graphics Adapter", " Graphics", " Series", " Edition" }; - ffStrbufRemoveStringsA(&gpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings); + ffStrbufRemoveStrings(&gpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings); } -static void pciDetectDeviceName(const FFinstance* instance, FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) +static void pciDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) { - if(ffStrbufCompS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD) == 0) + if(ffStrbufEqualS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD)) { - drmDetectDeviceName(instance, gpu, pci, device); + drmDetectDeviceName(gpu, pci, device); if(gpu->name.length > 0) return; } @@ -116,10 +119,7 @@ static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* if(!ffStrSet(base)) return; - FFstrbuf path; - ffStrbufInitA(&path, 64); - ffStrbufAppendF(&path, "%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func); - + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateF("%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func); ffStrbufEnsureFree(&gpu->driver, 1023); ssize_t resultLength = readlink(path.chars, gpu->driver.chars, gpu->driver.allocated - 1); //-1 for null terminator if(resultLength > 0) @@ -128,11 +128,9 @@ static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* gpu->driver.chars[resultLength] = '\0'; ffStrbufSubstrAfterLastC(&gpu->driver, '/'); } - - ffStrbufDestroy(&path); } -static void pciDetectTemperatur(FFGPUResult* gpu, struct pci_dev* device) +FF_MAYBE_UNUSED static void pciDetectTemp(FFGPUResult* gpu, struct pci_dev* device) { const FFTempsResult* tempsResult = ffDetectTemps(); @@ -149,39 +147,56 @@ static void pciDetectTemperatur(FFGPUResult* gpu, struct pci_dev* device) } } -static void detectType(FFGPUResult* gpu, const PCIData* pci, struct pci_dev* device) +FF_MAYBE_UNUSED static bool pciDetectMemory(FFGPUResult* gpu, const PCIData* pci, struct pci_dev* device) { - //There is no straightforward way to detect the type of a GPU. - //The approach taken here is to look at the memory sizes of the device. - //Since integrated GPUs usually use the system ram, they don't have expansive ROMs - //and their memory sizes are usually smaller than 1GB. + gpu->dedicated.used = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET; - if(!(pci->ffpci_fill_info(device, PCI_FILL_SIZES) & PCI_FILL_SIZES)) + uint32_t flags = (uint32_t) pci->ffpci_fill_info(device, PCI_FILL_IO_FLAGS | PCI_FILL_SIZES); + if (!(flags & PCI_FILL_IO_FLAGS) || !(flags & PCI_FILL_SIZES)) { - gpu->type = FF_GPU_TYPE_UNKNOWN; - return; + gpu->dedicated.total = gpu->shared.total = FF_GPU_VMEM_SIZE_UNSET; + return false; } - if(device->rom_size > 0) + gpu->dedicated.total = gpu->shared.total = 0; + for (uint32_t i = 0; i < sizeof(device->size) / sizeof(device->size[0]); i++) { - gpu->type = FF_GPU_TYPE_DISCRETE; - return; + if (!(device->flags[i] & PCI_IORESOURCE_MEM)) continue; + + // Assume dedicated memories are prefetchable + // At least it's true for my laptop + if (device->flags[i] & PCI_IORESOURCE_PREFETCH) + gpu->dedicated.total += device->size[i]; + else + gpu->shared.total += device->size[i]; } - uint32_t numSizes = sizeof(device->size) / sizeof(device->size[0]); - for(uint32_t i = 0; i < numSizes; i++) + if (gpu->dedicated.total == 0 && gpu->shared.total == 0) { - if(device->size[i] >= 1024 * 1024 * 1024) //1GB - { - gpu->type = FF_GPU_TYPE_DISCRETE; - return; - } + gpu->dedicated.total = gpu->shared.total = FF_GPU_VMEM_SIZE_UNSET; + return false; } - gpu->type = FF_GPU_TYPE_INTEGRATED; + return true; } -static void pciHandleDevice(const FFinstance* instance, FFlist* results, PCIData* pci, struct pci_dev* device) +FF_MAYBE_UNUSED static void pciDetectType(FFGPUResult* gpu) +{ + //There is no straightforward way to detect the type of a GPU. + //The approach taken here is to look at the memory sizes of the device. + //Since integrated GPUs usually use the system ram, they don't have expansive ROMs + //and their memory sizes are usually smaller than 1GB. + if (gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET) + { + gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 // 1GB + ? FF_GPU_TYPE_DISCRETE + : FF_GPU_TYPE_INTEGRATED; + } + else + gpu->type = FF_GPU_TYPE_UNKNOWN; +} + +static void pciHandleDevice(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* results, PCIData* pci, struct pci_dev* device) { pci->ffpci_fill_info(device, PCI_FILL_CLASS); @@ -200,24 +215,31 @@ static void pciHandleDevice(const FFinstance* instance, FFlist* results, PCIData FFGPUResult* gpu = ffListAdd(results); - gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET; - ffStrbufInit(&gpu->vendor); pciDetectVendorName(gpu, pci, device); ffStrbufInit(&gpu->name); - pciDetectDeviceName(instance, gpu, pci, device); + pciDetectDeviceName(gpu, pci, device); ffStrbufInit(&gpu->driver); pciDetectDriverName(gpu, pci, device); - detectType(gpu, pci, device); + #if FF_USE_PCI_MEMORY + // Libpci reports at least 2 false results (#495, #497) + pciDetectMemory(gpu, pci, device); + pciDetectType(gpu); + #else + gpu->dedicated.used = gpu->shared.used = gpu->dedicated.total = gpu->shared.total = FF_GPU_VMEM_SIZE_UNSET; + gpu->type = FF_GPU_TYPE_UNKNOWN; + #endif gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; - gpu->temperature = FF_GPU_TEMP_UNSET; - if(instance->config.gpuTemp) - pciDetectTemperatur(gpu, device); + + #ifdef __linux__ + if(options->temp) + pciDetectTemp(gpu, device); + #endif } jmp_buf pciInitJmpBuf; @@ -244,11 +266,11 @@ static void handlePciWarning(FF_MAYBE_UNUSED char *msg, ...) // noop } -static const char* pciDetectGPUs(const FFinstance* instance, FFlist* gpus) +static const char* pciDetectGPUs(const FFGPUOptions* options, FFlist* gpus) { PCIData pci; - FF_LIBRARY_LOAD(libpci, &instance->config.libPCI, "dlopen libpci.so failed", "libpci" FF_LIBRARY_EXTENSION, 4); + FF_LIBRARY_LOAD(libpci, &instance.config.libPCI, "dlopen libpci.so failed", "libpci" FF_LIBRARY_EXTENSION, 4); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_alloc); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_init); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_scan_bus); @@ -277,7 +299,7 @@ static const char* pciDetectGPUs(const FFinstance* instance, FFlist* gpus) struct pci_dev* device = pci.access->devices; while(device != NULL) { - pciHandleDevice(instance, gpus, &pci, device); + pciHandleDevice(options, gpus, &pci, device); device = device->next; } @@ -287,12 +309,12 @@ static const char* pciDetectGPUs(const FFinstance* instance, FFlist* gpus) #endif -const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) +const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus) { #ifdef FF_HAVE_LIBPCI - return pciDetectGPUs(instance, gpus); + return pciDetectGPUs(options, gpus); #else - FF_UNUSED(gpus, instance); + FF_UNUSED(options, gpus); return "fastfetch is built without libpci support"; #endif } diff --git a/src/detection/gpu/gpu_nosupport.c b/src/detection/gpu/gpu_nosupport.c index ef2d54abd9..28daf5fa65 100644 --- a/src/detection/gpu/gpu_nosupport.c +++ b/src/detection/gpu/gpu_nosupport.c @@ -1,7 +1,7 @@ #include "gpu.h" -const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) +const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus) { - FF_UNUSED(gpus, instance); + FF_UNUSED(options, gpus); return "Not supported on this platform"; } diff --git a/src/detection/gpu/gpu_windows.c b/src/detection/gpu/gpu_windows.c index d83da86f79..67211b76cd 100644 --- a/src/detection/gpu/gpu_windows.c +++ b/src/detection/gpu/gpu_windows.c @@ -9,7 +9,7 @@ static int isGpuNameEqual(const FFGPUResult* gpu, const FFstrbuf* name) return ffStrbufEqual(&gpu->name, name); } -const char* ffDetectGPUImpl(FFlist* gpus, FF_MAYBE_UNUSED const FFinstance* instance) +const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus) { DISPLAY_DEVICEW displayDevice = { .cb = sizeof(displayDevice) }; wchar_t regKey[MAX_PATH] = L"SYSTEM\\CurrentControlSet\\Control\\Video\\{"; @@ -29,7 +29,7 @@ const char* ffDetectGPUImpl(FFlist* gpus, FF_MAYBE_UNUSED const FFinstance* inst { // DeviceKey can be empty. See #484 FF_STRBUF_AUTO_DESTROY gpuName = ffStrbufCreateWS(displayDevice.DeviceString); - if (ffListFirstIndexComp(gpus, &gpuName, (void*) isGpuNameEqual) != gpus->length) continue; + if (ffListContains(gpus, &gpuName, (void*) isGpuNameEqual)) continue; } FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus); diff --git a/src/detection/gtk_qt/gtk.c b/src/detection/gtk_qt/gtk.c index ca57780338..8c7debe016 100644 --- a/src/detection/gtk_qt/gtk.c +++ b/src/detection/gtk_qt/gtk.c @@ -34,7 +34,7 @@ static inline void applyGTKSettings(FFGTKResult* result, const char* themeName, ffStrbufAppendS(&result->wallpaper, wallpaper); } -static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* result) +static void detectGTKFromSettings(FFGTKResult* result) { static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; @@ -58,48 +58,49 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul init = true; - const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance); + const FFDisplayServerResult* wmde = ffConnectDisplayServer(); if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_XFCE4) == 0) { - themeName = ffSettingsGetXFConf(instance, "xsettings", "/Net/ThemeName", FF_VARIANT_TYPE_STRING).strValue; - iconsName = ffSettingsGetXFConf(instance, "xsettings", "/Net/IconThemeName", FF_VARIANT_TYPE_STRING).strValue; - fontName = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/FontName", FF_VARIANT_TYPE_STRING).strValue; - cursorTheme = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeName", FF_VARIANT_TYPE_STRING).strValue; - cursorSize = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeSize", FF_VARIANT_TYPE_INT).intValue; - wallpaper = ffSettingsGetXFConf(instance, "xfce4-desktop", "/backdrop/screen0/monitor0/workspace0/last-image", FF_VARIANT_TYPE_STRING).strValue; + themeName = ffSettingsGetXFConf("xsettings", "/Net/ThemeName", FF_VARIANT_TYPE_STRING).strValue; + iconsName = ffSettingsGetXFConf("xsettings", "/Net/IconThemeName", FF_VARIANT_TYPE_STRING).strValue; + fontName = ffSettingsGetXFConf("xsettings", "/Gtk/FontName", FF_VARIANT_TYPE_STRING).strValue; + cursorTheme = ffSettingsGetXFConf("xsettings", "/Gtk/CursorThemeName", FF_VARIANT_TYPE_STRING).strValue; + cursorSize = ffSettingsGetXFConf("xsettings", "/Gtk/CursorThemeSize", FF_VARIANT_TYPE_INT).intValue; + wallpaper = ffSettingsGetXFConf("xfce4-desktop", "/backdrop/screen0/monitor0/workspace0/last-image", FF_VARIANT_TYPE_STRING).strValue; if (!wallpaper) // FIXME: find a way to enumerate possible properties - wallpaper = ffSettingsGetXFConf(instance, "xfce4-desktop", "/backdrop/screen0/monitoreDP-1/workspace0/last-image", FF_VARIANT_TYPE_STRING).strValue; + wallpaper = ffSettingsGetXFConf("xfce4-desktop", "/backdrop/screen0/monitoreDP-1/workspace0/last-image", FF_VARIANT_TYPE_STRING).strValue; } else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_CINNAMON) == 0) { - themeName = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/gtk-theme", "org.cinnamon.desktop.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue; - iconsName = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/icon-theme", "org.cinnamon.desktop.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue; - fontName = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/font-name", "org.cinnamon.desktop.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue; - cursorTheme = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/cursor-theme", "org.cinnamon.desktop.interface", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue; - cursorSize = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/cursor-size", "org.cinnamon.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue; - wallpaper = ffSettingsGet(instance, "/org/cinnamon/desktop/background/picture-uri", "org.cinnamon.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue; + themeName = ffSettingsGet("/org/cinnamon/desktop/interface/gtk-theme", "org.cinnamon.desktop.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue; + iconsName = ffSettingsGet("/org/cinnamon/desktop/interface/icon-theme", "org.cinnamon.desktop.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue; + fontName = ffSettingsGet("/org/cinnamon/desktop/interface/font-name", "org.cinnamon.desktop.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue; + cursorTheme = ffSettingsGet("/org/cinnamon/desktop/interface/cursor-theme", "org.cinnamon.desktop.interface", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue; + cursorSize = ffSettingsGet("/org/cinnamon/desktop/interface/cursor-size", "org.cinnamon.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue; + wallpaper = ffSettingsGet("/org/cinnamon/desktop/background/picture-uri", "org.cinnamon.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue; } else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_MATE) == 0) { - themeName = ffSettingsGet(instance, "/org/mate/interface/gtk-theme", "org.mate.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue; - iconsName = ffSettingsGet(instance, "/org/mate/interface/icon-theme", "org.mate.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue; - fontName = ffSettingsGet(instance, "/org/mate/interface/font-name", "org.mate.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue; - cursorTheme = ffSettingsGet(instance, "/org/mate/peripherals-mouse/cursor-theme", "org.mate.peripherals-mouse", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue; - cursorSize = ffSettingsGet(instance, "/org/mate/peripherals-mouse/cursor-size", "org.mate.peripherals-mouse", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue; - wallpaper = ffSettingsGet(instance, "/org/mate/desktop/background", "org.mate.background", NULL, "picture-filename", FF_VARIANT_TYPE_STRING).strValue; + themeName = ffSettingsGet("/org/mate/interface/gtk-theme", "org.mate.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue; + iconsName = ffSettingsGet("/org/mate/interface/icon-theme", "org.mate.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue; + fontName = ffSettingsGet("/org/mate/interface/font-name", "org.mate.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue; + cursorTheme = ffSettingsGet("/org/mate/peripherals-mouse/cursor-theme", "org.mate.peripherals-mouse", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue; + cursorSize = ffSettingsGet("/org/mate/peripherals-mouse/cursor-size", "org.mate.peripherals-mouse", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue; + wallpaper = ffSettingsGet("/org/mate/desktop/background", "org.mate.background", NULL, "picture-filename", FF_VARIANT_TYPE_STRING).strValue; } else if( ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_GNOME) == 0 || + ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_GNOME_CLASSIC) == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_UNITY) == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_BUDGIE) == 0 ) { - themeName = ffSettingsGet(instance, "/org/gnome/desktop/interface/gtk-theme", "org.gnome.desktop.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue; - iconsName = ffSettingsGet(instance, "/org/gnome/desktop/interface/icon-theme", "org.gnome.desktop.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue; - fontName = ffSettingsGet(instance, "/org/gnome/desktop/interface/font-name", "org.gnome.desktop.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue; - cursorTheme = ffSettingsGet(instance, "/org/gnome/desktop/interface/cursor-theme", "org.gnome.desktop.interface", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue; - cursorSize = ffSettingsGet(instance, "/org/gnome/desktop/interface/cursor-size", "org.gnome.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue; - wallpaper = ffSettingsGet(instance, "/org/gnome/desktop/background/picture-uri", "org.gnome.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue; + themeName = ffSettingsGet("/org/gnome/desktop/interface/gtk-theme", "org.gnome.desktop.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue; + iconsName = ffSettingsGet("/org/gnome/desktop/interface/icon-theme", "org.gnome.desktop.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue; + fontName = ffSettingsGet("/org/gnome/desktop/interface/font-name", "org.gnome.desktop.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue; + cursorTheme = ffSettingsGet("/org/gnome/desktop/interface/cursor-theme", "org.gnome.desktop.interface", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue; + cursorSize = ffSettingsGet("/org/gnome/desktop/interface/cursor-size", "org.gnome.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue; + wallpaper = ffSettingsGet("/org/gnome/desktop/background/picture-uri", "org.gnome.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue; } ffThreadMutexUnlock(&mutex); @@ -156,27 +157,24 @@ static void detectGTKFromConfigDir(FFstrbuf* configDir, const char* version, FFG ffStrbufSubstrBefore(configDir, configDirLength); } -static void detectGTK(const FFinstance* instance, const char* version, FFGTKResult* result) +static void detectGTK(const char* version, FFGTKResult* result) { //Mate, Cinnamon, Gnome, Unity, Budgie use dconf to save theme config //On other DEs, this will do nothing - detectGTKFromSettings(instance, result); + detectGTKFromSettings(result); if(allPropertiesSet(result)) return; //We need to do this because we use multiple threads on configDirs - FFstrbuf baseDir; - ffStrbufInitA(&baseDir, 64); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64); - FF_LIST_FOR_EACH(FFstrbuf, configDir, instance->state.platform.configDirs) + FF_LIST_FOR_EACH(FFstrbuf, configDir, instance.state.platform.configDirs) { ffStrbufSet(&baseDir, configDir); detectGTKFromConfigDir(&baseDir, version, result); if(allPropertiesSet(result)) break; } - - ffStrbufDestroy(&baseDir); } #define FF_DETECT_GTK_IMPL(version) \ @@ -195,21 +193,21 @@ static void detectGTK(const FFinstance* instance, const char* version, FFGTKResu ffStrbufInit(&result.cursor); \ ffStrbufInit(&result.cursorSize); \ ffStrbufInit(&result.wallpaper); \ - detectGTK(instance, #version, &result); \ + detectGTK(#version, &result); \ ffThreadMutexUnlock(&mutex); \ return &result; -const FFGTKResult* ffDetectGTK2(const FFinstance* instance) +const FFGTKResult* ffDetectGTK2(void) { FF_DETECT_GTK_IMPL(2) } -const FFGTKResult* ffDetectGTK3(const FFinstance* instance) +const FFGTKResult* ffDetectGTK3(void) { FF_DETECT_GTK_IMPL(3) } -const FFGTKResult* ffDetectGTK4(const FFinstance* instance) +const FFGTKResult* ffDetectGTK4(void) { FF_DETECT_GTK_IMPL(4) } diff --git a/src/detection/gtk_qt/gtk_qt.h b/src/detection/gtk_qt/gtk_qt.h index 8a115e5b07..ef329f03af 100644 --- a/src/detection/gtk_qt/gtk_qt.h +++ b/src/detection/gtk_qt/gtk_qt.h @@ -24,9 +24,9 @@ typedef struct FFQtResult FFstrbuf wallpaper; } FFQtResult; -const FFGTKResult* ffDetectGTK2(const FFinstance* instance); -const FFGTKResult* ffDetectGTK4(const FFinstance* instance); -const FFGTKResult* ffDetectGTK3(const FFinstance* instance); -const FFQtResult* ffDetectQt(const FFinstance* instance); +const FFGTKResult* ffDetectGTK2(void); +const FFGTKResult* ffDetectGTK4(void); +const FFGTKResult* ffDetectGTK3(void); +const FFQtResult* ffDetectQt(void); #endif diff --git a/src/detection/gtk_qt/qt.c b/src/detection/gtk_qt/qt.c index 0cd575adb3..71b0536c7a 100644 --- a/src/detection/gtk_qt/qt.c +++ b/src/detection/gtk_qt/qt.c @@ -81,15 +81,14 @@ static bool detectPlasmaFromFile(const char* filename, FFQtResult* result) return true; } -static void detectPlasma(const FFinstance* instance, FFQtResult* result) +static void detectPlasma(FFQtResult* result) { bool foundAFile = false; //We need to do this because we use multiple threads on configDirs - FFstrbuf baseDir; - ffStrbufInitA(&baseDir, 64); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64); - FF_LIST_FOR_EACH(FFstrbuf, configDir, instance->state.platform.configDirs) + FF_LIST_FOR_EACH(FFstrbuf, configDir, instance.state.platform.configDirs) { ffStrbufSet(&baseDir, configDir); ffStrbufAppendS(&baseDir, "kdeglobals"); @@ -103,13 +102,9 @@ static void detectPlasma(const FFinstance* instance, FFQtResult* result) ffParsePropFile(baseDir.chars, "Image=", &result->wallpaper); if(allValuesSet(result)) - { - ffStrbufDestroy(&baseDir); return; - } } - ffStrbufDestroy(&baseDir); if(!foundAFile) return; @@ -128,18 +123,18 @@ static void detectPlasma(const FFinstance* instance, FFQtResult* result) ffStrbufAppendS(&result->font, "Noto Sans, 10"); } -static void detectLXQt(const FFinstance* instance, FFQtResult* result) +static void detectLXQt(FFQtResult* result) { - ffParsePropFileConfigValues(instance, "lxqt/lxqt.conf", 3, (FFpropquery[]) { + ffParsePropFileConfigValues("lxqt/lxqt.conf", 3, (FFpropquery[]) { {"style = ", &result->widgetStyle}, {"icon_theme = ", &result->icons}, {"font = ", &result->font} }); - ffParsePropFileConfig(instance, "pcmanfm-qt/lxqt/settings.conf", "Wallpaper=", &result->wallpaper); + ffParsePropFileConfig("pcmanfm-qt/lxqt/settings.conf", "Wallpaper=", &result->wallpaper); } -const FFQtResult* ffDetectQt(const FFinstance* instance) +const FFQtResult* ffDetectQt(void) { static FFQtResult result; @@ -159,12 +154,12 @@ const FFQtResult* ffDetectQt(const FFinstance* instance) ffStrbufInit(&result.font); ffStrbufInit(&result.wallpaper); - const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance); + const FFDisplayServerResult* wmde = ffConnectDisplayServer(); if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA) == 0) - detectPlasma(instance, &result); + detectPlasma(&result); else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT) == 0) - detectLXQt(instance, &result); + detectLXQt(&result); ffThreadMutexUnlock(&mutex); return &result; diff --git a/src/detection/host/host.c b/src/detection/host/host.c deleted file mode 100644 index ea8274dbee..0000000000 --- a/src/detection/host/host.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "host.h" -#include "detection/internal.h" - -void ffDetectHostImpl(FFHostResult* host); - -const FFHostResult* ffDetectHost() -{ - FF_DETECTION_INTERNAL_GUARD(FFHostResult, - ffDetectHostImpl(&result) - ); -} diff --git a/src/detection/host/host.h b/src/detection/host/host.h index c8b47b6b2a..a0fd66511e 100644 --- a/src/detection/host/host.h +++ b/src/detection/host/host.h @@ -12,9 +12,8 @@ typedef struct FFHostResult FFstrbuf productVersion; FFstrbuf productSku; FFstrbuf sysVendor; - FFstrbuf error; } FFHostResult; -const FFHostResult* ffDetectHost(); +const char* ffDetectHost(FFHostResult* result); #endif diff --git a/src/detection/host/host_android.c b/src/detection/host/host_android.c index edeb9cb478..4b7c095a98 100644 --- a/src/detection/host/host_android.c +++ b/src/detection/host/host_android.c @@ -2,36 +2,36 @@ #include "common/settings.h" #include -void ffDetectHostImpl(FFHostResult* host) +const char* ffDetectHost(FFHostResult* host) { - ffStrbufInit(&host->error); - - //Family - - ffStrbufInit(&host->productFamily); + // http://newandroidbook.com/ddb/ ffSettingsGetAndroidProperty("ro.product.device", &host->productFamily); - //Name - - ffStrbufInit(&host->productName); - - ffSettingsGetAndroidProperty("ro.product.brand", &host->productName); - if(host->productName.length > 0){ - host->productName.chars[0] = (char) toupper(host->productName.chars[0]); - ffStrbufAppendC(&host->productName, ' '); + ffSettingsGetAndroidProperty("ro.product.marketname", &host->productName) + || ffSettingsGetAndroidProperty("ro.vendor.product.display", &host->productName) + || ffSettingsGetAndroidProperty("ro.config.devicename", &host->productName) + || ffSettingsGetAndroidProperty("ro.config.marketing_name", &host->productName) + || ffSettingsGetAndroidProperty("ro.product.vendor.model", &host->productName) + || ffSettingsGetAndroidProperty("ro.product.oppo_model", &host->productName) + || ffSettingsGetAndroidProperty("ro.oppo.market.name", &host->productName) + || ffSettingsGetAndroidProperty("ro.product.brand", &host->productName); + + if (ffSettingsGetAndroidProperty("ro.product.model", &host->productVersion)) + { + if (ffStrbufStartsWithIgnCase(&host->productVersion, &host->productName)) + { + ffStrbufSubstrAfter(&host->productVersion, host->productName.length); + ffStrbufTrimLeft(&host->productVersion, ' '); + } } - ffSettingsGetAndroidProperty("ro.product.model", &host->productName); - - ffStrbufTrimRight(&host->productName, ' '); - - //Sys vendor - - ffStrbufInit(&host->sysVendor); ffSettingsGetAndroidProperty("ro.product.manufacturer", &host->sysVendor); - //Not implemented + if(host->sysVendor.length && !ffStrbufStartsWithIgnCase(&host->productName, &host->sysVendor)) + { + ffStrbufPrependS(&host->productName, " "); + ffStrbufPrepend(&host->productName, &host->sysVendor); + } - ffStrbufInitA(&host->productVersion, 0); - ffStrbufInitA(&host->productSku, 0); + return NULL; } diff --git a/src/detection/host/host_apple.c b/src/detection/host/host_apple.c index 9814f57008..1c5789c70d 100644 --- a/src/detection/host/host_apple.c +++ b/src/detection/host/host_apple.c @@ -1,10 +1,6 @@ #include "host.h" #include "common/sysctl.h" - -static inline bool strEqual(const char* a, const char* b) -{ - return strcmp(a, b) == 0; -} +#include "util/stringUtils.h" static const char* getProductName(const FFstrbuf* hwModel) { @@ -18,158 +14,153 @@ static const char* getProductName(const FFstrbuf* hwModel) if(ffStrbufStartsWithS(hwModel, "MacBookPro")) { const char* version = hwModel->chars + strlen("MacBookPro"); - if(strEqual(version, "18,3") || - strEqual(version, "18,4")) return "MacBook Pro (14-inch, 2021)"; - if(strEqual(version, "18,1") || - strEqual(version, "18,2")) return "MacBook Pro (16-inch, 2021)"; - if(strEqual(version, "17,1")) return "MacBook Pro (13-inch, M1, 2020)"; - if(strEqual(version, "16,4")) return "MacBook Pro (16-inch, 2019)"; - if(strEqual(version, "16,3")) return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)"; - if(strEqual(version, "16,2")) return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)"; - if(strEqual(version, "16,1")) return "MacBook Pro (16-inch, 2019)"; - if(strEqual(version, "15,4")) return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)"; - if(strEqual(version, "15,3")) return "MacBook Pro (15-inch, 2019)"; - if(strEqual(version, "15,2")) return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)"; - if(strEqual(version, "15,1")) return "MacBook Pro (15-inch, 2018/2019)"; - if(strEqual(version, "14,3")) return "MacBook Pro (15-inch, 2017)"; - if(strEqual(version, "14,2")) return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)"; - if(strEqual(version, "14,1")) return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)"; - if(strEqual(version, "13,3")) return "MacBook Pro (15-inch, 2016)"; - if(strEqual(version, "13,2")) return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)"; - if(strEqual(version, "13,1")) return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)"; - if(strEqual(version, "12,1")) return "MacBook Pro (Retina, 13-inch, Early 2015)"; - if(strEqual(version, "11,4") || - strEqual(version, "11,5")) return "MacBook Pro (Retina, 15-inch, Mid 2015)"; - if(strEqual(version, "11,2") || - strEqual(version, "11,3")) return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)"; - if(strEqual(version, "11,1")) return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)"; - if(strEqual(version, "10,2")) return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)"; - if(strEqual(version, "10,1")) return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)"; - if(strEqual(version, "9,2")) return "MacBook Pro (13-inch, Mid 2012)"; - if(strEqual(version, "9,1")) return "MacBook Pro (15-inch, Mid 2012)"; - if(strEqual(version, "8,3")) return "MacBook Pro (17-inch, 2011)"; - if(strEqual(version, "8,2")) return "MacBook Pro (15-inch, 2011)"; - if(strEqual(version, "8,1")) return "MacBook Pro (13-inch, 2011)"; - if(strEqual(version, "7,1")) return "MacBook Pro (13-inch, Mid 2010)"; - if(strEqual(version, "6,2")) return "MacBook Pro (15-inch, Mid 2010)"; - if(strEqual(version, "6,1")) return "MacBook Pro (17-inch, Mid 2010)"; - if(strEqual(version, "5,5")) return "MacBook Pro (13-inch, Mid 2009)"; - if(strEqual(version, "5,3")) return "MacBook Pro (15-inch, Mid 2009)"; - if(strEqual(version, "5,2")) return "MacBook Pro (17-inch, Mid/Early 2009)"; - if(strEqual(version, "5,1")) return "MacBook Pro (15-inch, Late 2008)"; - if(strEqual(version, "4,1")) return "MacBook Pro (17/15-inch, Early 2008)"; + if(ffStrEquals(version, "18,3") || + ffStrEquals(version, "18,4")) return "MacBook Pro (14-inch, 2021)"; + if(ffStrEquals(version, "18,1") || + ffStrEquals(version, "18,2")) return "MacBook Pro (16-inch, 2021)"; + if(ffStrEquals(version, "17,1")) return "MacBook Pro (13-inch, M1, 2020)"; + if(ffStrEquals(version, "16,4")) return "MacBook Pro (16-inch, 2019)"; + if(ffStrEquals(version, "16,3")) return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)"; + if(ffStrEquals(version, "16,2")) return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)"; + if(ffStrEquals(version, "16,1")) return "MacBook Pro (16-inch, 2019)"; + if(ffStrEquals(version, "15,4")) return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)"; + if(ffStrEquals(version, "15,3")) return "MacBook Pro (15-inch, 2019)"; + if(ffStrEquals(version, "15,2")) return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)"; + if(ffStrEquals(version, "15,1")) return "MacBook Pro (15-inch, 2018/2019)"; + if(ffStrEquals(version, "14,3")) return "MacBook Pro (15-inch, 2017)"; + if(ffStrEquals(version, "14,2")) return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)"; + if(ffStrEquals(version, "14,1")) return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)"; + if(ffStrEquals(version, "13,3")) return "MacBook Pro (15-inch, 2016)"; + if(ffStrEquals(version, "13,2")) return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)"; + if(ffStrEquals(version, "13,1")) return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)"; + if(ffStrEquals(version, "12,1")) return "MacBook Pro (Retina, 13-inch, Early 2015)"; + if(ffStrEquals(version, "11,4") || + ffStrEquals(version, "11,5")) return "MacBook Pro (Retina, 15-inch, Mid 2015)"; + if(ffStrEquals(version, "11,2") || + ffStrEquals(version, "11,3")) return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)"; + if(ffStrEquals(version, "11,1")) return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)"; + if(ffStrEquals(version, "10,2")) return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)"; + if(ffStrEquals(version, "10,1")) return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)"; + if(ffStrEquals(version, "9,2")) return "MacBook Pro (13-inch, Mid 2012)"; + if(ffStrEquals(version, "9,1")) return "MacBook Pro (15-inch, Mid 2012)"; + if(ffStrEquals(version, "8,3")) return "MacBook Pro (17-inch, 2011)"; + if(ffStrEquals(version, "8,2")) return "MacBook Pro (15-inch, 2011)"; + if(ffStrEquals(version, "8,1")) return "MacBook Pro (13-inch, 2011)"; + if(ffStrEquals(version, "7,1")) return "MacBook Pro (13-inch, Mid 2010)"; + if(ffStrEquals(version, "6,2")) return "MacBook Pro (15-inch, Mid 2010)"; + if(ffStrEquals(version, "6,1")) return "MacBook Pro (17-inch, Mid 2010)"; + if(ffStrEquals(version, "5,5")) return "MacBook Pro (13-inch, Mid 2009)"; + if(ffStrEquals(version, "5,3")) return "MacBook Pro (15-inch, Mid 2009)"; + if(ffStrEquals(version, "5,2")) return "MacBook Pro (17-inch, Mid/Early 2009)"; + if(ffStrEquals(version, "5,1")) return "MacBook Pro (15-inch, Late 2008)"; + if(ffStrEquals(version, "4,1")) return "MacBook Pro (17/15-inch, Early 2008)"; } else if(ffStrbufStartsWithS(hwModel, "MacBookAir")) { const char* version = hwModel->chars + strlen("MacBookAir"); - if(strEqual(version, "10,1")) return "MacBook Air (M1, 2020)"; - if(strEqual(version, "9,1")) return "MacBook Air (Retina, 13-inch, 2020)"; - if(strEqual(version, "8,2")) return "MacBook Air (Retina, 13-inch, 2019)"; - if(strEqual(version, "8,1")) return "MacBook Air (Retina, 13-inch, 2018)"; - if(strEqual(version, "7,2")) return "MacBook Air (13-inch, Early 2015/2017)"; - if(strEqual(version, "7,1")) return "MacBook Air (11-inch, Early 2015)"; - if(strEqual(version, "6,2")) return "MacBook Air (13-inch, Mid 2013/Early 2014)"; - if(strEqual(version, "6,1")) return "MacBook Air (11-inch, Mid 2013/Early 2014)"; - if(strEqual(version, "5,2")) return "MacBook Air (13-inch, Mid 2012)"; - if(strEqual(version, "5,1")) return "MacBook Air (11-inch, Mid 2012)"; - if(strEqual(version, "4,2")) return "MacBook Air (13-inch, Mid 2011)"; - if(strEqual(version, "4,1")) return "MacBook Air (11-inch, Mid 2011)"; - if(strEqual(version, "3,2")) return "MacBook Air (13-inch, Late 2010)"; - if(strEqual(version, "3,1")) return "MacBook Air (11-inch, Late 2010)"; - if(strEqual(version, "2,1")) return "MacBook Air (Mid 2009)"; + if(ffStrEquals(version, "10,1")) return "MacBook Air (M1, 2020)"; + if(ffStrEquals(version, "9,1")) return "MacBook Air (Retina, 13-inch, 2020)"; + if(ffStrEquals(version, "8,2")) return "MacBook Air (Retina, 13-inch, 2019)"; + if(ffStrEquals(version, "8,1")) return "MacBook Air (Retina, 13-inch, 2018)"; + if(ffStrEquals(version, "7,2")) return "MacBook Air (13-inch, Early 2015/2017)"; + if(ffStrEquals(version, "7,1")) return "MacBook Air (11-inch, Early 2015)"; + if(ffStrEquals(version, "6,2")) return "MacBook Air (13-inch, Mid 2013/Early 2014)"; + if(ffStrEquals(version, "6,1")) return "MacBook Air (11-inch, Mid 2013/Early 2014)"; + if(ffStrEquals(version, "5,2")) return "MacBook Air (13-inch, Mid 2012)"; + if(ffStrEquals(version, "5,1")) return "MacBook Air (11-inch, Mid 2012)"; + if(ffStrEquals(version, "4,2")) return "MacBook Air (13-inch, Mid 2011)"; + if(ffStrEquals(version, "4,1")) return "MacBook Air (11-inch, Mid 2011)"; + if(ffStrEquals(version, "3,2")) return "MacBook Air (13-inch, Late 2010)"; + if(ffStrEquals(version, "3,1")) return "MacBook Air (11-inch, Late 2010)"; + if(ffStrEquals(version, "2,1")) return "MacBook Air (Mid 2009)"; } else if(ffStrbufStartsWithS(hwModel, "Macmini")) { const char* version = hwModel->chars + strlen("Macmini"); - if(strEqual(version, "9,1")) return "Mac mini (M1, 2020)"; - if(strEqual(version, "8,1")) return "Mac mini (2018)"; - if(strEqual(version, "7,1")) return "Mac mini (Mid 2014)"; - if(strEqual(version, "6,1") || - strEqual(version, "6,2")) return "Mac mini (Late 2012)"; - if(strEqual(version, "5,1") || - strEqual(version, "5,2")) return "Mac mini (Mid 2011)"; - if(strEqual(version, "4,1")) return "Mac mini (Mid 2010)"; - if(strEqual(version, "3,1")) return "Mac mini (Early/Late 2009)"; + if(ffStrEquals(version, "9,1")) return "Mac mini (M1, 2020)"; + if(ffStrEquals(version, "8,1")) return "Mac mini (2018)"; + if(ffStrEquals(version, "7,1")) return "Mac mini (Mid 2014)"; + if(ffStrEquals(version, "6,1") || + ffStrEquals(version, "6,2")) return "Mac mini (Late 2012)"; + if(ffStrEquals(version, "5,1") || + ffStrEquals(version, "5,2")) return "Mac mini (Mid 2011)"; + if(ffStrEquals(version, "4,1")) return "Mac mini (Mid 2010)"; + if(ffStrEquals(version, "3,1")) return "Mac mini (Early/Late 2009)"; } else if(ffStrbufStartsWithS(hwModel, "MacBook")) { const char* version = hwModel->chars + strlen("MacBook"); - if(strEqual(version, "10,1")) return "MacBook (Retina, 12-inch, 2017)"; - if(strEqual(version, "9,1")) return "MacBook (Retina, 12-inch, Early 2016)"; - if(strEqual(version, "8,1")) return "MacBook (Retina, 12-inch, Early 2015)"; - if(strEqual(version, "7,1")) return "MacBook (13-inch, Mid 2010)"; - if(strEqual(version, "6,1")) return "MacBook (13-inch, Late 2009)"; - if(strEqual(version, "5,2")) return "MacBook (13-inch, Early/Mid 2009)"; + if(ffStrEquals(version, "10,1")) return "MacBook (Retina, 12-inch, 2017)"; + if(ffStrEquals(version, "9,1")) return "MacBook (Retina, 12-inch, Early 2016)"; + if(ffStrEquals(version, "8,1")) return "MacBook (Retina, 12-inch, Early 2015)"; + if(ffStrEquals(version, "7,1")) return "MacBook (13-inch, Mid 2010)"; + if(ffStrEquals(version, "6,1")) return "MacBook (13-inch, Late 2009)"; + if(ffStrEquals(version, "5,2")) return "MacBook (13-inch, Early/Mid 2009)"; } else if(ffStrbufStartsWithS(hwModel, "MacPro")) { const char* version = hwModel->chars + strlen("MacPro"); - if(strEqual(version, "7,1")) return "Mac Pro (2019)"; - if(strEqual(version, "6,1")) return "Mac Pro (Late 2013)"; - if(strEqual(version, "5,1")) return "Mac Pro (Mid 2010 - Mid 2012)"; - if(strEqual(version, "4,1")) return "Mac Pro (Early 2009)"; + if(ffStrEquals(version, "7,1")) return "Mac Pro (2019)"; + if(ffStrEquals(version, "6,1")) return "Mac Pro (Late 2013)"; + if(ffStrEquals(version, "5,1")) return "Mac Pro (Mid 2010 - Mid 2012)"; + if(ffStrEquals(version, "4,1")) return "Mac Pro (Early 2009)"; } else if(ffStrbufStartsWithS(hwModel, "Mac")) { const char* version = hwModel->chars + strlen("Mac"); - if(strEqual(version, "14,15")) return "MacBook Air (15-inch, M2, 2023)"; - if(strEqual(version, "14,14")) return "Mac Studio (M2 Ultra, 2023, Two Thunderbolt 4 front ports)"; - if(strEqual(version, "14,13")) return "Mac Studio (M2 Max, 2023, Two USB-C front ports)"; - if(strEqual(version, "14,8")) return "Mac Pro (2023)"; - if(strEqual(version, "14,6") || - strEqual(version, "14,10")) return "MacBook Pro (16-inch, 2023)"; - if(strEqual(version, "14,5") || - strEqual(version, "14,9")) return "MacBook Pro (14-inch, 2023)"; - if(strEqual(version, "14,3")) return "Mac mini (M2, 2023, Two Thunderbolt 4 ports)"; - if(strEqual(version, "14,12")) return "Mac mini (M2, 2023, Four Thunderbolt 4 ports)"; - if(strEqual(version, "14,7")) return "MacBook Pro (13-inch, M2, 2022)"; - if(strEqual(version, "14,2")) return "MacBook Air (M2, 2022)"; - if(strEqual(version, "13,1")) return "Mac Studio (M1 Max, 2022, Two USB-C front ports)"; - if(strEqual(version, "13,2")) return "Mac Studio (M1 Ultra, 2022, Two Thunderbolt 4 front ports)"; + if(ffStrEquals(version, "14,15")) return "MacBook Air (15-inch, M2, 2023)"; + if(ffStrEquals(version, "14,14")) return "Mac Studio (M2 Ultra, 2023, Two Thunderbolt 4 front ports)"; + if(ffStrEquals(version, "14,13")) return "Mac Studio (M2 Max, 2023, Two USB-C front ports)"; + if(ffStrEquals(version, "14,8")) return "Mac Pro (2023)"; + if(ffStrEquals(version, "14,6") || + ffStrEquals(version, "14,10")) return "MacBook Pro (16-inch, 2023)"; + if(ffStrEquals(version, "14,5") || + ffStrEquals(version, "14,9")) return "MacBook Pro (14-inch, 2023)"; + if(ffStrEquals(version, "14,3")) return "Mac mini (M2, 2023, Two Thunderbolt 4 ports)"; + if(ffStrEquals(version, "14,12")) return "Mac mini (M2, 2023, Four Thunderbolt 4 ports)"; + if(ffStrEquals(version, "14,7")) return "MacBook Pro (13-inch, M2, 2022)"; + if(ffStrEquals(version, "14,2")) return "MacBook Air (M2, 2022)"; + if(ffStrEquals(version, "13,1")) return "Mac Studio (M1 Max, 2022, Two USB-C front ports)"; + if(ffStrEquals(version, "13,2")) return "Mac Studio (M1 Ultra, 2022, Two Thunderbolt 4 front ports)"; } else if(ffStrbufStartsWithS(hwModel, "iMac")) { const char* version = hwModel->chars + strlen("iMac"); - if(strEqual(version, "21,1")) return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports, Two USB 3 ports)"; - if(strEqual(version, "21,2")) return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports)"; - if(strEqual(version, "20,1") || - strEqual(version, "20,2")) return "iMac (Retina 5K, 27-inch, 2020)"; - if(strEqual(version, "19,1")) return "iMac (Retina 5K, 27-inch, 2019)"; - if(strEqual(version, "19,2")) return "iMac (Retina 4K, 21.5-inch, 2019)"; - if(strEqual(version, "Pro1,1")) return "iMac Pro (2017)"; - if(strEqual(version, "18,3")) return "iMac (Retina 5K, 27-inch, 2017)"; - if(strEqual(version, "18,2")) return "iMac (Retina 4K, 21.5-inch, 2017)"; - if(strEqual(version, "18,1")) return "iMac (21.5-inch, 2017)"; - if(strEqual(version, "17,1")) return "iMac (Retina 5K, 27-inch, Late 2015)"; - if(strEqual(version, "16,2")) return "iMac (Retina 4K, 21.5-inch, Late 2015)"; - if(strEqual(version, "16,1")) return "iMac (21.5-inch, Late 2015)"; - if(strEqual(version, "15,1")) return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)"; - if(strEqual(version, "14,4")) return "iMac (21.5-inch, Mid 2014)"; - if(strEqual(version, "14,2")) return "iMac (27-inch, Late 2013)"; - if(strEqual(version, "14,1")) return "iMac (21.5-inch, Late 2013)"; - if(strEqual(version, "13,2")) return "iMac (27-inch, Late 2012)"; - if(strEqual(version, "13,1")) return "iMac (21.5-inch, Late 2012)"; - if(strEqual(version, "12,2")) return "iMac (27-inch, Mid 2011)"; - if(strEqual(version, "12,1")) return "iMac (21.5-inch, Mid 2011)"; - if(strEqual(version, "11,3")) return "iMac (27-inch, Mid 2010)"; - if(strEqual(version, "11,2")) return "iMac (21.5-inch, Mid 2010)"; - if(strEqual(version, "10,1")) return "iMac (27/21.5-inch, Late 2009)"; - if(strEqual(version, "9,1")) return "iMac (24/20-inch, Early 2009)"; + if(ffStrEquals(version, "21,1")) return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports, Two USB 3 ports)"; + if(ffStrEquals(version, "21,2")) return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports)"; + if(ffStrEquals(version, "20,1") || + ffStrEquals(version, "20,2")) return "iMac (Retina 5K, 27-inch, 2020)"; + if(ffStrEquals(version, "19,1")) return "iMac (Retina 5K, 27-inch, 2019)"; + if(ffStrEquals(version, "19,2")) return "iMac (Retina 4K, 21.5-inch, 2019)"; + if(ffStrEquals(version, "Pro1,1")) return "iMac Pro (2017)"; + if(ffStrEquals(version, "18,3")) return "iMac (Retina 5K, 27-inch, 2017)"; + if(ffStrEquals(version, "18,2")) return "iMac (Retina 4K, 21.5-inch, 2017)"; + if(ffStrEquals(version, "18,1")) return "iMac (21.5-inch, 2017)"; + if(ffStrEquals(version, "17,1")) return "iMac (Retina 5K, 27-inch, Late 2015)"; + if(ffStrEquals(version, "16,2")) return "iMac (Retina 4K, 21.5-inch, Late 2015)"; + if(ffStrEquals(version, "16,1")) return "iMac (21.5-inch, Late 2015)"; + if(ffStrEquals(version, "15,1")) return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)"; + if(ffStrEquals(version, "14,4")) return "iMac (21.5-inch, Mid 2014)"; + if(ffStrEquals(version, "14,2")) return "iMac (27-inch, Late 2013)"; + if(ffStrEquals(version, "14,1")) return "iMac (21.5-inch, Late 2013)"; + if(ffStrEquals(version, "13,2")) return "iMac (27-inch, Late 2012)"; + if(ffStrEquals(version, "13,1")) return "iMac (21.5-inch, Late 2012)"; + if(ffStrEquals(version, "12,2")) return "iMac (27-inch, Mid 2011)"; + if(ffStrEquals(version, "12,1")) return "iMac (21.5-inch, Mid 2011)"; + if(ffStrEquals(version, "11,3")) return "iMac (27-inch, Mid 2010)"; + if(ffStrEquals(version, "11,2")) return "iMac (21.5-inch, Mid 2010)"; + if(ffStrEquals(version, "10,1")) return "iMac (27/21.5-inch, Late 2009)"; + if(ffStrEquals(version, "9,1")) return "iMac (24/20-inch, Early 2009)"; } return hwModel->chars; } -void ffDetectHostImpl(FFHostResult* host) +const char* ffDetectHost(FFHostResult* host) { - ffStrbufInit(&host->error); - - ffStrbufInit(&host->productName); - ffStrbufInit(&host->productFamily); - ffStrbufInit(&host->productVersion); - ffStrbufInit(&host->productSku); - ffStrbufInitS(&host->sysVendor, "Apple"); + ffStrbufAppendS(&host->sysVendor, "Apple"); - ffStrbufAppendS(&host->error, ffSysctlGetString("hw.model", &host->productFamily)); - if(host->error.length == 0) - ffStrbufAppendS(&host->productName, getProductName(&host->productFamily)); + const char* error = ffSysctlGetString("hw.model", &host->productFamily); + if (error) return error; + ffStrbufAppendS(&host->productName, getProductName(&host->productFamily)); + return NULL; } diff --git a/src/detection/host/host_bsd.c b/src/detection/host/host_bsd.c index 8be64b6c3f..9a7dcbd718 100644 --- a/src/detection/host/host_bsd.c +++ b/src/detection/host/host_bsd.c @@ -1,15 +1,19 @@ #include "host.h" -#include "common/sysctl.h" +#include "common/settings.h" +#include "util/smbiosHelper.h" -void ffDetectHostImpl(FFHostResult* host) +const char* ffDetectHost(FFHostResult* host) { - ffStrbufInit(&host->error); + ffSettingsGetFreeBSDKenv("smbios.system.product", &host->productName); + ffCleanUpSmbiosValue(&host->productName); + ffSettingsGetFreeBSDKenv("smbios.system.family", &host->productFamily); + ffCleanUpSmbiosValue(&host->productFamily); + ffSettingsGetFreeBSDKenv("smbios.system.version", &host->productVersion); + ffCleanUpSmbiosValue(&host->productVersion); + ffSettingsGetFreeBSDKenv("smbios.system.sku", &host->productSku); + ffCleanUpSmbiosValue(&host->productSku); + ffSettingsGetFreeBSDKenv("smbios.system.maker", &host->sysVendor); + ffCleanUpSmbiosValue(&host->sysVendor); - ffStrbufInit(&host->productName); - ffStrbufInit(&host->productFamily); - ffStrbufInit(&host->productVersion); - ffStrbufInit(&host->productSku); - ffStrbufInit(&host->sysVendor); - - ffStrbufAppendS(&host->error, ffSysctlGetString("hw.fdt.model", &host->productName)); + return NULL; } diff --git a/src/detection/host/host_linux.c b/src/detection/host/host_linux.c index 04ae3aa275..05e48cbbce 100644 --- a/src/detection/host/host_linux.c +++ b/src/detection/host/host_linux.c @@ -1,41 +1,18 @@ #include "host.h" #include "common/io/io.h" #include "common/processing.h" +#include "util/smbiosHelper.h" #include -static bool hostValueSet(FFstrbuf* value) -{ - return - value->length > 0 && - ffStrbufStartsWithIgnCaseS(value, "To be filled") != true && - ffStrbufStartsWithIgnCaseS(value, "To be set") != true && - ffStrbufStartsWithIgnCaseS(value, "OEM") != true && - ffStrbufStartsWithIgnCaseS(value, "O.E.M.") != true && - ffStrbufIgnCaseCompS(value, "None") != 0 && - ffStrbufIgnCaseCompS(value, "System Product") != 0 && - ffStrbufIgnCaseCompS(value, "System Product Name") != 0 && - ffStrbufIgnCaseCompS(value, "System Product Version") != 0 && - ffStrbufIgnCaseCompS(value, "System Name") != 0 && - ffStrbufIgnCaseCompS(value, "System Version") != 0 && - ffStrbufIgnCaseCompS(value, "Default string") != 0 && - ffStrbufIgnCaseCompS(value, "Undefined") != 0 && - ffStrbufIgnCaseCompS(value, "Not Specified") != 0 && - ffStrbufIgnCaseCompS(value, "Not Applicable") != 0 && - ffStrbufIgnCaseCompS(value, "INVALID") != 0 && - ffStrbufIgnCaseCompS(value, "Type1ProductConfigId") != 0 && - ffStrbufIgnCaseCompS(value, "All Series") != 0 - ; -} - -static void getHostValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) +static void getSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) { ffReadFileBuffer(devicesPath, buffer); - if(hostValueSet(buffer)) + if(ffIsSmbiosValueSet(buffer)) return; ffReadFileBuffer(classPath, buffer); - if(hostValueSet(buffer)) + if(ffIsSmbiosValueSet(buffer)) return; ffStrbufClear(buffer); @@ -43,40 +20,29 @@ static void getHostValue(const char* devicesPath, const char* classPath, FFstrbu static void getHostProductName(FFstrbuf* name) { - getHostValue("/sys/devices/virtual/dmi/id/product_name", "/sys/class/dmi/id/product_name", name); + getSmbiosValue("/sys/devices/virtual/dmi/id/product_name", "/sys/class/dmi/id/product_name", name); if(name->length > 0) return; ffReadFileBuffer("/sys/firmware/devicetree/base/model", name); - if(hostValueSet(name)) + if(ffIsSmbiosValueSet(name)) return; //does a clear before the read ffReadFileBuffer("/tmp/sysinfo/model", name); - if(hostValueSet(name)) + if(ffIsSmbiosValueSet(name)) return; ffStrbufClear(name); } -void ffDetectHostImpl(FFHostResult* host) +const char* ffDetectHost(FFHostResult* host) { - ffStrbufInit(&host->error); - - ffStrbufInit(&host->productFamily); - getHostValue("/sys/devices/virtual/dmi/id/product_family", "/sys/class/dmi/id/product_family", &host->productFamily); - - ffStrbufInit(&host->productName); + getSmbiosValue("/sys/devices/virtual/dmi/id/product_family", "/sys/class/dmi/id/product_family", &host->productFamily); getHostProductName(&host->productName); - - ffStrbufInit(&host->productVersion); - getHostValue("/sys/devices/virtual/dmi/id/product_version", "/sys/class/dmi/id/product_version", &host->productVersion); - - ffStrbufInit(&host->productSku); - getHostValue("/sys/devices/virtual/dmi/id/product_sku", "/sys/class/dmi/id/product_sku", &host->productSku); - - ffStrbufInit(&host->sysVendor); - getHostValue("/sys/devices/virtual/dmi/id/sys_vendor", "/sys/class/dmi/id/sys_vendor", &host->sysVendor); + getSmbiosValue("/sys/devices/virtual/dmi/id/product_version", "/sys/class/dmi/id/product_version", &host->productVersion); + getSmbiosValue("/sys/devices/virtual/dmi/id/product_sku", "/sys/class/dmi/id/product_sku", &host->productSku); + getSmbiosValue("/sys/devices/virtual/dmi/id/sys_vendor", "/sys/class/dmi/id/sys_vendor", &host->sysVendor); //KVM/Qemu virtual machine if(ffStrbufStartsWithS(&host->productName, "Standard PC")) @@ -84,13 +50,16 @@ void ffDetectHostImpl(FFHostResult* host) if(host->productFamily.length == 0 && host->productName.length == 0) { + const char* wslDistroName = getenv("WSL_DISTRO_NAME"); //On WSL, the real host can't be detected. Instead use WSL as host. - if(getenv("WSL_DISTRO") != NULL || getenv("WSL_INTEROP") != NULL) + if(wslDistroName != NULL || getenv("WSL_DISTRO") != NULL || getenv("WSL_INTEROP") != NULL) { ffStrbufAppendS(&host->productName, "Windows Subsystem for Linux"); + if (wslDistroName) + ffStrbufAppendF(&host->productName, " - %s", wslDistroName); + ffStrbufAppendS(&host->productFamily, "WSL"); - FFstrbuf wslVer; //Wide charactors - ffStrbufInit(&wslVer); + FF_STRBUF_AUTO_DESTROY wslVer = ffStrbufCreate(); //Wide charactors if(!ffProcessAppendStdOut(&wslVer, (char* const[]){ "wsl.exe", "--version", @@ -99,14 +68,13 @@ void ffDetectHostImpl(FFHostResult* host) { ffStrbufSubstrBeforeFirstC(&wslVer, '\r'); //CRLF ffStrbufSubstrAfterLastC(&wslVer, ' '); - ffStrbufAppendS(&host->productName, " ("); for(uint32_t i = 0; i < wslVer.length; ++i) { if(wslVer.chars[i]) //don't append \0 - ffStrbufAppendC(&host->productName, wslVer.chars[i]); + ffStrbufAppendC(&host->productVersion, wslVer.chars[i]); } - ffStrbufAppendC(&host->productName, ')'); } - ffStrbufDestroy(&wslVer); } } + + return NULL; } diff --git a/src/detection/host/host_windows.c b/src/detection/host/host_windows.c index 75afd05637..afc2b242c4 100644 --- a/src/detection/host/host_windows.c +++ b/src/detection/host/host_windows.c @@ -1,24 +1,24 @@ #include "host.h" #include "util/windows/registry.h" +#include "util/smbiosHelper.h" -void ffDetectHostImpl(FFHostResult* host) +const char* ffDetectHost(FFHostResult* host) { - ffStrbufInit(&host->error); - - ffStrbufInit(&host->productName); - ffStrbufInit(&host->productFamily); - ffStrbufInit(&host->productVersion); - ffStrbufInit(&host->productSku); - ffStrbufInit(&host->sysVendor); - FF_HKEY_AUTO_DESTROY hKey = NULL; - if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &host->error)) - return; + if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, NULL)) + return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"HARDWARE\\DESCRIPTION\\System\\BIOS\", &hKey, NULL) failed"; ffRegReadStrbuf(hKey, L"SystemProductName", &host->productName, NULL); + ffCleanUpSmbiosValue(&host->productName); ffRegReadStrbuf(hKey, L"SystemFamily", &host->productFamily, NULL); + ffCleanUpSmbiosValue(&host->productFamily); ffRegReadStrbuf(hKey, L"SystemVersion", &host->productVersion, NULL); + ffCleanUpSmbiosValue(&host->productVersion); ffRegReadStrbuf(hKey, L"SystemSKU", &host->productSku, NULL); + ffCleanUpSmbiosValue(&host->productSku); ffRegReadStrbuf(hKey, L"SystemManufacturer", &host->sysVendor, NULL); + ffCleanUpSmbiosValue(&host->sysVendor); + + return NULL; } diff --git a/src/detection/icons/icons.h b/src/detection/icons/icons.h index 4f948cdad8..744dc3f5f9 100644 --- a/src/detection/icons/icons.h +++ b/src/detection/icons/icons.h @@ -5,6 +5,6 @@ #include "fastfetch.h" -const char* ffDetectIcons(const FFinstance* instance, FFstrbuf* result); +const char* ffDetectIcons(FFstrbuf* result); #endif diff --git a/src/detection/icons/icons_linux.c b/src/detection/icons/icons_linux.c index 4ab35b5421..357cfadb65 100644 --- a/src/detection/icons/icons_linux.c +++ b/src/detection/icons/icons_linux.c @@ -3,23 +3,22 @@ #include "detection/gtk_qt/gtk_qt.h" #include "detection/displayserver/displayserver.h" -const char* ffDetectIcons(const FFinstance* instance, FFstrbuf* result) +const char* ffDetectIcons(FFstrbuf* result) { - const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance); + const FFDisplayServerResult* wmde = ffConnectDisplayServer(); if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY) == 0) return "Icons aren't supported in TTY"; - const FFstrbuf* plasma = &ffDetectQt(instance)->icons; - const FFstrbuf* gtk2 = &ffDetectGTK2(instance)->icons; - const FFstrbuf* gtk3 = &ffDetectGTK3(instance)->icons; - const FFstrbuf* gtk4 = &ffDetectGTK4(instance)->icons; + const FFstrbuf* plasma = &ffDetectQt()->icons; + const FFstrbuf* gtk2 = &ffDetectGTK2()->icons; + const FFstrbuf* gtk3 = &ffDetectGTK3()->icons; + const FFstrbuf* gtk4 = &ffDetectGTK4()->icons; if(plasma->length == 0 && gtk2->length == 0 && gtk3->length == 0 && gtk4->length == 0) return "No icons could be found"; - FF_STRBUF_AUTO_DESTROY gtkPretty; - ffStrbufInit(>kPretty); + FF_STRBUF_AUTO_DESTROY gtkPretty = ffStrbufCreate(); ffParseGTK(>kPretty, gtk2, gtk3, gtk4); if(plasma->length > 0) diff --git a/src/detection/icons/icons_nosupport.c b/src/detection/icons/icons_nosupport.c index 9a47a01831..f0a0ebe8cd 100644 --- a/src/detection/icons/icons_nosupport.c +++ b/src/detection/icons/icons_nosupport.c @@ -1,6 +1,6 @@ #include "icons.h" -const char* ffDetectIcons(FF_MAYBE_UNUSED const FFinstance* instance, FF_MAYBE_UNUSED FFstrbuf* result) +const char* ffDetectIcons(FF_MAYBE_UNUSED FFstrbuf* result) { return "Not supported on this platform"; } diff --git a/src/detection/icons/icons_windows.c b/src/detection/icons/icons_windows.c index 881589bc11..0008d04af3 100644 --- a/src/detection/icons/icons_windows.c +++ b/src/detection/icons/icons_windows.c @@ -1,7 +1,7 @@ #include "icons.h" #include "util/windows/registry.h" -const char* ffDetectIcons(FF_MAYBE_UNUSED const FFinstance* instance, FFstrbuf* result) +const char* ffDetectIcons(FFstrbuf* result) { FF_HKEY_AUTO_DESTROY hKey = NULL; if(!ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu", &hKey, NULL)) diff --git a/src/detection/lm/lm.h b/src/detection/lm/lm.h new file mode 100644 index 0000000000..e118419a5a --- /dev/null +++ b/src/detection/lm/lm.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_lm_lm +#define FF_INCLUDED_detection_lm_lm + +#include "fastfetch.h" + +typedef struct FFLMResult +{ + FFstrbuf service; + FFstrbuf type; + FFstrbuf version; +} FFLMResult; + +const char* ffDetectLM(FFLMResult* result); + +#endif diff --git a/src/detection/lm/lm_linux.c b/src/detection/lm/lm_linux.c new file mode 100644 index 0000000000..6416c80a7e --- /dev/null +++ b/src/detection/lm/lm_linux.c @@ -0,0 +1,187 @@ +#include "lm.h" +#include "common/properties.h" +#include "common/dbus.h" +#include "common/processing.h" +#include "detection/displayserver/displayserver.h" + +#include + +#define FF_SYSTEMD_SESSIONS_PATH "/var/run/systemd/sessions/" +#define FF_SYSTEMD_USERS_PATH "/run/systemd/users/" + +static const char* getGdmVersion(FFstrbuf* version) +{ + const char* error = ffProcessAppendStdOut(version, (char* const[]) { + "gdm", + "--version", + NULL + }); + if (error || version->length == 0) + { + error = ffProcessAppendStdOut(version, (char* const[]) { + "gdm3", + "--version", + NULL + }); + if (error || version->length == 0) return "Failed to get GDM version"; + } + + // GDM 44.1 + ffStrbufSubstrAfterFirstC(version, ' '); + return NULL; +} + +static const char* getSshdVersion(FFstrbuf* version) +{ + const char* error = ffProcessAppendStdErr(version, (char* const[]) { + "sshd", + "-qv", + NULL + }); + if (error) + return error; + + // unknown option -- v + // OpenSSH_9.0p1, OpenSSL 3.0.9 30 May 2023... + ffStrbufSubstrBeforeFirstC(version, ','); + ffStrbufSubstrAfterFirstC(version, '_'); + return NULL; +} + +#ifdef FF_HAVE_ZLIB +#include "common/library.h" +#include +#include + +static const char* getSddmVersion(FFstrbuf* version) +{ + FF_LIBRARY_LOAD(zlib, &instance.config.libZ, "dlopen libz failed", "libz" FF_LIBRARY_EXTENSION, 2) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzopen); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzread); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzerror); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gztell); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzrewind); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzclose); + + gzFile file = ffgzopen("/usr/share/man/man1/sddm.1.gz", "rb"); + if (file == Z_NULL) + return "ffgzopen(\"/usr/share/man/man1/sddm.1.gz\", \"rb\") failed"; + + ffStrbufEnsureFree(version, 2047); + memset(version->chars, 0, version->allocated); + int size = ffgzread(file, version->chars, version->allocated - 1); + ffgzclose(file); + + if (size <= 0) + return "ffgzread(file, version->chars, version->length) failed"; + + version->length = (uint32_t) size; + uint32_t index = ffStrbufFirstIndexS(version, ".TH "); + if (index == version->length) + { + ffStrbufClear(version); + return ".TH is not found"; + } + + ffStrbufSubstrBefore(version, ffStrbufNextIndexC(version, index, '\n')); + ffStrbufSubstrAfter(version, index + (uint32_t) strlen(".TH ")); + + // "SDDM" 1 "May 2014" "sddm 0.20.0" "sddm" + ffStrbufSubstrBeforeLastC(version, ' '); + ffStrbufTrimRight(version, '"'); + ffStrbufSubstrAfterLastC(version, ' '); + + return NULL; +} +#else +static const char* getSddmVersion(FF_MAYBE_UNUSED FFstrbuf* version) +{ + return "Fastfetch is built without libz support"; +} +#endif + +static const char* getXfwmVersion(FFstrbuf* version) +{ + const char* error = ffProcessAppendStdOut(version, (char* const[]) { + "xfwm4", + "--version", + NULL + }); + if (error) + return error; + + // This is xfwm4 version 4.18.0 (revision 7e7473c5b) for Xfce 4.18... + ffStrbufSubstrAfterFirstS(version, "version "); + ffStrbufSubstrBeforeFirstC(version, ' '); + + return NULL; +} + +static const char* getLightdmVersion(FFstrbuf* version) +{ + const char* error = ffProcessAppendStdErr(version, (char* const[]) { + "lightdm", + "--version", + NULL + }); + if (error) + return error; + + // lightdm 1.30.0 + ffStrbufSubstrAfterFirstC(version, ' '); + ffStrbufTrimRight(version, '\n'); + + return NULL; +} + +const char* ffDetectLM(FFLMResult* result) +{ + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + + FF_STRBUF_AUTO_DESTROY sessionId = ffStrbufCreateS(getenv("XDG_SESSION_ID")); + if (sessionId.length == 0) + { + // On some incorrectly configured systems, $XDG_SESSION_ID is not set. Try finding it ourself + // WARNING: This is private data. Do not parse + ffStrbufAppendF(&path, "/run/systemd/users/%d", getuid()); + + // This is actually buggy, and assumes current user is using DE + // `sd_pid_get_session` can be a better option, but we need to find a pid to use + if (!ffParsePropFileValues(path.chars, 1, (FFpropquery[]) { + {"DISPLAY=", &sessionId}, + })) + return "Failed to get $XDG_SESSION_ID"; + ffStrbufClear(&path); + } + + ffStrbufAppendS(&path, "/var/run/systemd/sessions/"); + ffStrbufAppend(&path, &sessionId); + + // WARNING: This is private data. Do not parse + if (!ffParsePropFileValues(path.chars, 2, (FFpropquery[]) { + {"SERVICE=", &result->service}, + {"TYPE=", &result->type}, + })) + return "Failed to parse /run/systemd/sessions/$XDG_SESSION_ID"; + + if (ffStrbufStartsWithS(&result->service, "gdm")) + getGdmVersion(&result->version); + else if (ffStrbufStartsWithS(&result->service, "sddm")) + getSddmVersion(&result->version); + else if (ffStrbufStartsWithS(&result->service, "xfwm")) + getXfwmVersion(&result->version); + else if (ffStrbufStartsWithS(&result->service, "lightdm")) + getLightdmVersion(&result->version); + else if (ffStrbufStartsWithS(&result->service, "sshd")) + getSshdVersion(&result->version); + + // Correct char cases + if (ffStrbufIgnCaseEqualS(&result->type, FF_WM_PROTOCOL_WAYLAND)) + ffStrbufSetS(&result->type, FF_WM_PROTOCOL_WAYLAND); + else if (ffStrbufIgnCaseEqualS(&result->type, FF_WM_PROTOCOL_X11)) + ffStrbufSetS(&result->type, FF_WM_PROTOCOL_X11); + else if (ffStrbufIgnCaseEqualS(&result->type, FF_WM_PROTOCOL_TTY)) + ffStrbufSetS(&result->type, FF_WM_PROTOCOL_TTY); + + return NULL; +} diff --git a/src/detection/lm/lm_nosupport.c b/src/detection/lm/lm_nosupport.c new file mode 100644 index 0000000000..cd1f5f7f74 --- /dev/null +++ b/src/detection/lm/lm_nosupport.c @@ -0,0 +1,6 @@ +#include "lm.h" + +const char* ffDetectLM(FF_MAYBE_UNUSED FFLMResult* result) +{ + return "Not supported on this platform"; +} diff --git a/src/detection/localip/localip.h b/src/detection/localip/localip.h index f90e97c26a..6fea95a79d 100644 --- a/src/detection/localip/localip.h +++ b/src/detection/localip/localip.h @@ -11,8 +11,13 @@ typedef struct FFLocalIpResult FFstrbuf ipv4; FFstrbuf ipv6; FFstrbuf mac; + bool defaultRoute; + + #ifdef _WIN32 + uint32_t ifIndex; + #endif } FFLocalIpResult; -const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results); +const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results); #endif diff --git a/src/detection/localip/localip_linux.c b/src/detection/localip/localip_linux.c index b753d14470..e702347357 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -1,4 +1,5 @@ #include "localip.h" +#include "common/io/io.h" #include #include @@ -6,11 +7,125 @@ #include #include #include +#include #if defined(__FreeBSD__) || defined(__APPLE__) #include +#include +#include #else -#include +#include +#endif + +#if defined(__linux__) +static bool getDefaultRoute(char iface[IF_NAMESIZE + 1]) +{ + FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/net/route", "r"); + if (!netRoute) return false; + + // skip first line + flockfile(netRoute); + while (getc_unlocked(netRoute) != '\n'); + funlockfile(netRoute); + unsigned long long destination; //, gateway, flags, refCount, use, metric, mask, mtu, + + static_assert(IF_NAMESIZE >= 16, "IF_NAMESIZE is too small"); + while (fscanf(netRoute, "%16s%llx%*[^\n]", iface, &destination) == 2) + { + if (destination == 0) + return true; + } + return false; +} +#elif defined(__FreeBSD__) || defined(__APPLE__) + +#define ROUNDUP2(a, n) ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n)) + +#if defined(__APPLE__) +# define ROUNDUP(a) ROUNDUP2((a), sizeof(int)) +#elif defined(__NetBSD__) +# define ROUNDUP(a) ROUNDUP2((a), sizeof(uint64_t)) +#elif defined(__FreeBSD__) +# define ROUNDUP(a) ROUNDUP2((a), sizeof(int)) +#elif defined(__OpenBSD__) +# define ROUNDUP(a) ROUNDUP2((a), sizeof(int)) +#else +# error unknown platform +#endif + +static struct sockaddr * +get_rt_address(struct rt_msghdr *rtm, int desired) +{ + struct sockaddr *sa = (struct sockaddr *)(rtm + 1); + + for (int i = 0; i < RTAX_MAX; i++) + { + if (rtm->rtm_addrs & (1 << i)) + { + if ((1 <sa_len) + (char *)sa); + } + } + return NULL; +} + +static bool getDefaultRoute(char iface[IF_NAMESIZE + 1]) +{ + //https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104 + + FF_AUTO_CLOSE_FD int pfRoute = socket(PF_ROUTE, SOCK_RAW, AF_INET); + if (pfRoute < 0) + return false; + + { + struct timeval timeout = {1, 0}; + setsockopt(pfRoute, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); + setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)); + } + + int pid = getpid(); + + struct { + struct rt_msghdr hdr; + struct sockaddr_in dst; + uint8_t data[512]; + } rtmsg = { + .hdr = { + .rtm_type = RTM_GET, + .rtm_flags = RTF_UP | RTF_GATEWAY, + .rtm_version = RTM_VERSION, + .rtm_addrs = RTA_DST | RTA_IFP, + .rtm_msglen = sizeof(rtmsg.hdr) + sizeof(rtmsg.dst), + .rtm_pid = pid, + .rtm_seq = 1, + }, + .dst = { + .sin_family = AF_INET, + .sin_len = sizeof(rtmsg.dst), + }, + }; + + if (write(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen) != rtmsg.hdr.rtm_msglen) + return false; + + while (read(pfRoute, &rtmsg, sizeof(rtmsg)) > 0) + { + if (rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == pid) + { + struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(&rtmsg.hdr, RTA_IFP); + if (sdl) + { + assert(sdl->sdl_nlen <= IF_NAMESIZE); + memcpy(iface, sdl->sdl_data, sdl->sdl_nlen); + iface[sdl->sdl_nlen] = 0; + return true; + } + return false; + } + } + return false; +} #endif static void addNewIp(FFlist* list, const char* name, const char* addr, int type) @@ -30,6 +145,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type) ffStrbufInit(&ip->ipv4); ffStrbufInit(&ip->ipv6); ffStrbufInit(&ip->mac); + ip->defaultRoute = false; } switch (type) @@ -46,7 +162,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type) } } -const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) +const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) { struct ifaddrs* ifAddrStruct = NULL; if(getifaddrs(&ifAddrStruct) < 0) @@ -57,15 +173,15 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) if (!ifa->ifa_addr || !(ifa->ifa_flags & IFF_RUNNING)) continue; - if ((ifa->ifa_flags & IFF_LOOPBACK) && !(instance->config.localIpShowType & FF_LOCALIP_TYPE_LOOP_BIT)) + if ((ifa->ifa_flags & IFF_LOOPBACK) && !(options->showType & FF_LOCALIP_TYPE_LOOP_BIT)) continue; - if (instance->config.localIpNamePrefix.length && strncmp(ifa->ifa_name, instance->config.localIpNamePrefix.chars, instance->config.localIpNamePrefix.length) != 0) + if (options->namePrefix.length && strncmp(ifa->ifa_name, options->namePrefix.chars, options->namePrefix.length) != 0) continue; if (ifa->ifa_addr->sa_family == AF_INET) { - if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV4_BIT)) + if (!(options->showType & FF_LOCALIP_TYPE_IPV4_BIT)) continue; struct sockaddr_in* ipv4 = (struct sockaddr_in*) ifa->ifa_addr; @@ -75,7 +191,7 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) } else if (ifa->ifa_addr->sa_family == AF_INET6) { - if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV6_BIT)) + if (!(options->showType & FF_LOCALIP_TYPE_IPV6_BIT)) continue; struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)ifa->ifa_addr; @@ -86,7 +202,7 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) #if defined(__FreeBSD__) || defined(__APPLE__) else if (ifa->ifa_addr->sa_family == AF_LINK) { - if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_MAC_BIT)) + if (!(options->showType & FF_LOCALIP_TYPE_MAC_BIT)) continue; char addressBuffer[32]; @@ -98,7 +214,7 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) #else else if (ifa->ifa_addr->sa_family == AF_PACKET) { - if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_MAC_BIT)) + if (!(options->showType & FF_LOCALIP_TYPE_MAC_BIT)) continue; char addressBuffer[32]; @@ -111,5 +227,12 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) } if (ifAddrStruct) freeifaddrs(ifAddrStruct); + + char iface[16 /*IF_NAMESIZE*/ + 1]; + if (getDefaultRoute(iface)) + { + FF_LIST_FOR_EACH(FFLocalIpResult, ip, *results) + ip->defaultRoute = ffStrbufEqualS(&ip->name, iface); + } return NULL; } diff --git a/src/detection/localip/localip_windows.c b/src/detection/localip/localip_windows.c index aa3c1dd520..c986120baf 100644 --- a/src/detection/localip/localip_windows.c +++ b/src/detection/localip/localip_windows.c @@ -6,7 +6,34 @@ #include "util/windows/unicode.h" #include "localip.h" -static void addNewIp(FFlist* list, const char* name, const char* value, int type, bool newIp) +static void setDefaultRoute(FFlist* ips) +{ + ULONG size = 0; + if (GetIpForwardTable(NULL, &size, TRUE) != ERROR_INSUFFICIENT_BUFFER) + return; + + FF_AUTO_FREE MIB_IPFORWARDTABLE* pIpForwardTable = (MIB_IPFORWARDTABLE*) malloc(size); + if (GetIpForwardTable(pIpForwardTable, &size, TRUE) != ERROR_SUCCESS) + return; + + for (uint32_t i = 0; i < pIpForwardTable->dwNumEntries; ++i) + { + MIB_IPFORWARDROW* ipForwardRow = &pIpForwardTable->table[i]; + if (ipForwardRow->dwForwardDest == 0 && ipForwardRow->dwForwardMask == 0) + { + FF_LIST_FOR_EACH(FFLocalIpResult, ip, *ips) + { + if (ip->ifIndex == ipForwardRow->dwForwardIfIndex) + { + ip->defaultRoute = true; + break; + } + } + } + } +} + +static void addNewIp(FFlist* list, const char* name, const char* value, int type, bool newIp, uint32_t ifIndex) { FFLocalIpResult* ip = NULL; @@ -17,6 +44,8 @@ static void addNewIp(FFlist* list, const char* name, const char* value, int type ffStrbufInit(&ip->ipv4); ffStrbufInit(&ip->ipv6); ffStrbufInit(&ip->mac); + ip->defaultRoute = false; + ip->ifIndex = ifIndex; } else { @@ -37,7 +66,7 @@ static void addNewIp(FFlist* list, const char* name, const char* value, int type } } -const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) +const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) { IP_ADAPTER_ADDRESSES* FF_AUTO_FREE adapter_addresses = NULL; @@ -51,8 +80,8 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) assert(adapter_addresses); DWORD error = GetAdaptersAddresses( - instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV4_BIT - ? instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV6_BIT ? AF_UNSPEC : AF_INET + options->showType & FF_LOCALIP_TYPE_IPV4_BIT + ? options->showType & FF_LOCALIP_TYPE_IPV6_BIT ? AF_UNSPEC : AF_INET : AF_INET6, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER, NULL, @@ -71,23 +100,23 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next) { bool isLoop = adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK; - if (isLoop && !(instance->config.localIpShowType & FF_LOCALIP_TYPE_LOOP_BIT)) + if (isLoop && !(options->showType & FF_LOCALIP_TYPE_LOOP_BIT)) continue; bool newIp = true; char name[128]; WideCharToMultiByte(CP_UTF8, 0, adapter->FriendlyName, -1, name, sizeof(name), NULL, NULL); - if (instance->config.localIpNamePrefix.length && strncmp(name, instance->config.localIpNamePrefix.chars, instance->config.localIpNamePrefix.length) != 0) + if (options->namePrefix.length && strncmp(name, options->namePrefix.chars, options->namePrefix.length) != 0) continue; - if (instance->config.localIpShowType & FF_LOCALIP_TYPE_MAC_BIT && adapter->PhysicalAddressLength == 6) + if (options->showType & FF_LOCALIP_TYPE_MAC_BIT && adapter->PhysicalAddressLength == 6) { char addressBuffer[32]; uint8_t* ptr = adapter->PhysicalAddress; snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); - addNewIp(results, name, addressBuffer, -1, newIp); + addNewIp(results, name, addressBuffer, -1, newIp, adapter->IfIndex); newIp = false; } @@ -98,7 +127,7 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) SOCKADDR_IN* ipv4 = (SOCKADDR_IN*) ifa->Address.lpSockaddr; char addressBuffer[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN); - addNewIp(results, name, addressBuffer, AF_INET, newIp); + addNewIp(results, name, addressBuffer, AF_INET, newIp, adapter->IfIndex); newIp = false; } else if (ifa->Address.lpSockaddr->sa_family == AF_INET6) @@ -106,11 +135,13 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) SOCKADDR_IN6* ipv6 = (SOCKADDR_IN6*) ifa->Address.lpSockaddr; char addressBuffer[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN); - addNewIp(results, name, addressBuffer, AF_INET6, newIp); + addNewIp(results, name, addressBuffer, AF_INET6, newIp, adapter->IfIndex); newIp = false; } } } + setDefaultRoute(results); + return NULL; } diff --git a/src/detection/media/media.c b/src/detection/media/media.c index 5c9d2145f2..50604342bd 100644 --- a/src/detection/media/media.c +++ b/src/detection/media/media.c @@ -1,12 +1,12 @@ #include "media.h" #include "detection/internal.h" -void ffDetectMediaImpl(const FFinstance* instance, FFMediaResult* media); +void ffDetectMediaImpl(FFMediaResult* media); -const FFMediaResult* ffDetectMedia(const FFinstance* instance) +const FFMediaResult* ffDetectMedia(void) { FF_DETECTION_INTERNAL_GUARD(FFMediaResult, - ffStrbufInitA(&result.error, 0); + ffStrbufInit(&result.error); ffStrbufInit(&result.playerId); ffStrbufInit(&result.player); ffStrbufInit(&result.song); @@ -15,7 +15,7 @@ const FFMediaResult* ffDetectMedia(const FFinstance* instance) ffStrbufInit(&result.url); ffStrbufInit(&result.status); - ffDetectMediaImpl(instance, &result); + ffDetectMediaImpl(&result); if(result.song.length == 0 && result.error.length == 0) ffStrbufAppendS(&result.error, "No media found"); diff --git a/src/detection/media/media.h b/src/detection/media/media.h index f82fa43592..8043e0d930 100644 --- a/src/detection/media/media.h +++ b/src/detection/media/media.h @@ -17,6 +17,6 @@ typedef struct FFMediaResult FFstrbuf status; } FFMediaResult; -const FFMediaResult* ffDetectMedia(const FFinstance* instance); +const FFMediaResult* ffDetectMedia(); #endif diff --git a/src/detection/media/media_apple.m b/src/detection/media/media_apple.m index 3e4bf3d75f..7413012736 100644 --- a/src/detection/media/media_apple.m +++ b/src/detection/media/media_apple.m @@ -77,7 +77,7 @@ return error; } -void ffDetectMediaImpl(const FFinstance* instance, FFMediaResult* media) +void ffDetectMediaImpl(FFMediaResult* media) { FF_UNUSED(instance) const char* error = getMedia(media); diff --git a/src/detection/media/media_linux.c b/src/detection/media/media_linux.c index d470641f7e..2552fdab2b 100644 --- a/src/detection/media/media_linux.c +++ b/src/detection/media/media_linux.c @@ -1,6 +1,7 @@ #include "fastfetch.h" #include "detection/media/media.h" #include "common/thread.h" +#include "util/stringUtils.h" #include @@ -61,13 +62,13 @@ static bool getBusProperties(FFDBusData* data, const char* busName, FFMediaResul data->lib->ffdbus_message_iter_next(&dictIterator); - if(strcmp(key, "xesam:title") == 0) + if(ffStrEquals(key, "xesam:title")) ffDBusGetValue(data, &dictIterator, &result->song); - else if(strcmp(key, "xesam:album") == 0) + else if(ffStrEquals(key, "xesam:album")) ffDBusGetValue(data, &dictIterator, &result->album); - else if(strcmp(key, "xesam:artist") == 0) + else if(ffStrEquals(key, "xesam:artist")) ffDBusGetValue(data, &dictIterator, &result->artist); - else if(strcmp(key, "xesam:url") == 0) + else if(ffStrEquals(key, "xesam:url")) ffDBusGetValue(data, &dictIterator, &result->url); if(result->song.length > 0 && result->artist.length > 0 && result->album.length > 0 && result->url.length > 0) @@ -99,20 +100,17 @@ static bool getBusProperties(FFDBusData* data, const char* busName, FFMediaResul return true; } -static void getCustomBus(FFDBusData* data, const FFinstance* instance, FFMediaResult* result) +static void getCustomBus(FFDBusData* data, const FFstrbuf* playerName, FFMediaResult* result) { - if(ffStrbufStartsWithS(&instance->config.playerName, FF_DBUS_MPRIS_PREFIX)) + if(ffStrbufStartsWithS(playerName, FF_DBUS_MPRIS_PREFIX)) { - getBusProperties(data, instance->config.playerName.chars, result); + getBusProperties(data, playerName->chars, result); return; } - FFstrbuf busName; - ffStrbufInit(&busName); - ffStrbufAppendS(&busName, FF_DBUS_MPRIS_PREFIX); - ffStrbufAppend(&busName, &instance->config.playerName); + FF_STRBUF_AUTO_DESTROY busName = ffStrbufCreateS(FF_DBUS_MPRIS_PREFIX); + ffStrbufAppend(&busName, playerName); getBusProperties(data, busName.chars, result); - ffStrbufDestroy(&busName); } static void getBestBus(FFDBusData* data, FFMediaResult* result) @@ -142,7 +140,7 @@ static void getBestBus(FFDBusData* data, FFMediaResult* result) const char* busName; data->lib->ffdbus_message_iter_get_basic(&arrayIterator, &busName); - if(strncmp(busName, FF_DBUS_MPRIS_PREFIX, sizeof(FF_DBUS_MPRIS_PREFIX) - 1) != 0) + if(!ffStrStartsWith(busName, FF_DBUS_MPRIS_PREFIX)) FF_DBUS_ITER_CONTINUE(data, &arrayIterator) if(getBusProperties(data, busName, result)) @@ -154,15 +152,17 @@ static void getBestBus(FFDBusData* data, FFMediaResult* result) data->lib->ffdbus_message_unref(reply); } -static const char* getMedia(const FFinstance* instance, FFMediaResult* result) +static const char* getMedia(FFMediaResult* result) { FFDBusData data; - const char* error = ffDBusLoadData(instance, DBUS_BUS_SESSION, &data); + const char* error = ffDBusLoadData(DBUS_BUS_SESSION, &data); if(error != NULL) return error; - if(instance->config.playerName.length > 0) - getCustomBus(&data, instance, result); + // FIXME: This is shared for both player and media module. + // However it uses an option in one specific module + if(instance.config.playerName.length > 0) + getCustomBus(&data, &instance.config.playerName, result); else getBestBus(&data, result); @@ -171,13 +171,12 @@ static const char* getMedia(const FFinstance* instance, FFMediaResult* result) #endif -void ffDetectMediaImpl(const FFinstance* instance, FFMediaResult* media) +void ffDetectMediaImpl(FFMediaResult* media) { #ifdef FF_HAVE_DBUS - const char* error = getMedia(instance, media); + const char* error = getMedia(media); ffStrbufAppendS(&media->error, error); #else - FF_UNUSED(instance); ffStrbufAppendS(&media->error, "Fastfetch was compiled without DBus support"); #endif } diff --git a/src/detection/media/media_nosupport.c b/src/detection/media/media_nosupport.c index e3d0381868..b0c19a6529 100644 --- a/src/detection/media/media_nosupport.c +++ b/src/detection/media/media_nosupport.c @@ -1,7 +1,6 @@ #include "media.h" -void ffDetectMediaImpl(const FFinstance* instance, FFMediaResult* media) +void ffDetectMediaImpl(FFMediaResult* media) { - FF_UNUSED(instance); ffStrbufAppendS(&media->error, "Not supported on this platform"); } diff --git a/src/detection/monitor/monitor.h b/src/detection/monitor/monitor.h new file mode 100644 index 0000000000..8314c4cf4b --- /dev/null +++ b/src/detection/monitor/monitor.h @@ -0,0 +1,13 @@ +#include "fastfetch.h" + +typedef struct FFMonitorResult +{ + FFstrbuf name; + uint32_t width; // native / maximum resolution, in pixels + uint32_t height; // native / maximum resolution, in pixels + uint32_t physicalWidth; // in mm + uint32_t physicalHeight; // in mm + bool hdrCompatible; +} FFMonitorResult; + +const char* ffDetectMonitor(FFlist* results); diff --git a/src/detection/monitor/monitor_apple.m b/src/detection/monitor/monitor_apple.m new file mode 100644 index 0000000000..8f931a98d5 --- /dev/null +++ b/src/detection/monitor/monitor_apple.m @@ -0,0 +1,139 @@ +#include "monitor.h" +#include "detection/displayserver/displayserver.h" +#include "util/apple/cf_helpers.h" +#include "util/apple/ddcci.h" +#include "util/edidHelper.h" + +#import +#import + +extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import)); + +static const char* detectWithDisplayServices(const FFDisplayServerResult* displayServer, FFlist* results) +{ + if(!CoreDisplay_DisplayCreateInfoDictionary) return "CoreDisplay_DisplayCreateInfoDictionary is not available"; + + FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays) + { + if (display->type == FF_DISPLAY_TYPE_BUILTIN) + { + CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary((CGDirectDisplayID) display->id); + if(displayInfo) + { + int width, height; + if (ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelWidth"), &width) || // Default resolution (limited by connectors, GPUs, etc.) + ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelHeight"), &height) || + width <= 0 || height <= 0) + continue; + + FFMonitorResult* monitor = (FFMonitorResult*) ffListAdd(results); + monitor->width = (uint32_t) width; + monitor->height = (uint32_t) height; + ffStrbufInitCopy(&monitor->name, &display->name); + + CGSize size = CGDisplayScreenSize((CGDirectDisplayID) display->id); + monitor->physicalWidth = (uint32_t) (size.width + 0.5); + monitor->physicalHeight = (uint32_t) (size.height + 0.5); + monitor->hdrCompatible = false; + + if (CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance"))) + monitor->hdrCompatible = true; + else + { + NSScreen* mainScreen = NSScreen.mainScreen; + if (display->primary) + monitor->hdrCompatible = mainScreen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1; + else + { + for (NSScreen* screen in NSScreen.screens) + { + if (screen == mainScreen) continue; + NSNumber* screenNumber = [screen.deviceDescription valueForKey:@"NSScreenNumber"]; + if (screenNumber && screenNumber.longValue == (long) display->id) + { + monitor->hdrCompatible = screen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1; + break; + } + } + continue; + } + } + } + } + } + return NULL; +} + +static const char* detectWithDdcci(FFlist* results) +{ + if (!IOAVServiceCreate || !IOAVServiceReadI2C) + return "IOAVService is not available"; + + CFMutableDictionaryRef matchDict = IOServiceMatching("DCPAVServiceProxy"); + if (matchDict == NULL) + return "IOServiceMatching(\"DCPAVServiceProxy\") failed"; + + io_iterator_t iterator; + if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess) + return "IOServiceGetMatchingServices() failed"; + + FF_STRBUF_AUTO_DESTROY location = ffStrbufCreate(); + + io_registry_entry_t registryEntry; + while((registryEntry = IOIteratorNext(iterator)) != 0) + { + CFMutableDictionaryRef properties; + if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) + { + IOObjectRelease(registryEntry); + continue; + } + + ffStrbufClear(&location); + if(ffCfDictGetString(properties, CFSTR("Location"), &location) || ffStrbufEqualS(&location, "Embedded")) + { + // Builtin display should be handled by DisplayServices + IOObjectRelease(registryEntry); + continue; + } + + FF_CFTYPE_AUTO_RELEASE IOAVServiceRef service = IOAVServiceCreateWithService(kCFAllocatorDefault, (io_service_t) registryEntry); + IOObjectRelease(registryEntry); + + if (!service) continue; + + FF_CFTYPE_AUTO_RELEASE CFDataRef edid = NULL; + if (IOAVServiceCopyEDID(service, &edid) != KERN_SUCCESS) + continue; + + uint32_t edidLength = (uint32_t) CFDataGetLength(edid); + if (edidLength == 0 || edidLength % 128 != 0) + continue; + + uint32_t width, height; + const uint8_t* edidData = CFDataGetBytePtr(edid); + + ffEdidGetPhysicalResolution(edidData, &width, &height); + if (width == 0 || height == 0) continue; + + FFMonitorResult* display = (FFMonitorResult*) ffListAdd(results); + display->width = width; + display->height = height; + ffStrbufInit(&display->name); + ffEdidGetName(edidData, &display->name); + ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight); + display->hdrCompatible = ffEdidGetHdrCompatible(edidData, edidLength); + } + return NULL; +} + +const char* ffDetectMonitor(FFlist* results) +{ + const FFDisplayServerResult* displayServer = ffConnectDisplayServer(); + + detectWithDisplayServices(displayServer, results); + + if (displayServer->displays.length > results->length) + detectWithDdcci(results); + return NULL; +} diff --git a/src/detection/monitor/monitor_linux.c b/src/detection/monitor/monitor_linux.c new file mode 100644 index 0000000000..a04276412e --- /dev/null +++ b/src/detection/monitor/monitor_linux.c @@ -0,0 +1,65 @@ +#include "monitor.h" + +#include "common/io/io.h" +#include "util/edidHelper.h" +#include "util/stringUtils.h" +#include "util/mallocHelper.h" + +#include +#include + +const char* ffDetectMonitor(FFlist* results) +{ + const char* drmDirPath = "/sys/class/drm/"; + + DIR* dirp = opendir(drmDirPath); + if(dirp == NULL) + return "opendir(drmDirPath) == NULL"; + + FF_STRBUF_AUTO_DESTROY drmDir = ffStrbufCreateA(64); + ffStrbufAppendS(&drmDir, drmDirPath); + + uint32_t drmDirLength = drmDir.length; + + struct dirent* entry; + while((entry = readdir(dirp)) != NULL) + { + if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, "..")) + continue; + + ffStrbufAppendS(&drmDir, entry->d_name); + ffStrbufAppendS(&drmDir, "/edid"); + + struct stat fileStat; + if (stat(drmDir.chars, &fileStat) < 0 || fileStat.st_size == 0 || fileStat.st_size % 128 != 0) + { + ffStrbufSubstrBefore(&drmDir, drmDirLength); + continue; + } + + FF_AUTO_FREE uint8_t* edidData = malloc((size_t) fileStat.st_size); + if(ffReadFileData(drmDir.chars, sizeof(edidData), edidData) != sizeof(edidData)) + { + ffStrbufSubstrBefore(&drmDir, drmDirLength); + continue; + } + + uint32_t width, height; + ffEdidGetPhysicalResolution(edidData, &width, &height); + if (width != 0 && height != 0) + { + FFMonitorResult* display = (FFMonitorResult*) ffListAdd(results); + display->width = width; + display->height = height; + ffStrbufInit(&display->name); + ffEdidGetName(edidData, &display->name); + ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight); + display->hdrCompatible = ffEdidGetHdrCompatible(edidData, (uint32_t) fileStat.st_size); + } + + ffStrbufSubstrBefore(&drmDir, drmDirLength); + } + + closedir(dirp); + return NULL; +} diff --git a/src/detection/monitor/monitor_nosupport.c b/src/detection/monitor/monitor_nosupport.c new file mode 100644 index 0000000000..c5bd0547a9 --- /dev/null +++ b/src/detection/monitor/monitor_nosupport.c @@ -0,0 +1,6 @@ +#include "monitor.h" + +const char* ffDetectMonitor(FF_MAYBE_UNUSED FFlist* results) +{ + return "Not supported on this platform"; +} diff --git a/src/detection/monitor/monitor_windows.c b/src/detection/monitor/monitor_windows.c new file mode 100644 index 0000000000..f56c5a188f --- /dev/null +++ b/src/detection/monitor/monitor_windows.c @@ -0,0 +1,53 @@ +#include "monitor.h" + +#include "common/io/io.h" +#include "util/edidHelper.h" +#include "util/mallocHelper.h" +#include "util/stringUtils.h" +#include "util/windows/registry.h" +#include "util/windows/unicode.h" + +#include +#include +#include + +static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev) +{ + if(*hdev) + SetupDiDestroyDeviceInfoList(*hdev); +} + +const char* ffDetectMonitor(FFlist* results) +{ + //https://learn.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices + HDEVINFO hdev __attribute__((__cleanup__(wrapSetupDiDestroyDeviceInfoList))) = + SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR, 0, 0, DIGCF_PRESENT); + if(hdev == INVALID_HANDLE_VALUE) + return "SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR) failed"; + + SP_DEVINFO_DATA did = { .cbSize = sizeof(did) }; + for (DWORD idev = 0; SetupDiEnumDeviceInfo(hdev, idev, &did); ++idev) + { + FF_HKEY_AUTO_DESTROY hKey = SetupDiOpenDevRegKey(hdev, &did, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); + if (!hKey) continue; + + FF_AUTO_FREE uint8_t* edidData = NULL; + uint32_t edidLength = 0; + if (!ffRegReadData(hKey, L"EDID", &edidData, &edidLength, NULL)) continue; + if (edidLength == 0 || edidLength % 128 != 0) + continue; + + uint32_t width, height; + ffEdidGetPhysicalResolution(edidData, &width, &height); + if (width == 0 || height == 0) continue; + + FFMonitorResult* display = (FFMonitorResult*) ffListAdd(results); + display->width = width; + display->height = height; + display->hdrCompatible = ffEdidGetHdrCompatible(edidData, edidLength); // Doesn't work. edidLength is always 128 + ffStrbufInit(&display->name); + ffEdidGetName(edidData, &display->name); + ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight); + } + return NULL; +} diff --git a/src/detection/opencl/opencl.c b/src/detection/opencl/opencl.c index 6eb2791d8e..d8cb4a66b4 100644 --- a/src/detection/opencl/opencl.c +++ b/src/detection/opencl/opencl.c @@ -46,9 +46,8 @@ static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result) return "clGetDeviceInfo returned NULL or empty string"; const char* versionPretty = version; - const char* prefix = "OpenCL "; - if(strncasecmp(version, prefix, sizeof(prefix) - 1) == 0) - versionPretty = version + sizeof(prefix) - 1; + if(ffStrStartsWithIgnCase(version, "OpenCL ")) + versionPretty = version + strlen("OpenCL "); ffStrbufSetS(&result->version, versionPretty); ffStrbufEnsureFree(&result->device, 128); @@ -64,13 +63,13 @@ static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result) #endif // defined(FF_HAVE_OPENCL) || defined(__APPLE__) -const char* ffDetectOpenCL(FFinstance* instance, FFOpenCLResult* result) +const char* ffDetectOpenCL(FFOpenCLResult* result) { #ifdef FF_HAVE_OPENCL OpenCLData data; - FF_LIBRARY_LOAD(opencl, &instance->config.libOpenCL, "dlopen libOpenCL"FF_LIBRARY_EXTENSION" failed", + FF_LIBRARY_LOAD(opencl, &instance.config.libOpenCL, "dlopen libOpenCL"FF_LIBRARY_EXTENSION" failed", #ifdef _WIN32 "OpenCL"FF_LIBRARY_EXTENSION, -1, #endif @@ -84,8 +83,6 @@ const char* ffDetectOpenCL(FFinstance* instance, FFOpenCLResult* result) #elif defined(__APPLE__) // FF_HAVE_OPENCL - FF_UNUSED(instance); - OpenCLData data; data.ffclGetPlatformIDs = clGetPlatformIDs; data.ffclGetDeviceIDs = clGetDeviceIDs; @@ -95,7 +92,7 @@ const char* ffDetectOpenCL(FFinstance* instance, FFOpenCLResult* result) #else - FF_UNUSED(instance, result); + FF_UNUSED(result); return "Fastfetch was build without OpenCL support"; #endif // FF_HAVE_OPENCL diff --git a/src/detection/opencl/opencl.h b/src/detection/opencl/opencl.h index 93cceecc8c..56a96c98f6 100644 --- a/src/detection/opencl/opencl.h +++ b/src/detection/opencl/opencl.h @@ -12,6 +12,6 @@ typedef struct FFOpenCLResult FFstrbuf vendor; } FFOpenCLResult; -const char* ffDetectOpenCL(FFinstance* instance, FFOpenCLResult* result); +const char* ffDetectOpenCL(FFOpenCLResult* result); #endif diff --git a/src/detection/opengl/opengl.h b/src/detection/opengl/opengl.h index 2063471846..b4426856bb 100644 --- a/src/detection/opengl/opengl.h +++ b/src/detection/opengl/opengl.h @@ -13,6 +13,6 @@ typedef struct FFOpenGLResult FFstrbuf slv; } FFOpenGLResult; -const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result); +const char* ffDetectOpenGL(FFOpenGLResult* result); #endif diff --git a/src/detection/opengl/opengl_apple.c b/src/detection/opengl/opengl_apple.c index 4ccbb5fe63..b6f4fe2572 100644 --- a/src/detection/opengl/opengl_apple.c +++ b/src/detection/opengl/opengl_apple.c @@ -35,10 +35,8 @@ static const char* cglHandlePixelFormat(FFOpenGLResult* result, CGLPixelFormatOb return error; } -const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result) +const char* ffDetectOpenGL(FFOpenGLResult* result) { - FF_UNUSED(instance); - CGLPixelFormatObj pixelFormat; CGLPixelFormatAttribute attrs[] = { kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core, diff --git a/src/detection/opengl/opengl_linux.c b/src/detection/opengl/opengl_linux.c index a959578f86..43378be636 100644 --- a/src/detection/opengl/opengl_linux.c +++ b/src/detection/opengl/opengl_linux.c @@ -30,6 +30,8 @@ static const char* glHandleResult(FFOpenGLResult* result, const GLData* data) #endif // FF_HAVE_GL #ifdef FF_HAVE_EGL +#include "common/io/io.h" + #include typedef struct EGLData @@ -116,11 +118,11 @@ static const char* eglHandleData(FFOpenGLResult* result, EGLData* data) return error; } -static const char* eglPrint(FFinstance* instance, FFOpenGLResult* result) +static const char* eglPrint(FFOpenGLResult* result) { EGLData eglData; - FF_LIBRARY_LOAD(egl, &instance->config.libEGL, "dlopen egl failed", "libEGL" FF_LIBRARY_EXTENSION, 1); + FF_LIBRARY_LOAD(egl, &instance.config.libEGL, "dlopen egl failed", "libEGL" FF_LIBRARY_EXTENSION, 1); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetProcAddress); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetDisplay); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglInitialize); @@ -133,6 +135,7 @@ static const char* eglPrint(FFinstance* instance, FFOpenGLResult* result) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglDestroySurface); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglTerminate); + FF_SUPPRESS_IO(); return eglHandleData(result, &eglData); } @@ -232,11 +235,11 @@ static const char* glxHandleData(FFOpenGLResult* result, GLXData* data) return error; } -static const char* glxPrint(FFinstance* instance, FFOpenGLResult* result) +static const char* glxPrint(FFOpenGLResult* result) { GLXData data; - FF_LIBRARY_LOAD(glx, &instance->config.libGLX, "dlopen glx failed", "libGLX" FF_LIBRARY_EXTENSION, 1); + FF_LIBRARY_LOAD(glx, &instance.config.libGLX, "dlopen glx failed", "libGLX" FF_LIBRARY_EXTENSION, 1); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXGetProcAddress); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XOpenDisplay); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXChooseVisual); @@ -296,11 +299,11 @@ static const char* osMesaHandleData(FFOpenGLResult* result, OSMesaData* data) return error; } -static const char* osMesaPrint(FFinstance* instance, FFOpenGLResult* result) +static const char* osMesaPrint(FFOpenGLResult* result) { OSMesaData data; - FF_LIBRARY_LOAD(osmesa, &instance->config.libOSMesa, "dlopen osmesa failed", "libOSMesa" FF_LIBRARY_EXTENSION, 8); + FF_LIBRARY_LOAD(osmesa, &instance.config.libOSMesa, "dlopen osmesa failed", "libOSMesa" FF_LIBRARY_EXTENSION, 8); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaGetProcAddress); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaCreateContext); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaMakeCurrent); @@ -311,32 +314,32 @@ static const char* osMesaPrint(FFinstance* instance, FFOpenGLResult* result) #endif //FF_HAVE_OSMESA -const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result) +const char* ffDetectOpenGL(FFOpenGLResult* result) { #if FF_HAVE_GL - if(instance->config.glType == FF_GL_TYPE_GLX) + if(instance.config.openGL.library == FF_OPENGL_LIBRARY_GLX) { #ifdef FF_HAVE_GLX - return glxPrint(instance, result); + return glxPrint(result); #else return "fastfetch was compiled without glx support"; #endif } - if(instance->config.glType == FF_GL_TYPE_EGL) + if(instance.config.openGL.library == FF_OPENGL_LIBRARY_EGL) { #ifdef FF_HAVE_EGL - return eglPrint(instance, result); + return eglPrint(result); #else return "fastfetch was compiled without egl support"; #endif } - if(instance->config.glType == FF_GL_TYPE_OSMESA) + if(instance.config.openGL.library == FF_OPENGL_LIBRARY_OSMESA) { #ifdef FF_HAVE_OSMESA - return osMesaPrint(instance, result); + return osMesaPrint(result); #else return "fastfetch was compiled without osmesa support"; #endif @@ -345,12 +348,12 @@ const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result) const char* error = ""; // not NULL dummy value #ifdef FF_HAVE_EGL - error = eglPrint(instance, result); + error = eglPrint(result); #endif #ifdef FF_HAVE_GLX if(error != NULL) - error = glxPrint(instance, result); + error = glxPrint(result); #endif //We don't use osmesa in auto mode here, because it is a software implementation, @@ -360,7 +363,7 @@ const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result) #else - FF_UNUSED(instance, result); + FF_UNUSED(result); return "Fastfetch was built without gl support."; #endif //FF_HAVE_GL diff --git a/src/detection/opengl/opengl_windows.c b/src/detection/opengl/opengl_windows.c index a3865e550d..11d608db5d 100644 --- a/src/detection/opengl/opengl_windows.c +++ b/src/detection/opengl/opengl_windows.c @@ -82,10 +82,8 @@ LRESULT CALLBACK wglHandleWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM } } -const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result) +const char* ffDetectOpenGL(FFOpenGLResult* result) { - FF_UNUSED(instance); - MSG msg = {0}; WNDCLASSW wc = { .lpfnWndProc = wglHandleWndProc, diff --git a/src/detection/os/os.c b/src/detection/os/os.c index dee22a566f..c09935954e 100644 --- a/src/detection/os/os.c +++ b/src/detection/os/os.c @@ -1,11 +1,11 @@ #include "os.h" #include "detection/internal.h" -void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance); +void ffDetectOSImpl(FFOSResult* os); -const FFOSResult* ffDetectOS(const FFinstance* instance) +const FFOSResult* ffDetectOS(void) { FF_DETECTION_INTERNAL_GUARD(FFOSResult, - ffDetectOSImpl(&result, instance) + ffDetectOSImpl(&result) ); } diff --git a/src/detection/os/os.h b/src/detection/os/os.h index 80fb6b2af5..87af406a98 100644 --- a/src/detection/os/os.h +++ b/src/detection/os/os.h @@ -19,6 +19,6 @@ typedef struct FFOSResult FFstrbuf buildID; } FFOSResult; -const FFOSResult* ffDetectOS(const FFinstance* instance); +const FFOSResult* ffDetectOS(); #endif diff --git a/src/detection/os/os_android.c b/src/detection/os/os_android.c index 890486ab72..1877aadfba 100644 --- a/src/detection/os/os_android.c +++ b/src/detection/os/os_android.c @@ -1,15 +1,13 @@ #include "os.h" #include "common/settings.h" -void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) +void ffDetectOSImpl(FFOSResult* os) { - FF_UNUSED(instance); + ffStrbufInitStatic(&os->name, "Android"); - ffStrbufInitS(&os->name, "Android"); + ffStrbufInitStatic(&os->prettyName, "Android"); - ffStrbufInitS(&os->prettyName, "Android"); - - ffStrbufInitS(&os->id, "android"); + ffStrbufInitStatic(&os->id, "android"); ffStrbufInit(&os->version); ffSettingsGetAndroidProperty("ro.build.version.release", &os->version); diff --git a/src/detection/os/os_apple.m b/src/detection/os/os_apple.m index 49a387d428..98e639bad6 100644 --- a/src/detection/os/os_apple.m +++ b/src/detection/os/os_apple.m @@ -1,5 +1,6 @@ #include "os.h" #include "common/sysctl.h" +#include "util/stringUtils.h" #include #include @@ -78,12 +79,11 @@ static void parseOSXSoftwareLicense(FFOSResult* os) char* line = NULL; size_t len = 0; const char* searchStr = "\\f0\\b SOFTWARE LICENSE AGREEMENT FOR macOS "; - const size_t searchLen = strlen(searchStr); while(getline(&line, &len, rtf) != EOF) { - if (strncmp(line, searchStr, searchLen) == 0) + if (ffStrStartsWith(line, searchStr)) { - ffStrbufAppendS(&os->codename, line + searchLen); + ffStrbufAppendS(&os->codename, line + strlen(searchStr)); ffStrbufTrimRight(&os->codename, '\n'); ffStrbufTrimRight(&os->codename, '\\'); break; @@ -96,10 +96,8 @@ static void parseOSXSoftwareLicense(FFOSResult* os) fclose(rtf); } -void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) +void ffDetectOSImpl(FFOSResult* os) { - FF_UNUSED(instance); - ffStrbufInit(&os->name); ffStrbufInit(&os->version); ffStrbufInit(&os->buildID); @@ -107,10 +105,10 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufInit(&os->prettyName); ffStrbufInit(&os->versionID); - ffStrbufInitA(&os->codename, 0); - ffStrbufInitA(&os->idLike, 0); - ffStrbufInitA(&os->variant, 0); - ffStrbufInitA(&os->variantID, 0); + ffStrbufInit(&os->codename); + ffStrbufInit(&os->idLike); + ffStrbufInit(&os->variant); + ffStrbufInit(&os->variantID); parseSystemVersion(os); diff --git a/src/detection/os/os_linux.c b/src/detection/os/os_linux.c index 063e8455bb..338a1fcfb1 100644 --- a/src/detection/os/os_linux.c +++ b/src/detection/os/os_linux.c @@ -75,6 +75,15 @@ static void getUbuntuFlavour(FFOSResult* result) return; } + if(strstr(xdgConfigDirs, "cinnamon") != NULL) + { + ffStrbufSetS(&result->name, "Ubuntu Cinnamon"); + ffStrbufSetS(&result->prettyName, "Ubuntu Cinnamon"); + ffStrbufSetS(&result->id, "ubuntu-cinnamon"); + ffStrbufSetS(&result->idLike, "ubuntu"); + return; + } + if(strstr(xdgConfigDirs, "mate") != NULL) { ffStrbufSetS(&result->name, "Ubuntu MATE"); @@ -92,17 +101,35 @@ static void getUbuntuFlavour(FFOSResult* result) ffStrbufSetS(&result->idLike, "ubuntu"); return; } + + if(strstr(xdgConfigDirs, "sway") != NULL) + { + ffStrbufSetS(&result->name, "Ubuntu Sway"); + ffStrbufSetS(&result->prettyName, "Ubuntu Sway"); + ffStrbufSetS(&result->id, "ubuntu-sway"); + ffStrbufSetS(&result->idLike, "ubuntu"); + return; + } + + if(strstr(xdgConfigDirs, "touch") != NULL) + { + ffStrbufSetS(&result->name, "Ubuntu Touch"); + ffStrbufSetS(&result->prettyName, "Ubuntu Touch"); + ffStrbufSetS(&result->id, "ubuntu-touch"); + ffStrbufSetS(&result->idLike, "ubuntu"); + return; + } } -static void detectOS(FFOSResult* os, const FFinstance* instance) +static void detectOS(FFOSResult* os) { - if(instance->config.osFile.length > 0) + if(instance.config.osFile.length > 0) { - parseFile(instance->config.osFile.chars, os); + parseFile(instance.config.osFile.chars, os); return; } - if(instance->config.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock"FASTFETCH_TARGET_DIR_ETC"/bedrock-release", os)) + if(instance.config.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock"FASTFETCH_TARGET_DIR_ETC"/bedrock-release", os)) { if(os->id.length == 0) ffStrbufAppendS(&os->id, "bedrock"); @@ -127,7 +154,7 @@ static void detectOS(FFOSResult* os, const FFinstance* instance) parseFile(FASTFETCH_TARGET_DIR_ETC"/lsb-release", os); } -void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) +void ffDetectOSImpl(FFOSResult* os) { ffStrbufInit(&os->name); ffStrbufInit(&os->prettyName); @@ -140,7 +167,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufInit(&os->codename); ffStrbufInit(&os->buildID); - detectOS(os, instance); + detectOS(os); if(ffStrbufIgnCaseCompS(&os->id, "ubuntu") == 0) getUbuntuFlavour(os); diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index 2b18f198d4..935f86153b 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -1,8 +1,8 @@ extern "C" { #include "os.h" #include "common/library.h" -#include "util/windows/unicode.h" } +#include "util/windows/unicode.hpp" #include "util/windows/wmi.hpp" static const char* getOsNameByWmi(FFstrbuf* osName) @@ -13,9 +13,13 @@ static const char* getOsNameByWmi(FFstrbuf* osName) if(FFWmiRecord record = query.next()) { - record.getString(L"Caption", osName); - ffStrbufTrimRight(osName, ' '); - return NULL; + if(auto vtCaption = record.get(L"Caption")) + { + ffStrbufSetWSV(osName, vtCaption.get()); + ffStrbufTrimRight(osName, ' '); + return NULL; + } + return "Get Caption failed"; } return "No WMI result returned"; @@ -30,16 +34,14 @@ static const char* getOsNameByWinbrand(FFstrbuf* osName) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(winbrand, BrandingFormatString); const wchar_t* rawName = ffBrandingFormatString(L"%WINDOWS_LONG%"); - ffStrbufSetWS(osName, rawName); - GlobalFree((HGLOBAL)rawName); - return NULL; + ffStrbufSetWS(osName, rawName); + GlobalFree((HGLOBAL)rawName); + return NULL; } extern "C" -void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) +void ffDetectOSImpl(FFOSResult* os) { - FF_UNUSED(instance); - ffStrbufInit(&os->name); ffStrbufInit(&os->prettyName); ffStrbufInit(&os->id); diff --git a/src/detection/packages/packages.c b/src/detection/packages/packages.c index 2404f74e33..ce7c778c3d 100644 --- a/src/detection/packages/packages.c +++ b/src/detection/packages/packages.c @@ -3,17 +3,17 @@ #include -void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result); +void ffDetectPackagesImpl(FFPackagesResult* result); -const FFPackagesResult* ffDetectPackages(const FFinstance* instance) +const char* ffDetectPackages(FFPackagesResult* result) { - FF_DETECTION_INTERNAL_GUARD(FFPackagesResult, - memset(&result, 0, sizeof(FFPackagesResult)); - ffStrbufInit(&result.pacmanBranch); + ffDetectPackagesImpl(result); - ffDetectPackagesImpl(instance, &result); + for(uint32_t i = 0; i < offsetof(FFPackagesResult, all) / sizeof(uint32_t); ++i) + result->all += ((uint32_t *)result)[i]; - for(uint32_t i = 0; i < offsetof(FFPackagesResult, all) / sizeof(uint32_t); ++i) - result.all += ((uint32_t *)&result)[i]; - ); + if (result->all == 0) + return "No packages from known package managers found"; + + return NULL; } diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index 9b6206574f..77f8e68121 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -20,6 +20,7 @@ typedef struct FFPackagesResult uint32_t nixSystem; uint32_t nixUser; uint32_t pacman; + uint32_t paludis; uint32_t pkg; uint32_t pkgtool; uint32_t port; @@ -33,6 +34,6 @@ typedef struct FFPackagesResult FFstrbuf pacmanBranch; } FFPackagesResult; -const FFPackagesResult* ffDetectPackages(const FFinstance* instance); +const char* ffDetectPackages(FFPackagesResult* result); #endif diff --git a/src/detection/packages/packages_apple.c b/src/detection/packages/packages_apple.c index eaaf5f2fa0..97e858fbe4 100644 --- a/src/detection/packages/packages_apple.c +++ b/src/detection/packages/packages_apple.c @@ -28,8 +28,7 @@ static uint32_t getNumElements(const char* dirname, unsigned char type) static void countBrewPackages(const char* dirname, FFPackagesResult* result) { - FF_STRBUF_AUTO_DESTROY baseDir; - ffStrbufInitS(&baseDir, dirname); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS(dirname); uint32_t baseDirLength = baseDir.length; @@ -54,8 +53,7 @@ static void getBrewPackages(FFPackagesResult* result) static uint32_t countMacPortsPackages(const char* dirname) { - FF_STRBUF_AUTO_DESTROY baseDir; - ffStrbufInitS(&baseDir, dirname); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS(dirname); ffStrbufAppendS(&baseDir, "/var/macports/software"); return getNumElements(baseDir.chars, DT_DIR); @@ -70,9 +68,8 @@ static uint32_t getMacPortsPackages() return countMacPortsPackages(FASTFETCH_TARGET_DIR_ROOT"/opt/local"); } -void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) +void ffDetectPackagesImpl(FFPackagesResult* result) { - FF_UNUSED(instance); getBrewPackages(result); result->port = getMacPortsPackages(); } diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index 60ea05de33..7dd4061b4a 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -5,6 +5,7 @@ #include "common/properties.h" #include "common/settings.h" #include "detection/os/os.h" +#include "util/stringUtils.h" #include @@ -73,11 +74,11 @@ static uint32_t getNumStrings(FFstrbuf* baseDir, const char* filename, const cha return num_elements; } -static uint32_t getSQLite3Int(const FFinstance* instance, FFstrbuf* baseDir, const char* dbPath, const char* query) +static uint32_t getSQLite3Int(FFstrbuf* baseDir, const char* dbPath, const char* query) { uint32_t baseDirLength = baseDir->length; ffStrbufAppendS(baseDir, dbPath); - uint32_t num_elements = (uint32_t) ffSettingsGetSQLite3Int(instance, baseDir->chars, query); + uint32_t num_elements = (uint32_t) ffSettingsGetSQLite3Int(baseDir->chars, query); ffStrbufSubstrBefore(baseDir, baseDirLength); return num_elements; } @@ -132,12 +133,10 @@ static uint32_t getNixPackagesImpl(char* path) if(!ffPathExists(path, FF_PATHTYPE_DIRECTORY)) return 0; - FFstrbuf output; - ffStrbufInitA(&output, 128); + FF_STRBUF_AUTO_DESTROY output = ffStrbufCreateA(128); //https://github.com/fastfetch-cli/fastfetch/issues/195#issuecomment-1191748222 - FFstrbuf command; - ffStrbufInitA(&command, 255); + FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(255); ffStrbufAppendS(&command, "for x in $(nix-store --query --requisites "); ffStrbufAppendS(&command, path); ffStrbufAppendS(&command, "); do if [ -d $x ]; then echo $x ; fi ; done | cut -d- -f2- | egrep '([0-9]{1,}\\.)+[0-9]{1,}' | egrep -v '\\-doc$|\\-man$|\\-info$|\\-dev$|\\-bin$|^nixos-system-nixos-' | uniq | wc -l"); @@ -149,12 +148,7 @@ static uint32_t getNixPackagesImpl(char* path) NULL }); - int result = (int) strtol(output.chars, NULL, 10); - - ffStrbufDestroy(&command); - ffStrbufDestroy(&output); - - return (uint32_t) result; + return (uint32_t) strtol(output.chars, NULL, 10); } static uint32_t getNixPackages(FFstrbuf* baseDir, const char* dirname) @@ -177,7 +171,7 @@ static uint32_t getXBPSImpl(FFstrbuf* baseDir) struct dirent *entry; while((entry = readdir(dir)) != NULL) { - if(entry->d_type != DT_REG || strncasecmp(entry->d_name, "pkgdb-", 6) != 0) + if(entry->d_type != DT_REG || !ffStrStartsWithIgnCase(entry->d_name, "pkgdb-")) continue; ffStrbufAppendC(baseDir, '/'); @@ -227,9 +221,9 @@ static uint32_t getFlatpak(FFstrbuf* baseDir, const char* dirname) #include #include -static uint32_t getRpmFromLibrpm(const FFinstance* instance) +static uint32_t getRpmFromLibrpm(void) { - FF_LIBRARY_LOAD(rpm, &instance->config.librpm, 0, "librpm" FF_LIBRARY_EXTENSION, 12) + FF_LIBRARY_LOAD(rpm, &instance.config.librpm, 0, "librpm" FF_LIBRARY_EXTENSION, 12) FF_LIBRARY_LOAD_SYMBOL(rpm, rpmReadConfigFiles, 0) FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsCreate, 0) FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsInitIterator, 0) @@ -265,7 +259,7 @@ static uint32_t getRpmFromLibrpm(const FFinstance* instance) #endif //FF_HAVE_RPM -static void getPackageCounts(const FFinstance* instance, FFstrbuf* baseDir, FFPackagesResult* packageCounts) +static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts) { packageCounts->apk += getNumStrings(baseDir, "/lib/apk/db/installed", "C:Q"); packageCounts->dpkg += getNumStrings(baseDir, "/var/lib/dpkg/status", "Status: "); @@ -275,18 +269,19 @@ static void getPackageCounts(const FFinstance* instance, FFstrbuf* baseDir, FFPa packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default"); packageCounts->nixSystem += getNixPackages(baseDir, "/run/current-system"); packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", DT_DIR); - packageCounts->pkg += getSQLite3Int(instance, baseDir, "/var/db/pkg/local.sqlite", "SELECT count(id) FROM packages"); + packageCounts->pkg += getSQLite3Int(baseDir, "/var/db/pkg/local.sqlite", "SELECT count(id) FROM packages"); packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", DT_REG); - packageCounts->rpm += getSQLite3Int(instance, baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(blob) FROM Packages"); + packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(blob) FROM Packages"); packageCounts->snap += getSnap(baseDir); packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps"); packageCounts->brewCask += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Caskroom", DT_DIR); packageCounts->brew += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Cellar", DT_DIR); + packageCounts->paludis += countFilesRecursive(baseDir, "/var/db/paludis/repositories", "environment.bz2"); } -static void getPackageCountsRegular(const FFinstance* instance, FFstrbuf* baseDir, FFPackagesResult* packageCounts) +static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* packageCounts) { - getPackageCounts(instance, baseDir, packageCounts); + getPackageCounts(baseDir, packageCounts); uint32_t baseDirLength = baseDir->length; ffStrbufAppendS(baseDir, FASTFETCH_TARGET_DIR_ETC"/pacman-mirrors.conf"); @@ -295,7 +290,7 @@ static void getPackageCountsRegular(const FFinstance* instance, FFstrbuf* baseDi ffStrbufSubstrBefore(baseDir, baseDirLength); } -static void getPackageCountsBedrock(const FFinstance* instance, FFstrbuf* baseDir, FFPackagesResult* packageCounts) +static void getPackageCountsBedrock(FFstrbuf* baseDir, FFPackagesResult* packageCounts) { uint32_t baseDirLength = baseDir->length; @@ -316,11 +311,11 @@ static void getPackageCountsBedrock(const FFinstance* instance, FFstrbuf* baseDi { if(entry->d_type != DT_DIR) continue; - if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, "..")) continue; ffStrbufAppendS(baseDir, entry->d_name); - getPackageCounts(instance, baseDir, packageCounts); + getPackageCounts(baseDir, packageCounts); ffStrbufSubstrBefore(baseDir, baseDirLength2); } @@ -328,26 +323,25 @@ static void getPackageCountsBedrock(const FFinstance* instance, FFstrbuf* baseDi ffStrbufSubstrBefore(baseDir, baseDirLength); } -void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) +void ffDetectPackagesImpl(FFPackagesResult* result) { - FF_STRBUF_AUTO_DESTROY baseDir; - ffStrbufInitA(&baseDir, 512); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(512); ffStrbufAppendS(&baseDir, FASTFETCH_TARGET_DIR_ROOT); - if(ffStrbufIgnCaseEqualS(&ffDetectOS(instance)->id, "bedrock")) - getPackageCountsBedrock(instance, &baseDir, result); + if(ffStrbufIgnCaseEqualS(&ffDetectOS()->id, "bedrock")) + getPackageCountsBedrock(&baseDir, result); else - getPackageCountsRegular(instance, &baseDir, result); + getPackageCountsRegular(&baseDir, result); // If SQL failed, we can still try with librpm. // This is needed on openSUSE, which seems to use a proprietary database file // This method doesn't work on bedrock, so we do it here. #ifdef FF_HAVE_RPM if(result->rpm == 0) - result->rpm = getRpmFromLibrpm(instance); + result->rpm = getRpmFromLibrpm(); #endif - ffStrbufSet(&baseDir, &instance->state.platform.homeDir); + ffStrbufSet(&baseDir, &instance.state.platform.homeDir); result->nixUser = getNixPackages(&baseDir, "/.nix-profile"); result->flatpakUser = getFlatpak(&baseDir, "/.local/share/flatpak"); } diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index 086a10ea1e..5b5343f793 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -32,10 +32,9 @@ static uint32_t getNumElements(const char* searchPath /* including `\*` suffix * return counter; } -static void detectScoop(const FFinstance* instance, FFPackagesResult* result) +static void detectScoop(FFPackagesResult* result) { - FF_STRBUF_AUTO_DESTROY scoopPath; - ffStrbufInitA(&scoopPath, MAX_PATH + 3); + FF_STRBUF_AUTO_DESTROY scoopPath = ffStrbufCreateA(MAX_PATH + 3); const char* scoopEnv = getenv("SCOOP"); if(ffStrSet(scoopEnv)) @@ -45,13 +44,13 @@ static void detectScoop(const FFinstance* instance, FFPackagesResult* result) } else { - ffStrbufAppendS(&scoopPath, instance->state.platform.homeDir.chars); + ffStrbufAppendS(&scoopPath, instance.state.platform.homeDir.chars); ffStrbufAppendS(&scoopPath, "/scoop/apps/*"); } result->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY, "scoop"); } -static void detectChoco(FF_MAYBE_UNUSED const FFinstance* instance, FFPackagesResult* result) +static void detectChoco(FF_MAYBE_UNUSED FFPackagesResult* result) { const char* chocoInstall = getenv("ChocolateyInstall"); if(!chocoInstall || chocoInstall[0] == '\0') @@ -63,7 +62,7 @@ static void detectChoco(FF_MAYBE_UNUSED const FFinstance* instance, FFPackagesRe result->choco = getNumElements(chocoPath, FILE_ATTRIBUTE_DIRECTORY, "choco"); } -static void detectPacman(FF_MAYBE_UNUSED const FFinstance* instance, FFPackagesResult* result) +static void detectPacman(FF_MAYBE_UNUSED FFPackagesResult* result) { const char* msystemPrefix = getenv("MSYSTEM_PREFIX"); if(!msystemPrefix) @@ -76,9 +75,9 @@ static void detectPacman(FF_MAYBE_UNUSED const FFinstance* instance, FFPackagesR result->pacman = getNumElements(pacmanPath, FILE_ATTRIBUTE_DIRECTORY, NULL); } -void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) +void ffDetectPackagesImpl(FFPackagesResult* result) { - detectScoop(instance, result); - detectChoco(instance, result); - detectPacman(instance, result); + detectScoop(result); + detectChoco(result); + detectPacman(result); } diff --git a/src/detection/poweradapter/poweradapter.h b/src/detection/poweradapter/poweradapter.h index c7f5ee7dc2..9abdd48ecf 100644 --- a/src/detection/poweradapter/poweradapter.h +++ b/src/detection/poweradapter/poweradapter.h @@ -14,9 +14,9 @@ typedef struct PowerAdapterResult int watts; } PowerAdapterResult; -const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results); +const char* ffDetectPowerAdapterImpl(FFlist* results); -#define FF_POWER_ADAPTER_UNSET -2 -#define FF_POWER_ADAPTER_NOT_CONNECTED -1 +#define FF_POWERADAPTER_UNSET -2 +#define FF_POWERADAPTER_NOT_CONNECTED -1 #endif diff --git a/src/detection/poweradapter/poweradapter_apple.c b/src/detection/poweradapter/poweradapter_apple.c index c14ff8c4e9..de3025a40b 100644 --- a/src/detection/poweradapter/poweradapter_apple.c +++ b/src/detection/poweradapter/poweradapter_apple.c @@ -4,10 +4,8 @@ #include -const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results) +const char* ffDetectPowerAdapterImpl(FFlist* results) { - FF_UNUSED(instance); - CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery"); if (matchDict == NULL) return "IOServiceMatching(\"AppleSmartBattery\") failed"; @@ -32,14 +30,14 @@ const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results) ffStrbufInit(&adapter->description); ffStrbufInit(&adapter->manufacturer); ffStrbufInit(&adapter->modelName); - adapter->watts = FF_POWER_ADAPTER_UNSET; + adapter->watts = FF_POWERADAPTER_UNSET; CFDictionaryRef adapterDict; if(!ffCfDictGetDict(properties, CFSTR("AdapterDetails"), &adapterDict)) { if (ffCfDictGetInt(adapterDict, CFSTR("Watts"), &adapter->watts)) { - adapter->watts = FF_POWER_ADAPTER_NOT_CONNECTED; + adapter->watts = FF_POWERADAPTER_NOT_CONNECTED; continue; } ffCfDictGetString(adapterDict, CFSTR("Name"), &adapter->name); diff --git a/src/detection/poweradapter/poweradapter_nosupport.c b/src/detection/poweradapter/poweradapter_nosupport.c index cf6d1c841f..80730810df 100644 --- a/src/detection/poweradapter/poweradapter_nosupport.c +++ b/src/detection/poweradapter/poweradapter_nosupport.c @@ -1,7 +1,7 @@ #include "fastfetch.h" -const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results) +const char* ffDetectPowerAdapterImpl(FFlist* results) { - FF_UNUSED(instance, results); + FF_UNUSED(results); return "Not supported on this platform"; } diff --git a/src/detection/sound/sound.h b/src/detection/sound/sound.h index 7603110f60..350a4f3e6c 100644 --- a/src/detection/sound/sound.h +++ b/src/detection/sound/sound.h @@ -16,6 +16,6 @@ typedef struct FFSoundDevice bool active; } FFSoundDevice; -const char* ffDetectSound(const FFinstance* instance, FFlist* devices /* List of FFSoundDevice */); +const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */); #endif diff --git a/src/detection/sound/sound_apple.c b/src/detection/sound/sound_apple.c index 862ee523a4..8f23f2a3aa 100644 --- a/src/detection/sound/sound_apple.c +++ b/src/detection/sound/sound_apple.c @@ -8,7 +8,7 @@ #define kAudioObjectPropertyElementMain kAudioObjectPropertyElementMaster #endif -const char* ffDetectSound(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* devices /* List of FFSoundDevice */) +const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */) { AudioDeviceID mainDeviceId; UInt32 dataSize = sizeof(mainDeviceId); diff --git a/src/detection/sound/sound_linux.c b/src/detection/sound/sound_linux.c index bba07c13be..8f14ab49e1 100644 --- a/src/detection/sound/sound_linux.c +++ b/src/detection/sound/sound_linux.c @@ -36,9 +36,9 @@ static void paServerInfoCallback(pa_context *c, const pa_server_info *i, void *u } } -static const char* detectSound(const FFinstance* instance, FFlist* devices) +static const char* detectSound(FFlist* devices) { - FF_LIBRARY_LOAD(pulse, &instance->config.libPulse, "Failed to load libpulse" FF_LIBRARY_EXTENSION, "libpulse" FF_LIBRARY_EXTENSION, 0) + FF_LIBRARY_LOAD(pulse, &instance.config.libPulse, "Failed to load libpulse" FF_LIBRARY_EXTENSION, "libpulse" FF_LIBRARY_EXTENSION, 0) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_new) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_get_api) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_iterate) @@ -119,12 +119,12 @@ static const char* detectSound(const FFinstance* instance, FFlist* devices) #endif // FF_HAVE_PULSE -const char* ffDetectSound(const FFinstance* instance, FFlist* devices) +const char* ffDetectSound(FFlist* devices) { #ifdef FF_HAVE_PULSE - return detectSound(instance, devices); + return detectSound(devices); #else - FF_UNUSED(instance, devices); + FF_UNUSED(devices); return "Fastfetch was built without libpulse support"; #endif } diff --git a/src/detection/sound/sound_nosupport.c b/src/detection/sound/sound_nosupport.c index 8f8014341f..7b23b2fa4d 100644 --- a/src/detection/sound/sound_nosupport.c +++ b/src/detection/sound/sound_nosupport.c @@ -1,6 +1,6 @@ #include "sound.h" -const char* ffDetectSound(FF_MAYBE_UNUSED const FFinstance* instance, FF_MAYBE_UNUSED FFlist* devices /* List of FFSoundDevice */) +const char* ffDetectSound(FF_MAYBE_UNUSED FFlist* devices /* List of FFSoundDevice */) { return "Not supported on this platform"; } diff --git a/src/detection/sound/sound_windows.cpp b/src/detection/sound/sound_windows.cpp index faa7328f48..6990615ab1 100644 --- a/src/detection/sound/sound_windows.cpp +++ b/src/detection/sound/sound_windows.cpp @@ -9,7 +9,7 @@ extern "C" { #include #include -const char* ffDetectSound(FF_MAYBE_UNUSED const FFinstance* instance, FF_MAYBE_UNUSED FFlist* devices /* List of FFSoundDevice */) +const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */) { const char* error = ffInitCom(); if (error) diff --git a/src/detection/temps/temps_apple.c b/src/detection/temps/temps_apple.c index 041e1418e8..7af1e12fe5 100644 --- a/src/detection/temps/temps_apple.c +++ b/src/detection/temps/temps_apple.c @@ -1,39 +1,11 @@ #include "fastfetch.h" #include "temps_apple.h" +#include "util/stringUtils.h" #include #include #include -static const char kDataTypeFlt[] = "flt "; -static const char kDataTypeFp1f[] = "fp1f"; -static const char kDataTypeFp4c[] = "fp4c"; -static const char kDataTypeFp5b[] = "fp5b"; -static const char kDataTypeFp6a[] = "fp6a"; -static const char kDataTypeFp79[] = "fp79"; -static const char kDataTypeFp88[] = "fp88"; -static const char kDataTypeFpa6[] = "fpa6"; -static const char kDataTypeFpc4[] = "fpc4"; -static const char kDataTypeFpe2[] = "fpe2"; -static const char kDataTypeSp1e[] = "sp1e"; -static const char kDataTypeSp3c[] = "sp3c"; -static const char kDataTypeSp4b[] = "sp4b"; -static const char kDataTypeSp5a[] = "sp5a"; -static const char kDataTypeSp69[] = "sp69"; -static const char kDataTypeSp78[] = "sp78"; -static const char kDataTypeSp87[] = "sp87"; -static const char kDataTypeSp96[] = "sp96"; -static const char kDataTypeSpb4[] = "spb4"; -static const char kDataTypeSpf0[] = "spf0"; -static const char kDataTypeUi8[] = "ui8 "; -static const char kDataTypeUi16[] = "ui16"; -static const char kDataTypeUi32[] = "ui32"; -static const char kDataTypeUi64[] = "ui64"; -static const char kDataTypeSi8[] = "si8 "; -static const char kDataTypeSi16[] = "si16"; -static const char kDataTypePwm[] = "{pwm"; - -static const char *kIOAppleSmcHiddenClassName = "AppleSMC"; static const char kSmcCmdReadBytes = 5; static const char kSmcCmdReadKeyInfo = 9; static const uint32_t kKernelIndexSmc = 2; @@ -168,7 +140,7 @@ static const char *smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcV static const char *smcOpen(io_connect_t *conn) { - CFMutableDictionaryRef matchDict = IOServiceMatching(kIOAppleSmcHiddenClassName); + CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSMC"); if (matchDict == NULL) return "IOServiceMatching(\"AppleSmartBattery\") failed"; @@ -198,108 +170,108 @@ static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl if (val.dataSize == 0) return "Empty SMC result"; - if (strcmp(val.dataType, kDataTypeUi8) == 0 || - strcmp(val.dataType, kDataTypeUi16) == 0 || - strcmp(val.dataType, kDataTypeUi32) == 0 || - strcmp(val.dataType, kDataTypeUi64) == 0) + if (ffStrEquals(val.dataType, "ui8 ") || + ffStrEquals(val.dataType, "ui16") || + ffStrEquals(val.dataType, "ui32") || + ffStrEquals(val.dataType, "ui64")) { uint64_t tmp = 0; for (uint32_t i = 0; i < val.dataSize; i++) tmp += (uint64_t)((uint8_t)(val.bytes[i]) * pow(256, val.dataSize - 1 - i)); *value = (double)tmp; } - else if (strcmp(val.dataType, kDataTypeFlt) == 0) + else if (ffStrEquals(val.dataType, "flt ")) { *value = *(float *)(val.bytes); } - else if (strcmp(val.dataType, kDataTypeFp1f) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "fp1f") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 32768.0; } - else if (strcmp(val.dataType, kDataTypeFp4c) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "fp4c") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0; } - else if (strcmp(val.dataType, kDataTypeFp5b) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "fp5b") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0; } - else if (strcmp(val.dataType, kDataTypeFp6a) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "fp6a") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0; } - else if (strcmp(val.dataType, kDataTypeFp79) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "fp79") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 512.0; } - else if (strcmp(val.dataType, kDataTypeFp88) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "fp88") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 256.0; } - else if (strcmp(val.dataType, kDataTypeFpa6) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "fpa6") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 64.0; } - else if (strcmp(val.dataType, kDataTypeFpc4) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "fpc4") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 16.0; } - else if (strcmp(val.dataType, kDataTypeFpe2) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "fpe2") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 4.0; } - else if (strcmp(val.dataType, kDataTypeSp1e) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "sp1e") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 16384.0; } - else if (strcmp(val.dataType, kDataTypeSp3c) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "sp3c") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0; } - else if (strcmp(val.dataType, kDataTypeSp4b) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "sp4b") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0; } - else if (strcmp(val.dataType, kDataTypeSp5a) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "sp5a") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0; } - else if (strcmp(val.dataType, kDataTypeSp69) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "sp69") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 512.0; } - else if (strcmp(val.dataType, kDataTypeSp78) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "sp78") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 256.0; } - else if (strcmp(val.dataType, kDataTypeSp87) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "sp87") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 128.0; } - else if (strcmp(val.dataType, kDataTypeSp96) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "sp96") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 64.0; } - else if (strcmp(val.dataType, kDataTypeSpb4) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "spb4") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 16.0; } - else if (strcmp(val.dataType, kDataTypeSpf0) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "spf0") && val.dataSize == 2) { *value = ntohs(*(uint16_t *)(val.bytes)) / 1.0; } - else if (strcmp(val.dataType, kDataTypeSi8) == 0 && val.dataSize == 1) + else if (ffStrEquals(val.dataType, "si8 ") && val.dataSize == 1) { signed char *bytes = (signed char *)val.bytes; int16_t temp = 0; temp += (int8_t)(bytes[0]); *value = temp; } - else if (strcmp(val.dataType, kDataTypeSi16) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "si16") && val.dataSize == 2) { *value = ntohs(*(int16_t *)(val.bytes)); } - else if (strcmp(val.dataType, kDataTypePwm) == 0 && val.dataSize == 2) + else if (ffStrEquals(val.dataType, "{pwm") && val.dataSize == 2) { *value = (double)ntohs(*(uint16_t *)(val.bytes)) * 100 / 65536.0; } @@ -308,23 +280,18 @@ static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl return NULL; } -static void detectTemp(io_connect_t conn, const char *sensor, const char *name, FFlist *list) +static bool detectTemp(io_connect_t conn, const char *sensor, double* sum) { double temp = 0; const char* error = smcReadValue(conn, sensor, &temp); - if (error) - return; - - FFTempValue* tempValue= (FFTempValue*)ffListAdd(list); - tempValue->value = temp; - - assert(strlen(sensor) == 4); - ffStrbufInitNS(&tempValue->deviceClass, 4, sensor); - - ffStrbufInitS(&tempValue->name, name); + if (error) return false; + // https://github.com/exelban/stats/blob/14e29c4d60229c363cca9c9d25c30c87b7870830/Modules/Sensors/readers.swift#L124 + if (temp < 10 || temp > 120) return false; + *sum += temp; + return true; } -const char *ffDetectCoreTemps(enum FFTempType type, FFlist *result) +const char *ffDetectCoreTemps(enum FFTempType type, double *result) { static io_connect_t conn; static dispatch_once_t once_control; @@ -332,76 +299,83 @@ const char *ffDetectCoreTemps(enum FFTempType type, FFlist *result) if(!conn) return "smcOpen() failed"; + uint32_t count = 0; + *result = 0; + // https://github.com/exelban/stats/blob/master/Modules/Sensors/values.swift switch (type) { case FF_TEMP_CPU_X64: - detectTemp(conn, "TC0D", "CPU diode", result); - detectTemp(conn, "TC0E", "CPU diode virtual", result); - detectTemp(conn, "TC0F", "CPU diode filtered", result); - detectTemp(conn, "TC0P", "CPU proximity", result); + count += detectTemp(conn, "TC0D", result); // CPU diode + count += detectTemp(conn, "TC0E", result); // CPU diode virtual + count += detectTemp(conn, "TC0F", result); // CPU diode filtered + count += detectTemp(conn, "TC0P", result); // CPU proximity break; case FF_TEMP_CPU_M1X: - detectTemp(conn, "Tp09", "CPU efficient core 1", result); - detectTemp(conn, "Tp0T", "CPU efficient core 2", result); - - detectTemp(conn, "Tp01", "CPU performance core 1", result); - detectTemp(conn, "Tp05", "CPU performance core 2", result); - detectTemp(conn, "Tp0D", "CPU performance core 3", result); - detectTemp(conn, "Tp0H", "CPU performance core 4", result); - detectTemp(conn, "Tp0L", "CPU performance core 5", result); - detectTemp(conn, "Tp0P", "CPU performance core 6", result); - detectTemp(conn, "Tp0X", "CPU performance core 7", result); - detectTemp(conn, "Tp0b", "CPU performance core 8", result); + count += detectTemp(conn, "Tp09", result); // CPU efficient core 1 + count += detectTemp(conn, "Tp0T", result); // CPU efficient core 2 + + count += detectTemp(conn, "Tp01", result); // CPU performance core 1 + count += detectTemp(conn, "Tp05", result); // CPU performance core 2 + count += detectTemp(conn, "Tp0D", result); // CPU performance core 3 + count += detectTemp(conn, "Tp0H", result); // CPU performance core 4 + count += detectTemp(conn, "Tp0L", result); // CPU performance core 5 + count += detectTemp(conn, "Tp0P", result); // CPU performance core 6 + count += detectTemp(conn, "Tp0X", result); // CPU performance core 7 + count += detectTemp(conn, "Tp0b", result); // CPU performance core 8 break; case FF_TEMP_CPU_M2X: - detectTemp(conn, "Tp05", "CPU efficient core 1", result); - detectTemp(conn, "Tp0D", "CPU efficient core 2", result); - detectTemp(conn, "Tp0j", "CPU efficient core 3", result); - detectTemp(conn, "Tp0r", "CPU efficient core 4", result); - - detectTemp(conn, "Tp01", "CPU performance core 1", result); - detectTemp(conn, "Tp09", "CPU performance core 2", result); - detectTemp(conn, "Tp0f", "CPU performance core 3", result); - detectTemp(conn, "Tp0n", "CPU performance core 4", result); + count += detectTemp(conn, "Tp0A", result); // CPU core 1 + count += detectTemp(conn, "Tp0D", result); // CPU core 2 + count += detectTemp(conn, "Tp0E", result); // CPU core 3 + count += detectTemp(conn, "Tp01", result); // CPU core 4 + count += detectTemp(conn, "Tp02", result); // CPU core 5 + count += detectTemp(conn, "Tp05", result); // CPU core 6 + count += detectTemp(conn, "Tp06", result); // CPU core 7 + count += detectTemp(conn, "Tp09", result); // CPU core 8 break; case FF_TEMP_GPU_INTEL: - detectTemp(conn, "TCGC", "GPU Intel Graphics", result); + count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics goto gpu_unknown; case FF_TEMP_GPU_AMD: - detectTemp(conn, "TGDD", "GPU AMD Radeon", result); + count += detectTemp(conn, "TGDD", result); // GPU AMD Radeon goto gpu_unknown; case FF_TEMP_GPU_UNKNOWN: // Nvidia? gpu_unknown: - detectTemp(conn, "TG0D", "GPU diode", result); - detectTemp(conn, "TG0P", "GPU proximity", result); + count += detectTemp(conn, "TG0D", result); // GPU diode + count += detectTemp(conn, "TG0P", result); // GPU proximity break; case FF_TEMP_GPU_M1X: - detectTemp(conn, "Tg05", "GPU 1", result); - detectTemp(conn, "Tg0D", "GPU 2", result); - detectTemp(conn, "Tg0L", "GPU 3", result); - detectTemp(conn, "Tg0T", "GPU 4", result); + count += detectTemp(conn, "Tg05", result); // GPU 1 + count += detectTemp(conn, "Tg0D", result); // GPU 2 + count += detectTemp(conn, "Tg0L", result); // GPU 3 + count += detectTemp(conn, "Tg0T", result); // GPU 4 break; case FF_TEMP_GPU_M2X: - detectTemp(conn, "Tg0f", "GPU 1", result); - detectTemp(conn, "Tg0n", "GPU 2", result); + count += detectTemp(conn, "Tg0f", result); // GPU 1 + count += detectTemp(conn, "Tg0j", result); // GPU 2 break; case FF_TEMP_BATTERY: - detectTemp(conn, "TB1T", "Battery", result); + count += detectTemp(conn, "TB1T", result); // Battery break; case FF_TEMP_MEMORY: - detectTemp(conn, "Tm02", "Memory", result); + count += detectTemp(conn, "Tm02", result); // Memory break; } + if (count == 0) + return "No temperatures detected"; + + *result /= count; + return NULL; } diff --git a/src/detection/temps/temps_apple.h b/src/detection/temps/temps_apple.h index 147c32d079..0fe4b01741 100644 --- a/src/detection/temps/temps_apple.h +++ b/src/detection/temps/temps_apple.h @@ -30,6 +30,6 @@ enum FFTempType FF_TEMP_MEMORY, }; -const char *ffDetectCoreTemps(enum FFTempType type, FFlist *result); +const char *ffDetectCoreTemps(enum FFTempType type, double* result); #endif diff --git a/src/detection/temps/temps_bsd.c b/src/detection/temps/temps_bsd.c new file mode 100644 index 0000000000..39693d65de --- /dev/null +++ b/src/detection/temps/temps_bsd.c @@ -0,0 +1,13 @@ +#include "temps_bsd.h" +#include "common/sysctl.h" + +const char* ffDetectThermalTemp(double* current) +{ + int temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999); + if (temp == -999999) + return "ffSysctlGetInt(\"hw.acpi.thermal.tz0.temperature\") failed"; + + // In tenth of degrees Kelvin + *current = (double) temp / 10 - 273.15; + return NULL; +} diff --git a/src/detection/temps/temps_bsd.h b/src/detection/temps/temps_bsd.h new file mode 100644 index 0000000000..a41aba6bc2 --- /dev/null +++ b/src/detection/temps/temps_bsd.h @@ -0,0 +1,8 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_temps_windows +#define FF_INCLUDED_detection_temps_windows + +const char* ffDetectThermalTemp(double* current); + +#endif diff --git a/src/detection/temps/temps_linux.c b/src/detection/temps/temps_linux.c index 0ade8180f7..ee30a85c4f 100644 --- a/src/detection/temps/temps_linux.c +++ b/src/detection/temps/temps_linux.c @@ -11,8 +11,7 @@ static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value) //https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface uint32_t dirLength = dir->length; - FF_STRBUF_AUTO_DESTROY valueBuffer; - ffStrbufInit(&valueBuffer); + FF_STRBUF_AUTO_DESTROY valueBuffer = ffStrbufCreate(); ffStrbufAppendS(dir, "temp1_input"); if(!ffReadFileBuffer(dir->chars, &valueBuffer)) @@ -42,7 +41,7 @@ static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value) return value->name.length > 0 || value->deviceClass > 0; } -const FFTempsResult* ffDetectTemps() +const FFTempsResult* ffDetectTemps(void) { static FFTempsResult result; static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; @@ -58,8 +57,7 @@ const FFTempsResult* ffDetectTemps() ffListInitA(&result.values, sizeof(FFTempValue), 16); - FFstrbuf baseDir; - ffStrbufInitA(&baseDir, 64); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64); ffStrbufAppendS(&baseDir, "/sys/class/hwmon/"); uint32_t baseDirLength = baseDir.length; @@ -67,7 +65,6 @@ const FFTempsResult* ffDetectTemps() DIR* dirp = opendir(baseDir.chars); if(dirp == NULL) { - ffStrbufDestroy(&baseDir); ffThreadMutexUnlock(&mutex); return &result; } @@ -94,7 +91,6 @@ const FFTempsResult* ffDetectTemps() } closedir(dirp); - ffStrbufDestroy(&baseDir); ffThreadMutexUnlock(&mutex); return &result; diff --git a/src/detection/temps/temps_windows.cpp b/src/detection/temps/temps_windows.cpp index 9c741b4cd5..c9cfeac501 100644 --- a/src/detection/temps/temps_windows.cpp +++ b/src/detection/temps/temps_windows.cpp @@ -15,10 +15,21 @@ const char* ffDetectSmbiosTemp(double* current, double* critical) if(FFWmiRecord record = query.next()) { - if (current && record.getReal(L"CurrentTemperature", current)) // In tenth of degrees Kelvin - *current = *current / 10 - 273.15; - if (critical && record.getReal(L"CriticalTripPoint", critical)) // In tenth of degrees Kelvin - *critical = *critical / 10 - 273.15; + if (current) + { + if(auto vtCurrent = record.get(L"CurrentTemperature")) + *current = vtCurrent.get() / 10 - 273.15; // In tenth of degrees Kelvin + else + *current = 0.0/0.0; + } + + if (critical) + { + if(auto vtCritical = record.get(L"CriticalTripPoint")) + *critical = vtCritical.get() / 10 - 273.15; // In tenth of degrees Kelvin + else + *critical = 0.0/0.0; + } } return "No WMI result returned"; diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index 1c2a4be9be..515c253501 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -4,13 +4,10 @@ #include "detection/internal.h" #include "detection/terminalshell/terminalshell.h" -static void detectAlacritty(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectAlacritty(FFTerminalFontResult* terminalFont) { - FFstrbuf fontName; - ffStrbufInit(&fontName); - - FFstrbuf fontSize; - ffStrbufInit(&fontSize); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); FFpropquery fontQuery[] = { {"family:", &fontName}, @@ -18,11 +15,11 @@ static void detectAlacritty(const FFinstance* instance, FFTerminalFontResult* te }; // alacritty parses config files in this order - ffParsePropFileConfigValues(instance, "alacritty/alacritty.yml", 2, fontQuery); + ffParsePropFileConfigValues("alacritty/alacritty.yml", 2, fontQuery); if(fontName.length == 0 || fontSize.length == 0) - ffParsePropFileConfigValues(instance, "alacritty.yml", 2, fontQuery); + ffParsePropFileConfigValues("alacritty.yml", 2, fontQuery); if(fontName.length == 0 || fontSize.length == 0) - ffParsePropFileConfigValues(instance, ".alacritty.yml", 2, fontQuery); + ffParsePropFileConfigValues(".alacritty.yml", 2, fontQuery); //by default alacritty uses its own font called alacritty if(fontName.length == 0) @@ -33,15 +30,11 @@ static void detectAlacritty(const FFinstance* instance, FFTerminalFontResult* te ffStrbufAppendS(&fontSize, "11"); ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&fontSize); } FF_MAYBE_UNUSED static void detectTTY(FFTerminalFontResult* terminalFont) { - FFstrbuf fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); ffParsePropFile(FASTFETCH_TARGET_DIR_ETC"/vconsole.conf", "Font =", &fontName); @@ -61,116 +54,86 @@ FF_MAYBE_UNUSED static void detectTTY(FFTerminalFontResult* terminalFont) ffFontInitCopy(&terminalFont->font, fontName.chars); else ffStrbufAppendS(&terminalFont->error, "Couldn't find Font in "FASTFETCH_TARGET_DIR_ETC"/vconsole.conf"); - - ffStrbufDestroy(&fontName); } #if defined(_WIN32) || defined(__linux__) -#ifdef FF_HAVE_LIBCJSON - #include "common/library.h" #include "common/processing.h" -#include #include +#include -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) - - cJSON* root; -} CJSONData; - -static const char* detectWTProfile(CJSONData* cjsonData, cJSON* profile, FFstrbuf* name, double* size) +static const char* detectWTProfile(yyjson_val* profile, FFstrbuf* name, double* size) { - if(!cjsonData->ffcJSON_IsObject(profile)) - return "cJSON_IsObject(profile) returns false"; + yyjson_val* font = yyjson_obj_get(profile, "font"); + if (!font) + return "yyjson_obj_get(profile, \"font\"); failed"; - cJSON* font = cjsonData->ffcJSON_GetObjectItemCaseSensitive(profile, "font"); - if(!cjsonData->ffcJSON_IsObject(font)) - return "cJSON_IsObject(font) returns false"; + if (!yyjson_is_obj(font)) + return "yyjson_is_obj(font) returns false"; - if(name->length == 0) + if (name->length == 0) { - cJSON* pface = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "face"); - if(cjsonData->ffcJSON_IsString(pface)) - ffStrbufAppendS(name, cjsonData->ffcJSON_GetStringValue(pface)); + yyjson_val* pface = yyjson_obj_get(font, "face"); + if(yyjson_is_str(pface)) + ffStrbufAppendS(name, unsafe_yyjson_get_str(pface)); } - if(*size < 0) + + if (*size < 0) { - cJSON* psize = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "size"); - if(cjsonData->ffcJSON_IsNumber(psize)) - *size = cjsonData->ffcJSON_GetNumberValue(psize); + yyjson_val* psize = yyjson_obj_get(font, "size"); + if (yyjson_is_num(psize)) + *size = yyjson_get_num(psize); } return NULL; } -static inline void wrapCjsonFree(CJSONData* data) +static inline void wrapYyjsonFree(yyjson_doc** doc) { - assert(data); - if (data->root) - data->ffcJSON_Delete(data->root); + assert(doc); + if (*doc) + yyjson_doc_free(*doc); } -static const char* detectFromWTImpl(const FFinstance* instance, FFstrbuf* content, FFstrbuf* name, double* size) +static const char* detectFromWTImpl(FFstrbuf* content, FFstrbuf* name, double* size) { - FF_LIBRARY_LOAD(libcjson, &instance->config.libcJSON, "dlopen libcjson" FF_LIBRARY_EXTENSION " failed", "libcjson"FF_LIBRARY_EXTENSION, 1) - CJSONData __attribute__((__cleanup__(wrapCjsonFree))) cjsonData = {}; // Make sure cjsonData is destroyed before libcjson is dlclosed - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_Parse, cJSON_Parse@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_IsObject, cJSON_IsObject@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_GetObjectItemCaseSensitive, cJSON_GetObjectItemCaseSensitive@8) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_IsString, cJSON_IsString@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_GetStringValue, cJSON_GetStringValue@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_IsNumber, cJSON_IsNumber@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_GetNumberValue, cJSON_GetNumberValue@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_IsArray, cJSON_IsArray@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_Delete, cJSON_Delete@4) - - cJSON* root = cjsonData.root = cjsonData.ffcJSON_Parse(content->chars); - if(!cjsonData.ffcJSON_IsObject(root)) - return "cJSON_Parse() failed"; - - cJSON* profiles = cjsonData.ffcJSON_GetObjectItemCaseSensitive(root, "profiles"); - if(!cjsonData.ffcJSON_IsObject(profiles)) - return "cJSON_GetObjectItemCaseSensitive(root, \"profiles\") failed"; - - FF_STRBUF_AUTO_DESTROY wtProfileId; - ffStrbufInitS(&wtProfileId, getenv("WT_PROFILE_ID")); + yyjson_doc* __attribute__((__cleanup__(wrapYyjsonFree))) doc = yyjson_read_opts(content->chars, content->length, YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_TRAILING_COMMAS | YYJSON_READ_ALLOW_INF_AND_NAN, NULL, NULL); + if (!doc) + return "Failed to parse WT JSON config file"; + + yyjson_val* const root = yyjson_doc_get_root(doc); + assert(root); + + yyjson_val* profiles = yyjson_obj_get(root, "profiles"); + if (!profiles) + return "yyjson_obj_get(root, \"profiles\") failed"; + + FF_STRBUF_AUTO_DESTROY wtProfileId = ffStrbufCreateS(getenv("WT_PROFILE_ID")); ffStrbufTrim(&wtProfileId, '\''); - if(wtProfileId.length > 0) + if (wtProfileId.length > 0) { - cJSON* list = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "list"); - if(cjsonData.ffcJSON_IsArray(list)) + yyjson_val* list = yyjson_obj_get(profiles, "list"); + if (yyjson_is_arr(list)) { - cJSON* profile; - cJSON_ArrayForEach(profile, list) + yyjson_val* profile; + size_t idx, max; + yyjson_arr_foreach(list, idx, max, profile) { - 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) + yyjson_val* guid = yyjson_obj_get(profile, "guid"); + + if(ffStrbufEqualS(&wtProfileId, yyjson_get_str(guid))) { - detectWTProfile(&cjsonData, profile, name, size); + detectWTProfile(profile, name, size); break; } } } } - cJSON* defaults = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "defaults"); - if(defaults) - detectWTProfile(&cjsonData, defaults, name, size); + yyjson_val* defaults = yyjson_obj_get(profiles, "defaults"); + if (defaults) + detectWTProfile(defaults, name, size); if(name->length == 0) ffStrbufSetS(name, "Cascadia Mono"); @@ -185,11 +148,10 @@ static const char* detectFromWTImpl(const FFinstance* instance, FFstrbuf* conten #include #endif -static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbuf* terminalExe, FFTerminalFontResult* terminalFont) +static void detectFromWindowsTeriminal(const FFstrbuf* terminalExe, FFTerminalFontResult* terminalFont) { //https://learn.microsoft.com/en-us/windows/terminal/install#settings-json-file - FF_STRBUF_AUTO_DESTROY json; - ffStrbufInit(&json); + FF_STRBUF_AUTO_DESTROY json = ffStrbufCreate(); const char* error = NULL; #ifdef _WIN32 @@ -258,10 +220,9 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbu return; } - FF_STRBUF_AUTO_DESTROY name; - ffStrbufInit(&name); + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); double size = -1; - error = detectFromWTImpl(instance, &json, &name, &size); + error = detectFromWTImpl(&json, &name, &size); if(error) ffStrbufAppendS(&terminalFont->error, error); @@ -273,32 +234,21 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbu } } -#else //FF_HAVE_CJSON -static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbuf* terminalExe, FFTerminalFontResult* terminalFont) -{ - FF_UNUSED(instance, terminalExe, terminalFont); - ffStrbufAppendS(&terminalFont->error, "Fastfetch was built without libcJSON support"); -} - -#endif //FF_HAVE_CJSON #endif //defined(_WIN32) || defined(__linux__) -FF_MAYBE_UNUSED static bool detectKitty(const FFinstance* instance, FFTerminalFontResult* result) +FF_MAYBE_UNUSED static bool detectKitty(FFTerminalFontResult* result) { - FF_STRBUF_AUTO_DESTROY fontName; - ffStrbufInit(&fontName); - - FF_STRBUF_AUTO_DESTROY fontSize; - ffStrbufInit(&fontSize); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); FFpropquery fontQuery[] = { {"font_family ", &fontName}, {"font_size ", &fontSize}, }; - if(!ffParsePropFileConfigValues(instance, "kitty/kitty.conf", 2, fontQuery)) + if(!ffParsePropFileConfigValues("kitty/kitty.conf", 2, fontQuery)) return false; if(fontName.length == 0) @@ -311,20 +261,17 @@ FF_MAYBE_UNUSED static bool detectKitty(const FFinstance* instance, FFTerminalFo return true; } -static void detectTerminator(const FFinstance* instance, FFTerminalFontResult* result) +static void detectTerminator(FFTerminalFontResult* result) { - FF_STRBUF_AUTO_DESTROY useSystemFont; - ffStrbufInit(&useSystemFont); - - FF_STRBUF_AUTO_DESTROY fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY useSystemFont = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); FFpropquery fontQuery[] = { {"use_system_font =", &useSystemFont}, {"font =", &fontName}, }; - if(!ffParsePropFileConfigValues(instance, "terminator/config", 2, fontQuery)) + if(!ffParsePropFileConfigValues("terminator/config", 2, fontQuery)) { ffStrbufAppendS(&result->error, "Couldn't read Terminator config file"); return; @@ -342,10 +289,9 @@ static void detectTerminator(const FFinstance* instance, FFTerminalFontResult* r ffFontInitPango(&result->font, fontName.chars); } -static bool detectWezterm(FF_MAYBE_UNUSED const FFinstance* instance, FFTerminalFontResult* result) +static bool detectWezterm(FFTerminalFontResult* result) { - FF_STRBUF_AUTO_DESTROY fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); ffStrbufSetS(&result->error, ffProcessAppendStdOut(&fontName, (char* const[]){ "wezterm", @@ -370,20 +316,17 @@ static bool detectWezterm(FF_MAYBE_UNUSED const FFinstance* instance, FFTerminal return true; } -static bool detectTabby(FF_MAYBE_UNUSED const FFinstance* instance, FFTerminalFontResult* result) +static bool detectTabby(FFTerminalFontResult* result) { - FF_STRBUF_AUTO_DESTROY fontName; - ffStrbufInit(&fontName); - - FF_STRBUF_AUTO_DESTROY fontSize; - ffStrbufInit(&fontSize); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); FFpropquery fontQuery[] = { {"font: ", &fontName}, {"fontSize: ", &fontSize}, }; - if(!ffParsePropFileConfigValues(instance, "tabby/config.yaml", 2, fontQuery)) + if(!ffParsePropFileConfigValues("tabby/config.yaml", 2, fontQuery)) return false; if(fontName.length == 0) @@ -396,24 +339,24 @@ static bool detectTabby(FF_MAYBE_UNUSED const FFinstance* instance, FFTerminalFo return true; } -void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont); +void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont); -static bool detectTerminalFontCommon(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) +static bool detectTerminalFontCommon(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "alacritty")) - detectAlacritty(instance, terminalFont); + detectAlacritty(terminalFont); else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "terminator")) - detectTerminator(instance, terminalFont); + detectTerminator(terminalFont); else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "wezterm-gui")) - detectWezterm(instance, terminalFont); + detectWezterm(terminalFont); else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "tabby")) - detectTabby(instance, terminalFont); + detectTabby(terminalFont); #ifndef _WIN32 else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/pts/")) ffStrbufAppendS(&terminalFont->error, "Terminal font detection is not supported on PTS"); - else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "kitty")) - detectKitty(instance, terminalFont); + else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalPrettyName, "kitty")) + detectKitty(terminalFont); else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty")) detectTTY(terminalFont); #endif @@ -422,7 +365,7 @@ static bool detectTerminalFontCommon(const FFinstance* instance, const FFTermina //Used by both Linux (WSL) and Windows else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "Windows Terminal") || ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "WindowsTerminal.exe")) - detectFromWindowsTeriminal(instance, &terminalShell->terminalExe, terminalFont); + detectFromWindowsTeriminal(&terminalShell->terminalExe, terminalFont); #endif else @@ -431,20 +374,18 @@ static bool detectTerminalFontCommon(const FFinstance* instance, const FFTermina return true; } -const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance) +bool ffDetectTerminalFont(FFTerminalFontResult* result) { - FF_DETECTION_INTERNAL_GUARD(FFTerminalFontResult, - ffStrbufInitA(&result.error, 0); + const FFTerminalShellResult* terminalShell = ffDetectTerminalShell(); - const FFTerminalShellResult* terminalShell = ffDetectTerminalShell(instance); + if(terminalShell->terminalProcessName.length == 0) + ffStrbufAppendS(&result->error, "Terminal font needs successful terminal detection"); - if(terminalShell->terminalProcessName.length == 0) - ffStrbufAppendS(&result.error, "Terminal font needs successful terminal detection"); + else if(!detectTerminalFontCommon(terminalShell, result)) + ffDetectTerminalFontPlatform(terminalShell, result); - else if(!detectTerminalFontCommon(instance, terminalShell, &result)) - ffDetectTerminalFontPlatform(instance, terminalShell, &result); + if(result->error.length == 0 && result->font.pretty.length == 0) + ffStrbufAppendF(&result->error, "Unknown terminal: %s", terminalShell->terminalProcessName.chars); - if(result.error.length == 0 && result.font.pretty.length == 0) - ffStrbufAppendF(&result.error, "Unknown terminal: %s", terminalShell->terminalProcessName.chars); - ); + return result->error.length == 0; } diff --git a/src/detection/terminalfont/terminalfont.h b/src/detection/terminalfont/terminalfont.h index 0adc2e2aaa..936cdeb4f5 100644 --- a/src/detection/terminalfont/terminalfont.h +++ b/src/detection/terminalfont/terminalfont.h @@ -10,8 +10,9 @@ typedef struct FFTerminalFontResult { FFstrbuf error; FFfont font; + FFfont fallback; } FFTerminalFontResult; -const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance); +bool ffDetectTerminalFont(FFTerminalFontResult* result); #endif diff --git a/src/detection/terminalfont/terminalfont_android.c b/src/detection/terminalfont/terminalfont_android.c index 251ada6c74..ae79a4517a 100644 --- a/src/detection/terminalfont/terminalfont_android.c +++ b/src/detection/terminalfont/terminalfont_android.c @@ -11,11 +11,11 @@ #define FF_TERMUX_FONT_PATH FASTFETCH_TARGET_DIR_HOME "/.termux/font.ttf" -const char* detectTermux(const FFinstance* instance, FFTerminalFontResult* terminalFont) +const char* detectTermux(FFTerminalFontResult* terminalFont) { #ifdef FF_HAVE_FREETYPE - FF_LIBRARY_LOAD(freetype, &instance->config.libfreetype, "dlopen libfreetype"FF_LIBRARY_EXTENSION " failed", "libfreetype"FF_LIBRARY_EXTENSION, 2) + FF_LIBRARY_LOAD(freetype, &instance.config.libfreetype, "dlopen libfreetype"FF_LIBRARY_EXTENSION " failed", "libfreetype"FF_LIBRARY_EXTENSION, 2) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_Init_FreeType); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_New_Face); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_Done_Face); @@ -53,7 +53,7 @@ const char* detectTermux(const FFinstance* instance, FFTerminalFontResult* termi #endif } -void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) +void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { if(ffStrbufCompS(&terminalShell->terminalProcessName, "Termux") != 0) { @@ -67,5 +67,5 @@ void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalSh return; } - ffStrbufSetS(&terminalFont->error, detectTermux(instance, terminalFont)); + ffStrbufSetS(&terminalFont->error, detectTermux(terminalFont)); } diff --git a/src/detection/terminalfont/terminalfont_apple.m b/src/detection/terminalfont/terminalfont_apple.m index 2dd3d03b78..8714621099 100644 --- a/src/detection/terminalfont/terminalfont_apple.m +++ b/src/detection/terminalfont/terminalfont_apple.m @@ -7,7 +7,7 @@ #include #import -static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectIterm2(FFTerminalFontResult* terminalFont) { const char* profile = getenv("ITERM_PROFILE"); if (profile == NULL) @@ -17,7 +17,7 @@ static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* termi } NSError* error; - NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/com.googlecode.iterm2.plist", instance->state.platform.homeDir.chars]; + NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/com.googlecode.iterm2.plist", instance.state.platform.homeDir.chars]; NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName] error:&error]; if(error) @@ -38,6 +38,14 @@ static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* termi return; } ffFontInitWithSpace(&terminalFont->font, normalFont.UTF8String); + + NSNumber* useNonAsciiFont = [bookmark valueForKey:@"Use Non-ASCII Font"]; + if(useNonAsciiFont.boolValue) + { + NSString* nonAsciiFont = [bookmark valueForKey:@"Non Ascii Font"]; + if (nonAsciiFont) + ffFontInitWithSpace(&terminalFont->fallback, nonAsciiFont.UTF8String); + } return; } @@ -46,8 +54,7 @@ static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* termi static void detectAppleTerminal(FFTerminalFontResult* terminalFont) { - FF_STRBUF_AUTO_DESTROY font; - ffStrbufInit(&font); + FF_STRBUF_AUTO_DESTROY font = ffStrbufCreate(); ffOsascript("tell application \"Terminal\" to font name of window frontmost & \" \" & font size of window frontmost", &font); if(font.length == 0) @@ -59,10 +66,10 @@ static void detectAppleTerminal(FFTerminalFontResult* terminalFont) ffFontInitWithSpace(&terminalFont->font, font.chars); } -static void detectWarpTerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectWarpTerminal(FFTerminalFontResult* terminalFont) { NSError* error; - NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/dev.warp.Warp-Stable.plist", instance->state.platform.homeDir.chars]; + NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/dev.warp.Warp-Stable.plist", instance.state.platform.homeDir.chars]; NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName] error:&error]; if(error) @@ -84,13 +91,13 @@ static void detectWarpTerminal(const FFinstance* instance, FFTerminalFontResult* ffFontInitValues(&terminalFont->font, fontName.UTF8String, fontSize.UTF8String); } -void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) +void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "iterm.app") == 0 || ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "iTermServer-")) - detectIterm2(instance, terminalFont); + detectIterm2(terminalFont); else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Apple_Terminal") == 0) detectAppleTerminal(terminalFont); else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WarpTerminal") == 0) - detectWarpTerminal(instance, terminalFont); + detectWarpTerminal(terminalFont); } diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index 6b08c41c58..6833ba0863 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -4,46 +4,46 @@ #include "common/parsing.h" #include "detection/terminalshell/terminalshell.h" #include "detection/displayserver/displayserver.h" +#include "util/mallocHelper.h" #include "util/stringUtils.h" -static const char* getSystemMonospaceFont(const FFinstance* instance) +static const char* getSystemMonospaceFont(void) { - const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance); + const FFDisplayServerResult* wmde = ffConnectDisplayServer(); if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, "Cinnamon")) { - const char* systemMonospaceFont = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/monospace-font-name", "org.cinnamon.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; + const char* systemMonospaceFont = ffSettingsGet("/org/cinnamon/desktop/interface/monospace-font-name", "org.cinnamon.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; if(ffStrSet(systemMonospaceFont)) return systemMonospaceFont; } else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, "Mate")) { - const char* systemMonospaceFont = ffSettingsGet(instance, "/org/mate/interface/monospace-font-name", "org.mate.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; + const char* systemMonospaceFont = ffSettingsGet("/org/mate/interface/monospace-font-name", "org.mate.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; if(ffStrSet(systemMonospaceFont)) return systemMonospaceFont; } - return ffSettingsGet(instance, "/org/gnome/desktop/interface/monospace-font-name", "org.gnome.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; + return ffSettingsGet("/org/gnome/desktop/interface/monospace-font-name", "org.gnome.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue; } -static void detectFromGSettings(const FFinstance* instance, const char* profilePath, const char* profileList, const char* profile, const char* defaultProfileKey, FFTerminalFontResult* terminalFont) +static void detectFromGSettings(const char* profilePath, const char* profileList, const char* profile, const char* defaultProfileKey, FFTerminalFontResult* terminalFont) { - const char* defaultProfile = ffSettingsGetGSettings(instance, profileList, NULL, defaultProfileKey, FF_VARIANT_TYPE_STRING).strValue; + FF_AUTO_FREE const char* defaultProfile = ffSettingsGetGSettings(profileList, NULL, defaultProfileKey, FF_VARIANT_TYPE_STRING).strValue; if(!ffStrSet(defaultProfile)) { ffStrbufAppendF(&terminalFont->error, "Could not get default profile from gsettings: %s", profileList); return; } - FFstrbuf path; - ffStrbufInitA(&path, 128); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateA(128); ffStrbufAppendS(&path, profilePath); ffStrbufAppendS(&path, defaultProfile); ffStrbufAppendC(&path, '/'); - if(!ffSettingsGetGSettings(instance, profile, path.chars, "use-system-font", FF_VARIANT_TYPE_BOOL).boolValue) + if(!ffSettingsGetGSettings(profile, path.chars, "use-system-font", FF_VARIANT_TYPE_BOOL).boolValue) { - const char* fontName = ffSettingsGetGSettings(instance, profile, path.chars, "font", FF_VARIANT_TYPE_STRING).strValue; + FF_AUTO_FREE const char* fontName = ffSettingsGetGSettings(profile, path.chars, "font", FF_VARIANT_TYPE_STRING).strValue; if(ffStrSet(fontName)) ffFontInitPango(&terminalFont->font, fontName); else @@ -51,72 +51,59 @@ static void detectFromGSettings(const FFinstance* instance, const char* profileP } else { - const char* fontName = getSystemMonospaceFont(instance); + const char* fontName = getSystemMonospaceFont(); if(ffStrSet(fontName)) ffFontInitPango(&terminalFont->font, fontName); else ffStrbufAppendS(&terminalFont->error, "Could't get system monospace font name from GSettings / DConf"); } - - ffStrbufDestroy(&path); } -static void detectFromConfigFile(const FFinstance* instance, const char* configFile, const char* start, FFTerminalFontResult* terminalFont) +static void detectFromConfigFile(const char* configFile, const char* start, FFTerminalFontResult* terminalFont) { - FFstrbuf fontName; - ffStrbufInit(&fontName); - ffParsePropFileConfig(instance, configFile, start, &fontName); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + ffParsePropFileConfig(configFile, start, &fontName); if(fontName.length == 0) ffStrbufAppendF(&terminalFont->error, "Couldn't find %s in .config/%s", start, configFile); else ffFontInitPango(&terminalFont->font, fontName.chars); - - ffStrbufDestroy(&fontName); } -static void detectKonsole(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectKonsole(FFTerminalFontResult* terminalFont, const char* rcFile) { - FFstrbuf profile; - ffStrbufInit(&profile); - ffParsePropFileConfig(instance, "konsolerc", "DefaultProfile =", &profile); + FF_STRBUF_AUTO_DESTROY profile = ffStrbufCreate(); + if(!ffParsePropFileConfig(rcFile, "DefaultProfile =", &profile)) + { + ffStrbufAppendF(&terminalFont->error, "Configuration \".config/%s\" doesn't exist", rcFile); + return; + } if(profile.length == 0) { - ffStrbufAppendS(&terminalFont->error, "Couldn't find \"DefaultProfile=%[^\\n]\" in \".config/konsolerc\""); - ffStrbufDestroy(&profile); + ffStrbufAppendS(&terminalFont->error, "Built-in profile is used"); return; } - FFstrbuf profilePath; - ffStrbufInitA(&profilePath, 32); + FF_STRBUF_AUTO_DESTROY profilePath = ffStrbufCreateA(32); ffStrbufAppendS(&profilePath, "konsole/"); ffStrbufAppend(&profilePath, &profile); - ffStrbufDestroy(&profile); - - FFstrbuf fontName; - ffStrbufInit(&fontName); - ffParsePropFileData(instance, profilePath.chars, "Font =", &fontName); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + ffParsePropFileData(profilePath.chars, "Font =", &fontName); if(fontName.length == 0) ffStrbufAppendF(&terminalFont->error, "Couldn't find \"Font=%%[^\\n]\" in \"%s\"", profilePath.chars); else ffFontInitQt(&terminalFont->font, fontName.chars); - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&profilePath); } -static void detectXFCETerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectXFCETerminal(FFTerminalFontResult* terminalFont) { - FFstrbuf useSysFont; - ffStrbufInit(&useSysFont); - - FFstrbuf fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY useSysFont = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); - ffParsePropFileConfigValues(instance, "xfce4/terminal/terminalrc", 2, (FFpropquery[]) { + ffParsePropFileConfigValues("xfce4/terminal/terminalrc", 2, (FFpropquery[]) { {"FontUseSystem = ", &useSysFont}, {"FontName = ", &fontName} }); @@ -130,28 +117,21 @@ static void detectXFCETerminal(const FFinstance* instance, FFTerminalFontResult* } else { - const char* systemFontName = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/MonospaceFontName", FF_VARIANT_TYPE_STRING).strValue; + const char* systemFontName = ffSettingsGetXFConf("xsettings", "/Gtk/MonospaceFontName", FF_VARIANT_TYPE_STRING).strValue; if(ffStrSet(systemFontName)) ffFontInitPango(&terminalFont->font, systemFontName); else ffStrbufAppendS(&terminalFont->error, "Couldn't find xsettings::/Gtk/MonospaceFontName in XFConf"); } - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&useSysFont); } -static void detectDeepinTerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectDeepinTerminal(FFTerminalFontResult* terminalFont) { - FFstrbuf fontName; - ffStrbufInit(&fontName); - - FFstrbuf fontSize; - ffStrbufInit(&fontSize); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY profile = ffStrbufCreate(); - FFstrbuf profile; - ffStrbufInit(&profile); - ffStrbufAppend(&profile, &instance->state.platform.homeDir); + ffStrbufAppend(&profile, &instance.state.platform.homeDir); ffStrbufAppendS(&profile, ".config/deepin/deepin-terminal/config.conf"); //TODO: Use config dirs FILE* file = fopen(profile.chars, "r"); @@ -162,13 +142,13 @@ static void detectDeepinTerminal(const FFinstance* instance, FFTerminalFontResul for(int count = 0; getline(&line, &len, file) != -1 && count < 2;) { - if(strcmp(line, "[basic.interface.font]\n") == 0) + if(ffStrEquals(line, "[basic.interface.font]\n")) { if(getline(&line, &len, file) != -1) ffParsePropLine(line, "value=", &fontName); ++count; } - else if(strcmp(line, "[basic.interface.font_size]\n") == 0) + else if(ffStrEquals(line, "[basic.interface.font_size]\n")) { if(getline(&line, &len, file) != -1) ffParsePropLine(line, "value=", &fontSize); @@ -180,25 +160,19 @@ static void detectDeepinTerminal(const FFinstance* instance, FFTerminalFontResul fclose(file); } - ffStrbufDestroy(&profile); - if(fontName.length == 0) ffStrbufAppendS(&fontName, "Noto Sans Mono"); if(fontSize.length == 0) ffStrbufAppendS(&fontSize, "11"); ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&fontSize); } -static void detectFootTerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectFootTerminal(FFTerminalFontResult* terminalFont) { - FF_STRBUF_AUTO_DESTROY font; - ffStrbufInit(&font); + FF_STRBUF_AUTO_DESTROY font = ffStrbufCreate(); - if (!ffParsePropFileConfig(instance, "foot/foot.ini", "font=", &font) || !ffStrSet(font.chars)) + if (!ffParsePropFileConfig("foot/foot.ini", "font=", &font) || !ffStrSet(font.chars)) { ffFontInitValues(&terminalFont->font, "monospace", "8"); return; @@ -221,12 +195,12 @@ static void detectFootTerminal(const FFinstance* instance, FFTerminalFontResult* ffFontInitValues(&terminalFont->font, font.chars, &font.chars[equal + strlen("size=")]); } -static void detectQTerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectQTerminal(FFTerminalFontResult* terminalFont) { FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); - ffParsePropFileConfigValues(instance, "qterminal.org/qterminal.ini", 2, (FFpropquery[]) { + ffParsePropFileConfigValues("qterminal.org/qterminal.ini", 2, (FFpropquery[]) { {"fontFamily=", &fontName}, {"fontSize=", &fontSize}, }); @@ -238,24 +212,45 @@ static void detectQTerminal(const FFinstance* instance, FFTerminalFontResult* te ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); } -void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) +static void detectXterm(FFTerminalFontResult* terminalFont) +{ + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); + + ffParsePropFileHomeValues(".Xresources", 2, (FFpropquery[]) { + {"xterm*faceName:", &fontName}, + {"xterm*faceSize:", &fontSize}, + }); + + if (fontName.length == 0) + ffStrbufAppendS(&fontName, "fixed"); + if (fontSize.length == 0) + ffStrbufAppendS(&fontSize, "8.0"); + ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); +} + +void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "konsole")) - detectKonsole(instance, terminalFont); + detectKonsole(terminalFont, "konsolerc"); + else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "yakuake")) + detectKonsole(terminalFont, "yakuakerc"); else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "xfce4-terminal")) - detectXFCETerminal(instance, terminalFont); + detectXFCETerminal(terminalFont); else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "lxterminal")) - detectFromConfigFile(instance, "lxterminal/lxterminal.conf", "fontname =", terminalFont); + detectFromConfigFile("lxterminal/lxterminal.conf", "fontname =", terminalFont); else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "tilix")) - detectFromGSettings(instance, "/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", "default", terminalFont); + detectFromGSettings("/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", "default", terminalFont); else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "gnome-terminal-")) - detectFromGSettings(instance, "/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", "default", terminalFont); + detectFromGSettings("/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", "default", terminalFont); else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "mate-terminal")) - detectFromGSettings(instance, "/org/mate/terminal/profiles/", "org.mate.terminal.global", "org.mate.terminal.profile", "default-profile", terminalFont); + detectFromGSettings("/org/mate/terminal/profiles/", "org.mate.terminal.global", "org.mate.terminal.profile", "default-profile", terminalFont); else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "deepin-terminal")) - detectDeepinTerminal(instance, terminalFont); + detectDeepinTerminal(terminalFont); else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "foot")) - detectFootTerminal(instance, terminalFont); + detectFootTerminal(terminalFont); else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "qterminal")) - detectQTerminal(instance, terminalFont); + detectQTerminal(terminalFont); + else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "xterm")) + detectXterm(terminalFont); } diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c index da2f0568b1..e461986dd5 100644 --- a/src/detection/terminalfont/terminalfont_windows.c +++ b/src/detection/terminalfont/terminalfont_windows.c @@ -6,19 +6,16 @@ #include -static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectMintty(FFTerminalFontResult* terminalFont) { - FF_STRBUF_AUTO_DESTROY fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); - FF_STRBUF_AUTO_DESTROY fontSize; - ffStrbufInit(&fontSize); - - if(!ffParsePropFileConfigValues(instance, "mintty/config", 2, (FFpropquery[]) { + if(!ffParsePropFileConfigValues("mintty/config", 2, (FFpropquery[]) { {"Font=", &fontName}, {"FontHeight=", &fontSize} })) - ffParsePropFileConfigValues(instance, ".minttyrc", 2, (FFpropquery[]) { + ffParsePropFileConfigValues(".minttyrc", 2, (FFpropquery[]) { {"Font=", &fontName}, {"FontHeight=", &fontSize} }); @@ -30,10 +27,8 @@ static void detectMintty(const FFinstance* instance, FFTerminalFontResult* termi ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); } -static void detectConhost(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectConhost(FFTerminalFontResult* terminalFont) { - FF_UNUSED(instance); - CONSOLE_FONT_INFOEX cfi = { .cbSize = sizeof(cfi) }; if(!GetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi)) { @@ -49,19 +44,12 @@ static void detectConhost(const FFinstance* instance, FFTerminalFontResult* term ffFontInitValues(&terminalFont->font, fontName.chars, fontSize); } -static void detectConEmu(const FFinstance* instance, FFTerminalFontResult* terminalFont) +static void detectConEmu(FFTerminalFontResult* terminalFont) { - FF_UNUSED(instance) - //https://conemu.github.io/en/ConEmuXml.html#search-sequence - FFstrbuf path; - ffStrbufInit(&path); - - FFstrbuf fontName; - ffStrbufInit(&fontName); - - FFstrbuf fontSize; - ffStrbufInit(&fontSize); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); const char* paths[] = { "ConEmuDir", "ConEmuBaseDir", "APPDATA" }; for (uint32_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i) @@ -77,7 +65,6 @@ static void detectConEmu(const FFinstance* instance, FFTerminalFontResult* termi break; } } - ffStrbufDestroy(&path); if(fontName.length == 0 && fontSize.length == 0) { @@ -96,17 +83,14 @@ static void detectConEmu(const FFinstance* instance, FFTerminalFontResult* termi ffStrbufAppendS(&fontSize, "14"); ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&fontSize); } -void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) +void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "mintty") == 0) - detectMintty(instance, terminalFont); + detectMintty(terminalFont); else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "conhost.exe") == 0) - detectConhost(instance, terminalFont); - else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "ConEmuC")) - detectConEmu(instance, terminalFont); + detectConhost(terminalFont); + else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "ConEmu")) + detectConEmu(terminalFont); } diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index 494612bff9..18a9b79c8b 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -2,6 +2,7 @@ #include "common/io/io.h" #include "common/processing.h" #include "common/properties.h" +#include "util/stringUtils.h" #ifdef _WIN32 @@ -40,17 +41,11 @@ static bool getFileVersion(const char* exePath, FFstrbuf* version) static bool getExeVersionRaw(FFstrbuf* exe, FFstrbuf* version) { - bool ok = ffProcessAppendStdOut(version, (char* const[]) { + return ffProcessAppendStdOut(version, (char* const[]) { exe->chars, "--version", NULL }) == NULL; - if (ok) - { - ffStrbufTrim(version, '\n'); - ffStrbufTrim(version, ' '); - } - return ok; } static bool getExeVersionGeneral(FFstrbuf* exe, FFstrbuf* version) @@ -82,7 +77,6 @@ static bool getShellVersionFish(FFstrbuf* exe, FFstrbuf* version) return false; //fish, version 3.6.0 - ffStrbufTrimRight(version, '\n'); ffStrbufSubstrAfterLastC(version, ' '); return true; } @@ -100,11 +94,40 @@ static bool getShellVersionPwsh(FFstrbuf* exe, FFstrbuf* version) if(!getExeVersionRaw(exe, version)) return false; - ffStrbufTrimRight(version, '\n'); ffStrbufSubstrAfterLastC(version, ' '); return true; } +static bool getShellVersionKsh(FFstrbuf* exe, FFstrbuf* version) +{ + if(ffProcessAppendStdErr(version, (char* const[]) { + exe->chars, + "--version", + NULL + }) != NULL) + return false; + + // version sh (AT&T Research) 93u+ 2012-08-01 + ffStrbufSubstrAfterLastC(version, ')'); + ffStrbufTrim(version, ' '); + return true; +} + +static bool getShellVersionOksh(FFstrbuf* exe, FFstrbuf* version) +{ + if(ffProcessAppendStdOut(version, (char* const[]) { + exe->chars, + "-c", + "echo $OKSH_VERSION", + NULL + }) != NULL) + return false; + + //oksh 7.3 + ffStrbufSubstrAfterFirstC(version, ' '); + return true; +} + #ifdef _WIN32 static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version) { @@ -117,7 +140,6 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version) NULL })) return false; - ffStrbufTrimRight(version, '\n'); ffStrbufSubstrAfterLastC(version, ' '); return true; } @@ -137,6 +159,10 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version) return getExeVersionGeneral(exe, version); //tcsh 6.24.07 (Astron) 2022-12-21 (aarch64-apple-darwin) options wide,nls,dl,al,kan,sm,rh,color,filec if(strcasecmp(exeName, "nu") == 0) return getExeVersionRaw(exe, version); //0.73.0 + if(strcasecmp(exeName, "ksh") == 0) + return getShellVersionKsh(exe, version); + if(strcasecmp(exeName, "oksh") == 0) + return getShellVersionOksh(exe, version); if(strcasecmp(exeName, "python") == 0 && getenv("XONSH_VERSION")) { ffStrbufSetS(version, getenv("XONSH_VERSION")); @@ -213,6 +239,30 @@ FF_MAYBE_UNUSED static bool getTerminalVersionMateTerminal(FFstrbuf* exe, FFstrb return version->length > 0; } +FF_MAYBE_UNUSED static bool getTerminalVersionCockpit(FFstrbuf* exe, FFstrbuf* version) +{ + if(!getExeVersionRaw(exe, version)) return false; + + //Version: 295\n... + ffStrbufSubstrBeforeFirstC(version, '\n'); + ffStrbufSubstrAfterFirstC(version, ' '); + return version->length > 0; +} + +FF_MAYBE_UNUSED static bool getTerminalVersionXterm(FFstrbuf* exe, FFstrbuf* version) +{ + if(ffProcessAppendStdOut(version, (char* const[]){ + exe->chars, + "-v", + NULL + })) return false; + + //xterm(273) + ffStrbufTrimRight(version, ')'); + ffStrbufSubstrAfterFirstC(version, '('); + return version->length > 0; +} + #ifdef _WIN32 static bool getTerminalVersionWindowsTerminal(FFstrbuf* exe, FFstrbuf* version) @@ -259,6 +309,9 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe if(ffStrbufIgnCaseEqualS(processName, "konsole")) return getTerminalVersionKonsole(exe, version); + if(ffStrbufIgnCaseEqualS(processName, "yakuake")) + return getExeVersionGeneral(exe, version);//yakuake 22.12.3 + if(ffStrbufIgnCaseEqualS(processName, "xfce4-terminal")) return getExeVersionGeneral(exe, version);//xfce4-terminal 1.0.4 (Xfce 4.18)... @@ -277,6 +330,12 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe if(ffStrbufIgnCaseEqualS(processName, "mate-terminal")) return getTerminalVersionMateTerminal(exe, version); + if(ffStrbufIgnCaseEqualS(processName, "cockpit-bridge")) + return getTerminalVersionCockpit(exe, version); + + if(ffStrbufIgnCaseEqualS(processName, "xterm")) + return getTerminalVersionXterm(exe, version); + #endif #ifdef _WIN32 @@ -284,7 +343,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe if(ffStrbufIgnCaseEqualS(processName, "WindowsTerminal.exe")) return getTerminalVersionWindowsTerminal(exe, version); - if(ffStrbufStartsWithIgnCaseS(processName, "ConEmuC")) + if(ffStrbufStartsWithIgnCaseS(processName, "ConEmu")) return getTerminalVersionConEmu(exe, version); #endif @@ -309,8 +368,8 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe if(termProgram) { if(ffStrbufStartsWithIgnCaseS(processName, termProgram) || // processName ends with `.exe` on Windows - (strcmp(termProgram, "vscode") == 0 && ffStrbufStartsWithIgnCaseS(processName, "code")) || - (strcmp(termProgram, "iTerm.app") == 0 && ffStrbufStartsWithIgnCaseS(processName, "iTermServer-")) + (ffStrEquals(termProgram, "vscode") && ffStrbufStartsWithIgnCaseS(processName, "code")) || + (ffStrEquals(termProgram, "iTerm.app") && ffStrbufStartsWithIgnCaseS(processName, "iTermServer-")) ) { ffStrbufSetS(version, termProgramVersion); return true; diff --git a/src/detection/terminalshell/terminalshell.h b/src/detection/terminalshell/terminalshell.h index f506381bb3..c727b5fdf4 100644 --- a/src/detection/terminalshell/terminalshell.h +++ b/src/detection/terminalshell/terminalshell.h @@ -26,6 +26,6 @@ typedef struct FFTerminalShellResult FFstrbuf userShellVersion; } FFTerminalShellResult; -const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance); +const FFTerminalShellResult* ffDetectTerminalShell(); #endif diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 79b1e584d5..fa8be7e722 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -132,16 +132,17 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid) //Common programs that are between terminal and own process, but are not the shell if( - strcasecmp(name, "sh") == 0 || //This prevents us from detecting things like pipes and redirects, i hope nobody uses plain `sh` as shell - strcasecmp(name, "sudo") == 0 || - strcasecmp(name, "su") == 0 || - strcasecmp(name, "doas") == 0 || - strcasecmp(name, "strace") == 0 || - strcasecmp(name, "sshd") == 0 || - strcasecmp(name, "gdb") == 0 || - strcasecmp(name, "lldb") == 0 || - strcasecmp(name, "guake-wrapped") == 0 || - strcasestr(name, "debug") != NULL + strcasecmp(name, "sh") == 0 || //This prevents us from detecting things like pipes and redirects, i hope nobody uses plain `sh` as shell + strcasecmp(name, "sudo") == 0 || + strcasecmp(name, "su") == 0 || + strcasecmp(name, "strace") == 0 || + strcasecmp(name, "sshd") == 0 || + strcasecmp(name, "gdb") == 0 || + strcasecmp(name, "lldb") == 0 || + strcasecmp(name, "guake-wrapped") == 0 || + strcasestr(name, "debug") != NULL || + strcasestr(name, "command-not-found") != NULL || + ffStrEndsWith(name, ".sh") ) { getTerminalShell(result, ppid); return; @@ -152,6 +153,8 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid) strcasecmp(name, "bash") == 0 || strcasecmp(name, "zsh") == 0 || strcasecmp(name, "ksh") == 0 || + strcasecmp(name, "mksh") == 0 || + strcasecmp(name, "oksh") == 0 || strcasecmp(name, "csh") == 0 || strcasecmp(name, "tcsh") == 0 || strcasecmp(name, "fish") == 0 || @@ -172,6 +175,12 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid) return; } + #ifdef __APPLE__ + // https://github.com/fastfetch-cli/fastfetch/discussions/501 + if (ffStrEndsWith(name, " (figterm)")) + getProcessNameAndPpid(ppid, name, &ppid); + #endif + result->terminalPid = (uint32_t) pid; ffStrbufSetS(&result->terminalProcessName, name); getProcessInformation(pid, &result->terminalProcessName, &result->terminalExe, &result->terminalExeName); @@ -208,6 +217,11 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) getenv("WT_SESSION") != NULL || getenv("WT_PROFILE_ID") != NULL )) term = "Windows Terminal"; + + //ConEmu + if(!ffStrSet(term) && ( + getenv("ConEmuPID") != NULL + )) term = "ConEmu"; #endif //Alacritty @@ -237,15 +251,6 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) if(!ffStrSet(term)) term = getenv("TERM_PROGRAM"); - #ifdef __linux__ - if(!ffStrSet(term)) - { - //We are in WSL but not in Windows Terminal - if(getenv("WSL_DISTRO") != NULL || getenv("WSL_INTEROP") != NULL) - term = "conhost"; - } - #endif - //Normal Terminal if(!ffStrSet(term)) term = getenv("TERM"); @@ -262,9 +267,9 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) } } -static void getUserShellFromEnv(const FFinstance* instance, FFTerminalShellResult* result) +static void getUserShellFromEnv(FFTerminalShellResult* result) { - ffStrbufSet(&result->userShellExe, &instance->state.platform.userShell); + ffStrbufSet(&result->userShellExe, &instance.state.platform.userShell); if(result->userShellExe.length == 0) return; @@ -281,8 +286,7 @@ static void getUserShellFromEnv(const FFinstance* instance, FFTerminalShellResul static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version) { - FFstrbuf command; - ffStrbufInit(&command); + FF_STRBUF_AUTO_DESTROY command = ffStrbufCreate(); ffStrbufAppendS(&command, "printf \"%s\" \"$"); ffStrbufAppendTransformS(&command, exeName, toupper); ffStrbufAppendS(&command, "_VERSION\""); @@ -296,9 +300,7 @@ static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* NULL }); ffStrbufSubstrBeforeFirstC(version, '('); - ffStrbufRemoveStrings(version, 2, "-release", "release"); - - ffStrbufDestroy(&command); + ffStrbufRemoveStrings(version, 2, (const char*[]) { "-release", "release" }); } bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version); @@ -312,10 +314,8 @@ static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* versio bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version); -const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) +const FFTerminalShellResult* ffDetectTerminalShell() { - FF_UNUSED(instance); - static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static FFTerminalShellResult result; static bool init = false; @@ -353,47 +353,47 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) getTerminalShell(&result, getppid()); getTerminalFromEnv(&result); - getUserShellFromEnv(instance, &result); + getUserShellFromEnv(&result); ffStrbufClear(&result.shellVersion); - if(instance->config.shellVersion) - { - getShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion); + getShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion); - if(strcasecmp(result.shellExeName, result.userShellExeName) != 0) - getShellVersion(&result.userShellExe, result.userShellExeName, &result.userShellVersion); - else - ffStrbufSet(&result.userShellVersion, &result.shellVersion); - } + if(strcasecmp(result.shellExeName, result.userShellExeName) != 0) + getShellVersion(&result.userShellExe, result.userShellExeName, &result.userShellVersion); + else + ffStrbufSet(&result.userShellVersion, &result.shellVersion); if(ffStrbufEqualS(&result.shellProcessName, "pwsh")) - ffStrbufInitS(&result.shellPrettyName, "PowerShell"); + ffStrbufInitStatic(&result.shellPrettyName, "PowerShell"); else if(ffStrbufEqualS(&result.shellProcessName, "nu")) - ffStrbufInitS(&result.shellPrettyName, "nushell"); + ffStrbufInitStatic(&result.shellPrettyName, "nushell"); else if(ffStrbufIgnCaseEqualS(&result.shellProcessName, "python") && getenv("XONSH_VERSION")) - ffStrbufInitS(&result.shellPrettyName, "xonsh"); + ffStrbufInitStatic(&result.shellPrettyName, "xonsh"); else { // https://github.com/fastfetch-cli/fastfetch/discussions/280#discussioncomment-3831734 ffStrbufInitS(&result.shellPrettyName, result.shellExeName); } + if(ffStrbufEqualS(&result.terminalProcessName, "wezterm-gui")) - ffStrbufInitS(&result.terminalPrettyName, "WezTerm"); + ffStrbufInitStatic(&result.terminalPrettyName, "WezTerm"); + else if(ffStrbufEqualS(&result.terminalProcessName, ".kitty-wrapped")) + ffStrbufInitStatic(&result.terminalPrettyName, "kitty"); // #510 #if defined(__linux__) || defined(__FreeBSD__) else if(ffStrbufStartsWithS(&result.terminalProcessName, "gnome-terminal-")) - ffStrbufInitS(&result.terminalPrettyName, "gnome-terminal"); + ffStrbufInitStatic(&result.terminalPrettyName, "gnome-terminal"); #elif defined(__APPLE__) else if(ffStrbufEqualS(&result.terminalProcessName, "iTerm.app") || ffStrbufStartsWithS(&result.terminalProcessName, "iTermServer-")) - ffStrbufInitS(&result.terminalPrettyName, "iTerm"); + ffStrbufInitStatic(&result.terminalPrettyName, "iTerm"); else if(ffStrbufEqualS(&result.terminalProcessName, "Apple_Terminal")) - ffStrbufInitS(&result.terminalPrettyName, "Apple Terminal"); + ffStrbufInitStatic(&result.terminalPrettyName, "Apple Terminal"); else if(ffStrbufEqualS(&result.terminalProcessName, "WarpTerminal")) - ffStrbufInitS(&result.terminalPrettyName, "Warp"); + ffStrbufInitStatic(&result.terminalPrettyName, "Warp"); #endif @@ -403,9 +403,7 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) ffStrbufInitCopy(&result.terminalPrettyName, &result.terminalProcessName); ffStrbufInit(&result.terminalVersion); - - if(instance->config.terminalVersion) - fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion); + fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion); ffThreadMutexUnlock(&mutex); return &result; diff --git a/src/detection/terminalshell/terminalshell_windows.c b/src/detection/terminalshell/terminalshell_windows.c index 580252f766..0bd65e5784 100644 --- a/src/detection/terminalshell/terminalshell_windows.c +++ b/src/detection/terminalshell/terminalshell_windows.c @@ -1,7 +1,10 @@ #include "terminalshell.h" +#include "common/io/io.h" #include "common/processing.h" #include "common/thread.h" #include "util/mallocHelper.h" +#include "util/windows/registry.h" +#include "util/windows/unicode.h" #include #include @@ -78,48 +81,9 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb return true; } -static bool getTerminalInfoByEnumeratingChildProcesses(FFTerminalShellResult* result, uint32_t ppid) -{ - ULONG size = 0; - if(NtQuerySystemInformation(SystemProcessInformation, NULL, 0, &size) != STATUS_INFO_LENGTH_MISMATCH) - return false; - - size += sizeof(SystemProcessInformation) * 5; //What if new processes are created during two syscalls? - - SYSTEM_PROCESS_INFORMATION* FF_AUTO_FREE pstart = (SYSTEM_PROCESS_INFORMATION*)malloc(size); - if(!pstart) - return false; - - if(!NT_SUCCESS(NtQuerySystemInformation(SystemProcessInformation, pstart, size, NULL))) - return false; - - uint32_t currentProcessId = (uint32_t) GetCurrentProcessId(); - - for (SYSTEM_PROCESS_INFORMATION* ptr = pstart; ptr->NextEntryOffset; ptr = (SYSTEM_PROCESS_INFORMATION*)((uint8_t*)ptr + ptr->NextEntryOffset)) - { - if ((uint32_t)(uintptr_t) ptr->InheritedFromUniqueProcessId != ppid) - continue; - - uint32_t pid = (uint32_t)(uintptr_t) ptr->UniqueProcessId; - if (pid == currentProcessId) - continue; - - if(!getProcessInfo(pid, NULL, &result->terminalProcessName, &result->terminalExe, &result->terminalExeName)) - return false; - - result->terminalPid = pid; - ffStrbufSet(&result->terminalPrettyName, &result->terminalProcessName); - if(ffStrbufEndsWithIgnCaseS(&result->terminalPrettyName, ".exe")) - ffStrbufSubstrBefore(&result->terminalPrettyName, result->terminalPrettyName.length - 4); - - return true; - } - return false; -} - bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version); -static uint32_t getShellInfo(const FFinstance* instance, FFTerminalShellResult* result, uint32_t pid) +static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) { uint32_t ppid; @@ -143,18 +107,17 @@ static uint32_t getShellInfo(const FFinstance* instance, FFTerminalShellResult* ffStrbufIgnCaseEqualS(&result->shellPrettyName, "fastfetch") || //scoop warps the real binaries with a "shim" exe ffStrbufIgnCaseEqualS(&result->shellPrettyName, "flashfetch") || ffStrbufContainIgnCaseS(&result->shellPrettyName, "debug") || - ffStrbufStartsWithIgnCaseS(&result->shellPrettyName, "ConEmuC") // https://github.com/fastfetch-cli/fastfetch/issues/488#issuecomment-1619982014 + ffStrbufStartsWithIgnCaseS(&result->shellPrettyName, "ConEmu") // https://github.com/fastfetch-cli/fastfetch/issues/488#issuecomment-1619982014 ) { ffStrbufClear(&result->shellProcessName); ffStrbufClear(&result->shellPrettyName); ffStrbufClear(&result->shellExe); result->shellExeName = NULL; - return getShellInfo(instance, result, ppid); + return getShellInfo(result, ppid); } ffStrbufClear(&result->shellVersion); - if(instance->config.shellVersion) - fftsGetShellVersion(&result->shellExe, result->shellPrettyName.chars, &result->shellVersion); + fftsGetShellVersion(&result->shellExe, result->shellPrettyName.chars, &result->shellVersion); result->shellPid = pid; if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "pwsh")) @@ -201,7 +164,128 @@ static uint32_t getShellInfo(const FFinstance* instance, FFTerminalShellResult* return ppid; } -static uint32_t getTerminalInfo(const FFinstance* instance, FFTerminalShellResult* result, uint32_t pid) +static bool getTerminalFromEnv(FFTerminalShellResult* result) +{ + if( + result->terminalProcessName.length > 0 && + ffStrbufIgnCaseCompS(&result->terminalProcessName, "explorer") != 0 + ) return false; + + const char* term = getenv("ConEmuPID"); + + if(term) + { + //ConEmu + uint32_t pid = (uint32_t) strtoul(term, NULL, 10); + result->terminalPid = pid; + if(getProcessInfo(pid, NULL, &result->terminalProcessName, &result->terminalExe, &result->terminalExeName)) + { + ffStrbufSet(&result->terminalPrettyName, &result->terminalProcessName); + if(ffStrbufEndsWithIgnCaseS(&result->terminalPrettyName, ".exe")) + ffStrbufSubstrBefore(&result->terminalPrettyName, result->terminalPrettyName.length - 4); + return true; + } + else + { + term = "ConEmu"; + } + } + + //SSH + if(getenv("SSH_CONNECTION") != NULL) + term = getenv("SSH_TTY"); + + //Windows Terminal + if(!term && ( + getenv("WT_SESSION") != NULL || + getenv("WT_PROFILE_ID") != NULL + )) term = "Windows Terminal"; + + //Alacritty + if(!term && ( + getenv("ALACRITTY_SOCKET") != NULL || + getenv("ALACRITTY_LOG") != NULL || + getenv("ALACRITTY_WINDOW_ID") != NULL + )) term = "Alacritty"; + + if(!term) + term = getenv("TERM_PROGRAM"); + + //Normal Terminal + if(!term) + term = getenv("TERM"); + + if(term) + { + ffStrbufSetS(&result->terminalProcessName, term); + ffStrbufSetS(&result->terminalPrettyName, term); + ffStrbufSetS(&result->terminalExe, term); + result->terminalExeName = ""; + return true; + } + + return false; +} + +static bool detectDefaultTerminal(FFTerminalShellResult* result) +{ + wchar_t regPath[128] = L"SOFTWARE\\Classes\\PackagedCom\\ClassIndex\\"; + wchar_t* uuid = regPath + strlen("SOFTWARE\\Classes\\PackagedCom\\ClassIndex\\"); + DWORD bufSize = 80; + if (RegGetValueW(HKEY_CURRENT_USER, L"Console\\%%Startup", L"DelegationTerminal", RRF_RT_REG_SZ, NULL, uuid, &bufSize) == ERROR_SUCCESS) + { + if(wcscmp(uuid, L"{00000000-0000-0000-0000-000000000000}") == 0) + { + // Let Windows deside + return false; + } + if(wcscmp(uuid, L"{B23D10C0-E52E-411E-9D5B-C09FDF709C7D}") == 0) + { + goto conhost; + } + + FF_HKEY_AUTO_DESTROY hKey = NULL; + if(ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regPath, &hKey, NULL)) + { + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + if(ffRegGetSubKey(hKey, 0, &path, NULL)) + { + if (ffStrbufStartsWithS(&path, "Microsoft.WindowsTerminal")) + { + ffStrbufSetS(&result->terminalProcessName, "WindowsTerminal.exe"); + ffStrbufSetS(&result->terminalPrettyName, "WindowsTerminal"); + ffStrbufSetF(&result->terminalExe, "%s\\WindowsApps\\%s\\WindowsTerminal.exe", getenv("ProgramFiles"), path.chars); + if(ffPathExists(result->terminalExe.chars, FF_PATHTYPE_FILE)) + { + result->terminalExeName = result->terminalExe.chars + ffStrbufLastIndexC(&result->terminalExe, '\\') + 1; + } + else + { + ffStrbufDestroy(&result->terminalExe); + ffStrbufInitMove(&result->terminalExe, &path); + result->terminalExeName = ""; + } + return true; + } + } + } + } + +conhost: + ffStrbufSetF(&result->terminalExe, "%s\\System32\\conhost.exe", getenv("SystemRoot")); + if(ffPathExists(result->terminalExe.chars, FF_PATHTYPE_FILE)) + { + ffStrbufSetS(&result->terminalProcessName, "conhost.exe"); + ffStrbufSetS(&result->terminalPrettyName, "conhost"); + result->terminalExeName = result->terminalExe.chars + ffStrbufLastIndexC(&result->terminalExe, '\\') + 1; + return true; + } + + ffStrbufClear(&result->terminalExe); + return false; +} + +static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) { uint32_t ppid; @@ -220,98 +304,57 @@ static uint32_t getTerminalInfo(const FFinstance* instance, FFTerminalShellResul ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "fish") || ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "nu") || ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "powershell") || - ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "powershell_ise") + ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "powershell_ise") || + ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "wsl") || // running inside wsl + ffStrbufStartsWithIgnCaseS(&result->terminalPrettyName, "ConEmuC") // wrapper process of ConEmu ) { //We are nested shell ffStrbufClear(&result->terminalProcessName); ffStrbufClear(&result->terminalPrettyName); ffStrbufClear(&result->terminalExe); result->terminalExeName = ""; - return getTerminalInfo(instance, result, ppid); + return getTerminalInfo(result, ppid); } if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "sihost") || ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "explorer") ) { - ffStrbufClear(&result->terminalProcessName); - ffStrbufClear(&result->terminalPrettyName); - ffStrbufClear(&result->terminalExe); - result->terminalExeName = ""; - - // Maybe terminal process is created by shell - if(!getTerminalInfoByEnumeratingChildProcesses(result, result->shellPid)) + // A CUI program created by Windows Explorer will spawn a conhost as its child. + // However the conhost process is just a placeholder; + // The true terminal can be Windows Terminal or others. + if (!getTerminalFromEnv(result) && !detectDefaultTerminal(result)) + { + ffStrbufClear(&result->terminalProcessName); + ffStrbufClear(&result->terminalPrettyName); + ffStrbufClear(&result->terminalExe); + result->terminalExeName = ""; return 0; + } } else result->terminalPid = pid; if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "WindowsTerminal")) - ffStrbufSetS(&result->terminalPrettyName, ffStrbufContainIgnCaseS(&result->terminalExe, ".WindowsTerminalPreview_") + ffStrbufSetStatic(&result->terminalPrettyName, ffStrbufContainIgnCaseS(&result->terminalExe, ".WindowsTerminalPreview_") ? "Windows Terminal Preview" : "Windows Terminal" ); else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "conhost")) - ffStrbufSetS(&result->terminalPrettyName, "Console Window Host"); + ffStrbufSetStatic(&result->terminalPrettyName, "Console Window Host"); else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "Code")) - ffStrbufSetS(&result->terminalPrettyName, "Visual Studio Code"); + ffStrbufSetStatic(&result->terminalPrettyName, "Visual Studio Code"); else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "explorer")) - ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer"); - else if(ffStrbufStartsWithIgnCaseS(&result->terminalPrettyName, "ConEmuC")) - ffStrbufSetS(&result->terminalPrettyName, "ConEmu"); + ffStrbufSetStatic(&result->terminalPrettyName, "Windows Explorer"); else if(ffStrbufEqualS(&result->terminalPrettyName, "wezterm-gui")) - ffStrbufInitS(&result->terminalPrettyName, "WezTerm"); + ffStrbufSetStatic(&result->terminalPrettyName, "WezTerm"); return ppid; } -static void getTerminalFromEnv(FFTerminalShellResult* result) -{ - if( - result->terminalProcessName.length > 0 && - ffStrbufIgnCaseCompS(&result->terminalProcessName, "explorer") != 0 - ) return; - - const char* term = NULL; - - //SSH - if(getenv("SSH_CONNECTION") != NULL) - term = getenv("SSH_TTY"); - - //Windows Terminal - if(!term && ( - getenv("WT_SESSION") != NULL || - getenv("WT_PROFILE_ID") != NULL - )) term = "Windows Terminal"; - - //Alacritty - if(!term && ( - getenv("ALACRITTY_SOCKET") != NULL || - getenv("ALACRITTY_LOG") != NULL || - getenv("ALACRITTY_WINDOW_ID") != NULL - )) term = "Alacritty"; - - if(!term) - term = getenv("TERM_PROGRAM"); - - //Normal Terminal - if(!term) - term = getenv("TERM"); - - if(term) - { - ffStrbufSetS(&result->terminalProcessName, term); - ffStrbufSetS(&result->terminalPrettyName, term); - ffStrbufSetS(&result->terminalExe, term); - result->terminalExeName = ""; - } -} - bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version); -const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) +const FFTerminalShellResult* ffDetectTerminalShell(void) { - FF_UNUSED(instance); - static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static FFTerminalShellResult result; static bool init = false; @@ -344,16 +387,15 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) if(!getProcessInfo(0, &ppid, NULL, NULL, NULL)) goto exit; - ppid = getShellInfo(instance, &result, ppid); + ppid = getShellInfo(&result, ppid); if(ppid) - getTerminalInfo(instance, &result, ppid); + getTerminalInfo(&result, ppid); if(result.terminalProcessName.length == 0) getTerminalFromEnv(&result); ffStrbufInit(&result.terminalVersion); - if(instance->config.terminalVersion) - fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion); + fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion); exit: ffThreadMutexUnlock(&mutex); diff --git a/src/detection/terminalsize/terminalsize.h b/src/detection/terminalsize/terminalsize.h new file mode 100644 index 0000000000..b1b51ebe5e --- /dev/null +++ b/src/detection/terminalsize/terminalsize.h @@ -0,0 +1,18 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_terminalsize_terminalsize +#define FF_INCLUDED_detection_terminalsize_terminalsize + +#include "fastfetch.h" + +typedef struct FFTerminalSizeResult +{ + uint16_t rows; + uint16_t columns; + uint16_t width; + uint16_t height; +} FFTerminalSizeResult; + +bool ffDetectTerminalSize(FFTerminalSizeResult* result); + +#endif diff --git a/src/detection/terminalsize/terminalsize_linux.c b/src/detection/terminalsize/terminalsize_linux.c new file mode 100644 index 0000000000..68a75cbb2a --- /dev/null +++ b/src/detection/terminalsize/terminalsize_linux.c @@ -0,0 +1,26 @@ +#include "terminalsize.h" +#include "common/io/io.h" + +#include +#include + +bool ffDetectTerminalSize(FFTerminalSizeResult* result) +{ + struct winsize winsize = {}; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize); + + if (winsize.ws_row == 0 || winsize.ws_col == 0) + ffGetTerminalResponse("\033[18t", "\033[8;%hu;%hut", &winsize.ws_row, &winsize.ws_col); + + if (winsize.ws_ypixel == 0 || winsize.ws_xpixel == 0) + ffGetTerminalResponse("\033[14t", "\033[4;%hu;%hut", &winsize.ws_ypixel, &winsize.ws_xpixel); + + if (winsize.ws_row == 0 && winsize.ws_col == 0) + return false; + + result->rows = winsize.ws_row; + result->columns = winsize.ws_col; + result->width = winsize.ws_xpixel; + result->height = winsize.ws_ypixel; + return true; +} diff --git a/src/detection/terminalsize/terminalsize_windows.c b/src/detection/terminalsize/terminalsize_windows.c new file mode 100644 index 0000000000..a0b5545175 --- /dev/null +++ b/src/detection/terminalsize/terminalsize_windows.c @@ -0,0 +1,41 @@ +#include "terminalsize.h" +#include "common/io/io.h" + +#include + +bool ffDetectTerminalSize(FFTerminalSizeResult* result) +{ + { + CONSOLE_SCREEN_BUFFER_INFO csbi; + if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) + { + result->columns = (uint16_t) (csbi.srWindow.Right - csbi.srWindow.Left + 1); + result->rows = (uint16_t) (csbi.srWindow.Bottom - csbi.srWindow.Top + 1); + } + else + { + ffGetTerminalResponse("\033[18t", "\033[8;%hu;%hut", &result->rows, &result->columns); + } + } + + if (result->columns == 0 && result->rows == 0) + return false; + + { + CONSOLE_FONT_INFO cfi; + if(GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi)) // Only works for ConHost + { + result->width = result->columns * (uint16_t) cfi.dwFontSize.X; + result->height = result->rows * (uint16_t) cfi.dwFontSize.Y; + } + else + { + // Pending https://github.com/microsoft/terminal/issues/8581 + // if (result->width == 0 && result->height == 0) + // ffGetTerminalResponse("\033[14t", "\033[4;%hu;%hut", &result->height, &result->width); + return false; + } + } + + return result->columns > 0 && result->rows > 0; +} diff --git a/src/detection/theme/theme.h b/src/detection/theme/theme.h index 252b4873fe..ec4c596e86 100644 --- a/src/detection/theme/theme.h +++ b/src/detection/theme/theme.h @@ -5,6 +5,6 @@ #include "fastfetch.h" -const char* ffDetectTheme(const FFinstance* instance, FFstrbuf* result); +const char* ffDetectTheme(FFstrbuf* result); #endif diff --git a/src/detection/theme/theme_linux.c b/src/detection/theme/theme_linux.c index bcacf89ea5..1a97f49f43 100644 --- a/src/detection/theme/theme_linux.c +++ b/src/detection/theme/theme_linux.c @@ -3,23 +3,22 @@ #include "detection/gtk_qt/gtk_qt.h" #include "detection/displayserver/displayserver.h" -const char* ffDetectTheme(const FFinstance* instance, FFstrbuf* result) +const char* ffDetectTheme(FFstrbuf* result) { - const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance); + const FFDisplayServerResult* wmde = ffConnectDisplayServer(); if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY) == 0) return "Theme isn't supported in TTY"; - const FFQtResult* plasma = ffDetectQt(instance); - const FFstrbuf* gtk2 = &ffDetectGTK2(instance)->theme; - const FFstrbuf* gtk3 = &ffDetectGTK3(instance)->theme; - const FFstrbuf* gtk4 = &ffDetectGTK4(instance)->theme; + const FFQtResult* plasma = ffDetectQt(); + const FFstrbuf* gtk2 = &ffDetectGTK2()->theme; + const FFstrbuf* gtk3 = &ffDetectGTK3()->theme; + const FFstrbuf* gtk4 = &ffDetectGTK4()->theme; if(plasma->widgetStyle.length == 0 && plasma->colorScheme.length == 0 && gtk2->length == 0 && gtk3->length == 0 && gtk4->length == 0) return "No themes found"; - FF_STRBUF_AUTO_DESTROY plasmaColorPretty; - ffStrbufInit(&plasmaColorPretty); + FF_STRBUF_AUTO_DESTROY plasmaColorPretty = ffStrbufCreate(); if(ffStrbufStartsWithIgnCase(&plasma->colorScheme, &plasma->widgetStyle)) ffStrbufAppendNS(&plasmaColorPretty, plasma->colorScheme.length - plasma->widgetStyle.length, &plasma->colorScheme.chars[plasma->widgetStyle.length]); else @@ -27,8 +26,7 @@ const char* ffDetectTheme(const FFinstance* instance, FFstrbuf* result) ffStrbufTrim(&plasmaColorPretty, ' '); - FF_STRBUF_AUTO_DESTROY gtkPretty; - ffStrbufInit(>kPretty); + FF_STRBUF_AUTO_DESTROY gtkPretty = ffStrbufCreate(); ffParseGTK(>kPretty, gtk2, gtk3, gtk4); if(plasma->widgetStyle.length > 0) diff --git a/src/detection/theme/theme_nosupport.c b/src/detection/theme/theme_nosupport.c index d0e9fd0731..c946833e6f 100644 --- a/src/detection/theme/theme_nosupport.c +++ b/src/detection/theme/theme_nosupport.c @@ -1,6 +1,6 @@ #include "theme.h" -const char* ffDetectTheme(FF_MAYBE_UNUSED const FFinstance* instance, FF_MAYBE_UNUSED FFstrbuf* result) +const char* ffDetectTheme(FF_MAYBE_UNUSED FFstrbuf* result) { return "Not supported on this platform"; } diff --git a/src/detection/uptime/uptime.h b/src/detection/uptime/uptime.h index 6a032b47cd..447b13d5b6 100644 --- a/src/detection/uptime/uptime.h +++ b/src/detection/uptime/uptime.h @@ -5,6 +5,6 @@ #include "fastfetch.h" -uint64_t ffDetectUptime(); +const char* ffDetectUptime(uint64_t* result); #endif diff --git a/src/detection/uptime/uptime_bsd.c b/src/detection/uptime/uptime_bsd.c index 375065c350..4e3a707c6e 100644 --- a/src/detection/uptime/uptime_bsd.c +++ b/src/detection/uptime/uptime_bsd.c @@ -4,7 +4,7 @@ #include #include -uint64_t ffDetectUptime() +const char* ffDetectUptime(uint64_t* result) { struct timeval bootTime; size_t bootTimeSize = sizeof(bootTime); @@ -12,8 +12,10 @@ uint64_t ffDetectUptime() (int[]) {CTL_KERN, KERN_BOOTTIME}, 2, &bootTime, &bootTimeSize, NULL, 0 - ) == 0) - return (uint64_t) difftime(time(NULL), bootTime.tv_sec); + ) != 0) + return "sysctl({CTL_KERN, KERN_BOOTTIME}) failed"; - return 0; + *result = (uint64_t) difftime(time(NULL), bootTime.tv_sec); + + return NULL; } diff --git a/src/detection/uptime/uptime_linux.c b/src/detection/uptime/uptime_linux.c index cf48607711..0339bc7e65 100644 --- a/src/detection/uptime/uptime_linux.c +++ b/src/detection/uptime/uptime_linux.c @@ -2,10 +2,11 @@ #include -uint64_t ffDetectUptime() +const char* ffDetectUptime(uint64_t* result) { struct sysinfo info; if(sysinfo(&info) != 0) - return 0; - return (uint32_t) info.uptime; + return "sysinfo() failed"; + *result = (uint64_t) info.uptime; + return NULL; } diff --git a/src/detection/uptime/uptime_windows.c b/src/detection/uptime/uptime_windows.c index 657af033b8..55053ab246 100644 --- a/src/detection/uptime/uptime_windows.c +++ b/src/detection/uptime/uptime_windows.c @@ -2,7 +2,8 @@ #include -uint64_t ffDetectUptime() +const char* ffDetectUptime(uint64_t* result) { - return GetTickCount64() / 1000; + *result = GetTickCount64() / 1000; + return NULL; } diff --git a/src/detection/users/users_linux.c b/src/detection/users/users_linux.c index 421a6d5d24..3b4963a143 100644 --- a/src/detection/users/users_linux.c +++ b/src/detection/users/users_linux.c @@ -24,7 +24,7 @@ void ffDetectUsers(FFlist* users, FFstrbuf* error) FF_LIST_FOR_EACH(FFstrbuf, user, *users) { - if(ffStrbufCompS(user, n->ut_user) == 0) + if(ffStrbufEqualS(user, n->ut_user)) goto next; } diff --git a/src/detection/vulkan/vulkan.c b/src/detection/vulkan/vulkan.c index 878017e95e..88d687c8e8 100644 --- a/src/detection/vulkan/vulkan.c +++ b/src/detection/vulkan/vulkan.c @@ -38,9 +38,9 @@ static void applyDriverName(VkPhysicalDeviceDriverProperties* properties, FFstrb ffStrbufAppendC(result, ']'); } -static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* result) +static const char* detectVulkan(FFVulkanResult* result) { - FF_LIBRARY_LOAD(vulkan, &instance->config.libVulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed", + FF_LIBRARY_LOAD(vulkan, &instance.config.libVulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed", #ifdef __APPLE__ "libMoltenVK"FF_LIBRARY_EXTENSION, -1 #elif defined(_WIN32) @@ -119,7 +119,7 @@ static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* resu PFN_vkGetPhysicalDeviceMemoryProperties ffvkGetPhysicalDeviceMemoryProperties = NULL; PFN_vkGetPhysicalDeviceMemoryProperties2 ffvkGetPhysicalDeviceMemoryProperties2 = - instance->config.allowSlowOperations ? (PFN_vkGetPhysicalDeviceMemoryProperties2) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties2") : NULL; // 1.1 + instance.config.allowSlowOperations ? (PFN_vkGetPhysicalDeviceMemoryProperties2) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties2") : NULL; // 1.1 if(!ffvkGetPhysicalDeviceMemoryProperties2) ffvkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties"); @@ -245,7 +245,7 @@ static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* resu #endif -const FFVulkanResult* ffDetectVulkan(const FFinstance* instance) +FFVulkanResult* ffDetectVulkan(void) { static FFVulkanResult result; static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; @@ -265,9 +265,8 @@ const FFVulkanResult* ffDetectVulkan(const FFinstance* instance) ffListInit(&result.gpus, sizeof(FFGPUResult)); #ifdef FF_HAVE_VULKAN - result.error = detectVulkan(instance, &result); + result.error = detectVulkan(&result); #else - FF_UNUSED(instance); result.error = "fastfetch was compiled without vulkan support"; #endif diff --git a/src/detection/vulkan/vulkan.h b/src/detection/vulkan/vulkan.h index 559dc3ff77..560fcdc53a 100644 --- a/src/detection/vulkan/vulkan.h +++ b/src/detection/vulkan/vulkan.h @@ -14,6 +14,6 @@ typedef struct FFVulkanResult const char* error; } FFVulkanResult; -const FFVulkanResult* ffDetectVulkan(const FFinstance* instance); +FFVulkanResult* ffDetectVulkan(); #endif diff --git a/src/detection/wallpaper/wallpaper.h b/src/detection/wallpaper/wallpaper.h index 72208eb5b2..f75ad77dd3 100644 --- a/src/detection/wallpaper/wallpaper.h +++ b/src/detection/wallpaper/wallpaper.h @@ -5,6 +5,6 @@ #include "fastfetch.h" -const char* ffDetectWallpaper(const FFinstance* instance, FFstrbuf* result); +const char* ffDetectWallpaper(FFstrbuf* result); #endif diff --git a/src/detection/wallpaper/wallpaper_apple.c b/src/detection/wallpaper/wallpaper_apple.c index f1235ba1e4..4ec1314179 100644 --- a/src/detection/wallpaper/wallpaper_apple.c +++ b/src/detection/wallpaper/wallpaper_apple.c @@ -2,16 +2,15 @@ #include "common/settings.h" #include "util/apple/osascript.h" -const char* ffDetectWallpaper(FF_MAYBE_UNUSED const FFinstance* instance, FFstrbuf* result) +const char* ffDetectWallpaper(FFstrbuf* result) { // https://stackoverflow.com/questions/301215/getting-desktop-background-on-mac #ifdef FF_HAVE_SQLITE3 - FF_STRBUF_AUTO_DESTROY path; - ffStrbufInitCopy(&path, &instance->state.platform.homeDir); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(&instance.state.platform.homeDir); ffStrbufAppendS(&path, "Library/Application Support/Dock/desktoppicture.db"); - if (ffSettingsGetSQLite3String(instance, path.chars, + if (ffSettingsGetSQLite3String(path.chars, "SELECT value\n" "FROM preferences\n" "JOIN data ON preferences.data_id=data.ROWID\n" diff --git a/src/detection/wallpaper/wallpaper_linux.c b/src/detection/wallpaper/wallpaper_linux.c index 7ae5b480d0..d2aa65b6c3 100644 --- a/src/detection/wallpaper/wallpaper_linux.c +++ b/src/detection/wallpaper/wallpaper_linux.c @@ -2,15 +2,15 @@ #include "common/settings.h" #include "detection/gtk_qt/gtk_qt.h" -const char* ffDetectWallpaper(const FFinstance* instance, FFstrbuf* result) +const char* ffDetectWallpaper(FFstrbuf* result) { const FFstrbuf* wallpaper = NULL; - const FFGTKResult* gtk = ffDetectGTK4(instance); + const FFGTKResult* gtk = ffDetectGTK4(); if (gtk->wallpaper.length) wallpaper = >k->wallpaper; else { - const FFQtResult* qt = ffDetectQt(instance); + const FFQtResult* qt = ffDetectQt(); if (qt->wallpaper.length) wallpaper = &qt->wallpaper; } diff --git a/src/detection/wallpaper/wallpaper_nosupport.c b/src/detection/wallpaper/wallpaper_nosupport.c index 92278511d9..787b106af4 100644 --- a/src/detection/wallpaper/wallpaper_nosupport.c +++ b/src/detection/wallpaper/wallpaper_nosupport.c @@ -1,6 +1,6 @@ #include "wallpaper.h" -const char* ffDetectWallpaper(FF_MAYBE_UNUSED const FFinstance* instance, FF_MAYBE_UNUSED FFstrbuf* result) +const char* ffDetectWallpaper(FF_MAYBE_UNUSED FFstrbuf* result) { return "Not supported on this platform"; } diff --git a/src/detection/wallpaper/wallpaper_windows.c b/src/detection/wallpaper/wallpaper_windows.c index aa8b696ad5..7a099cb407 100644 --- a/src/detection/wallpaper/wallpaper_windows.c +++ b/src/detection/wallpaper/wallpaper_windows.c @@ -1,7 +1,7 @@ #include "wallpaper.h" #include "util/windows/registry.h" -const char* ffDetectWallpaper(FF_MAYBE_UNUSED const FFinstance* instance, FFstrbuf* result) +const char* ffDetectWallpaper(FFstrbuf* result) { FF_HKEY_AUTO_DESTROY hKey = NULL; if(!ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Desktop", &hKey, NULL)) diff --git a/src/detection/wifi/wifi.h b/src/detection/wifi/wifi.h index fae5c46ce3..d3257a9efc 100644 --- a/src/detection/wifi/wifi.h +++ b/src/detection/wifi/wifi.h @@ -29,6 +29,6 @@ typedef struct FFWifiResult struct FFWifiConnection conn; } FFWifiResult; -const char* ffDetectWifi(const FFinstance* instance, FFlist* result /*list of FFWifiItem*/); +const char* ffDetectWifi(FFlist* result /*list of FFWifiItem*/); #endif diff --git a/src/detection/wifi/wifi_android.c b/src/detection/wifi/wifi_android.c index 8e6e2b072a..e34f45365b 100644 --- a/src/detection/wifi/wifi_android.c +++ b/src/detection/wifi/wifi_android.c @@ -6,10 +6,16 @@ #define FF_TERMUX_API_PATH FASTFETCH_TARGET_DIR_ROOT "/libexec/termux-api" #define FF_TERMUX_API_PARAM "WifiConnectionInfo" -const char* ffDetectWifi(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* result) +static inline void wrapYyjsonFree(yyjson_doc** doc) { - FF_STRBUF_AUTO_DESTROY buffer; - ffStrbufInit(&buffer); + assert(doc); + if (*doc) + yyjson_doc_free(*doc); +} + +const char* ffDetectWifi(FFlist* result) +{ + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); if(ffProcessAppendStdOut(&buffer, (char* const[]){ FF_TERMUX_API_PATH, @@ -18,8 +24,13 @@ const char* ffDetectWifi(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* res })) return "Starting `" FF_TERMUX_API_PATH " " FF_TERMUX_API_PARAM "` failed"; - if(buffer.chars[0] != '{') - return "`" FF_TERMUX_API_PATH " " FF_TERMUX_API_PARAM "` prints invalid result (not a JSON object)"; + yyjson_doc* __attribute__((__cleanup__(wrapYyjsonFree))) doc = yyjson_read_opts(buffer.chars, buffer.length, 0, NULL, NULL); + if (!doc) + return "Failed to parse wifi connection info"; + + yyjson_val* root = yyjson_doc_get_root(doc); + if (!yyjson_is_obj(root)) + return "Wifi info result is not a JSON object"; FFWifiResult* item = (FFWifiResult*)ffListAdd(result); ffStrbufInit(&item->inf.description); @@ -33,37 +44,22 @@ const char* ffDetectWifi(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* res item->conn.rxRate = 0.0/0.0; item->conn.txRate = 0.0/0.0; - if(!ffParsePropLines(buffer.chars, "\"supplicant_state\": ", &item->inf.status)) - ffStrbufAppendS(&item->inf.status, "Unknown"); - - { - ffStrbufTrimRight(&item->inf.status, ','); - ffStrbufTrim(&item->inf.status, '"'); - if(!ffStrbufEqualS(&item->inf.status, "COMPLETED")) - return NULL; - } - - if(ffParsePropLines(buffer.chars, "\"rssi\": ", &item->inf.description)) - { - double rssi = ffStrbufToDouble(&item->inf.description); - item->conn.signalQuality = rssi >= -50 ? 100 : rssi <= -100 ? 0 : (rssi + 100) * 2; - ffStrbufClear(&item->inf.description); - } - - if(ffParsePropLines(buffer.chars, "\"network_id\": ", &item->inf.description)) - ffStrbufTrimRight(&item->inf.description, ','); - - if(ffParsePropLines(buffer.chars, "\"bssid\": ", &item->conn.macAddress)) + ffStrbufAppendS(&item->inf.status, yyjson_get_str(yyjson_obj_get(root, "supplicant_state"))); + if(!item->inf.status.length) { - ffStrbufTrimRight(&item->conn.macAddress, ','); - ffStrbufTrim(&item->conn.macAddress, '"'); + ffStrbufAppendS(&item->inf.status, "Unknown"); + return NULL; } - if(ffParsePropLines(buffer.chars, "\"ssid\": ", &item->conn.ssid)) - { - ffStrbufTrimRight(&item->conn.ssid, ','); - ffStrbufTrim(&item->conn.ssid, '"'); - } + if(!ffStrbufEqualS(&item->inf.status, "COMPLETED")) + return NULL; + + double rssi = yyjson_get_num(yyjson_obj_get(root, "rssi")); + item->conn.signalQuality = rssi >= -50 ? 100 : rssi <= -100 ? 0 : (rssi + 100) * 2; + + ffStrbufAppendS(&item->inf.description, yyjson_get_str(yyjson_obj_get(root, "ip"))); + ffStrbufAppendS(&item->conn.macAddress, yyjson_get_str(yyjson_obj_get(root, "bssid"))); + ffStrbufAppendS(&item->conn.ssid, yyjson_get_str(yyjson_obj_get(root, "ssid"))); return NULL; } diff --git a/src/detection/wifi/wifi_apple.m b/src/detection/wifi/wifi_apple.m index a83f794859..c6b572012f 100644 --- a/src/detection/wifi/wifi_apple.m +++ b/src/detection/wifi/wifi_apple.m @@ -2,10 +2,8 @@ #import -const char* ffDetectWifi(const FFinstance* instance, FFlist* result) +const char* ffDetectWifi(FFlist* result) { - FF_UNUSED(instance); - NSArray* interfaces = CWWiFiClient.sharedWiFiClient.interfaces; if(!interfaces) return "CWWiFiClient.sharedWiFiClient.interfaces is nil"; diff --git a/src/detection/wifi/wifi_bsd.c b/src/detection/wifi/wifi_bsd.c new file mode 100644 index 0000000000..663c6a4be2 --- /dev/null +++ b/src/detection/wifi/wifi_bsd.c @@ -0,0 +1,61 @@ +#include "wifi.h" +#include "common/processing.h" +#include "common/properties.h" +#include "util/stringUtils.h" + +#include +#include +#include + +const char* ffDetectWifi(FFlist* result) +{ + struct if_nameindex* infs = if_nameindex(); + if(!infs) + return "if_nameindex() failed"; + + for(struct if_nameindex* i = infs; !(i->if_index == 0 && i->if_name == NULL); ++i) + { + if (!ffStrStartsWith(i->if_name, "wlan")) continue; + FF_STRBUF_AUTO_DESTROY ifconfig = ffStrbufCreate(); + if (ffProcessAppendStdOut(&ifconfig, (char* const[]) { + "ifconfig", + i->if_name, + NULL + }) == NULL) + { + FFWifiResult* item = (FFWifiResult*) ffListAdd(result); + ffStrbufInitS(&item->inf.description, i->if_name); + ffStrbufInit(&item->inf.status); + ffStrbufInit(&item->conn.status); + ffStrbufInit(&item->conn.ssid); + ffStrbufInit(&item->conn.macAddress); + ffStrbufInit(&item->conn.protocol); + ffStrbufInit(&item->conn.security); + item->conn.signalQuality = 0.0/0.0; + item->conn.rxRate = 0.0/0.0; + item->conn.txRate = 0.0/0.0; + + ffParsePropLines(ifconfig.chars, "ssid ", &item->conn.ssid); + if (item->conn.ssid.length) ffStrbufSubstrBeforeFirstC(&item->conn.ssid, ' '); + + ffParsePropLines(ifconfig.chars, "ether ", &item->conn.macAddress); + + ffParsePropLines(ifconfig.chars, "media: ", &item->conn.protocol); + if (item->conn.protocol.length) + { + uint32_t index = ffStrbufFirstIndexS(&item->conn.protocol, " mode "); + if (index == item->conn.protocol.length) + ffStrbufClear(&item->conn.protocol); + else + { + ffStrbufSubstrAfter(&item->conn.protocol, index + strlen(" mode ") - 1); + ffStrbufPrependS(&item->conn.protocol, "802."); + } + } + + ffParsePropLines(ifconfig.chars, "status: ", &item->conn.macAddress); + } + } + + return NULL; +} diff --git a/src/detection/wifi/wifi_linux.c b/src/detection/wifi/wifi_linux.c index d0a679fdbc..9a75d587ed 100644 --- a/src/detection/wifi/wifi_linux.c +++ b/src/detection/wifi/wifi_linux.c @@ -1,4 +1,5 @@ #include "wifi.h" +#include "util/stringUtils.h" #include #include @@ -19,9 +20,9 @@ #define NM_802_11_AP_SEC_KEY_MGMT_OWE_TM 0x00001000 #endif -static const char* detectWifiWithLibnm(const FFinstance* instance, FFlist* result) +static const char* detectWifiWithLibnm(FFlist* result) { - FF_LIBRARY_LOAD(nm, &instance->config.libnm, "dlopen libnm failed", "libnm" FF_LIBRARY_EXTENSION, 0); + FF_LIBRARY_LOAD(nm, &instance.config.libnm, "dlopen libnm failed", "libnm" FF_LIBRARY_EXTENSION, 0); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_client_new); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_client_get_devices); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_device_get_iface); @@ -142,17 +143,20 @@ static const char* detectWifiWithLibnm(const FFinstance* instance, FFlist* resul item->conn.signalQuality = ffnm_access_point_get_strength(ap); item->conn.rxRate = ffnm_access_point_get_max_bitrate(ap); - if(instance->config.allowSlowOperations) + FF_STRBUF_AUTO_DESTROY output = ffStrbufCreate(); + if(!ffProcessAppendStdOut(&output, (char* const[]){ + "iw", + "dev", + item->inf.description.chars, + "link", + NULL + })) { - FF_STRBUF_AUTO_DESTROY output; - ffStrbufInit(&output); - if(!ffProcessAppendStdOut(&output, (char* const[]){ - "iw", - "dev", - item->inf.description.chars, - "link", - NULL - }) && ffParsePropLines(output.chars, "tx bitrate: ", &item->conn.protocol)) + if(ffParsePropLines(output.chars, "rx bitrate: ", &item->conn.protocol)) + { + sscanf(item->conn.protocol.chars, "%lf", &item->conn.rxRate); + } + if(ffParsePropLines(output.chars, "tx bitrate: ", &item->conn.protocol)) { if(ffStrbufContainS(&item->conn.protocol, " HE-MCS ")) ffStrbufSetS(&item->conn.protocol, "802.11ax (Wi-Fi 6)"); @@ -162,6 +166,8 @@ static const char* detectWifiWithLibnm(const FFinstance* instance, FFlist* resul ffStrbufSetS(&item->conn.protocol, "802.11n (Wi-Fi 4)"); else ffStrbufSetS(&item->conn.protocol, "802.11a/b/g"); + + sscanf(item->conn.protocol.chars, "%lf", &item->conn.txRate); } } @@ -171,28 +177,28 @@ static const char* detectWifiWithLibnm(const FFinstance* instance, FFlist* resul if ((flags & NM_802_11_AP_FLAGS_PRIVACY) && (wpaFlags == NM_802_11_AP_SEC_NONE) && (rsnFlags == NM_802_11_AP_SEC_NONE)) - ffStrbufAppendS(&item->conn.security, "WEP "); + ffStrbufAppendS(&item->conn.security, "WEP/"); if (wpaFlags != NM_802_11_AP_SEC_NONE) - ffStrbufAppendS(&item->conn.security, "WPA "); + ffStrbufAppendS(&item->conn.security, "WPA/"); if ((rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_PSK) || (rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { - ffStrbufAppendS(&item->conn.security, "WPA2 "); + ffStrbufAppendS(&item->conn.security, "WPA2/"); } if (rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_SAE) { - ffStrbufAppendS(&item->conn.security, "WPA3 "); + ffStrbufAppendS(&item->conn.security, "WPA3/"); } if ((rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_OWE) || (rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) { - ffStrbufAppendS(&item->conn.security, "OWE "); + ffStrbufAppendS(&item->conn.security, "OWE/"); } if ((wpaFlags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) || (rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { - ffStrbufAppendS(&item->conn.security, "802.1X "); + ffStrbufAppendS(&item->conn.security, "802.1X/"); } if (!item->conn.security.length) ffStrbufAppendS(&item->conn.security, "Insecure"); else - ffStrbufTrimRight(&item->conn.security, ' '); + ffStrbufTrimRight(&item->conn.security, '/'); } ffg_object_unref(client); @@ -202,22 +208,24 @@ static const char* detectWifiWithLibnm(const FFinstance* instance, FFlist* resul #endif +#if __has_include() +#define FF_DETECT_WIFI_WITH_IOCTLS + #include "common/io/io.h" #include -#include #include #include #include +#include //TODO: Don't depend on kernel headers -static const char* detectWifiWithIoctls(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* result) +static const char* detectWifiWithIoctls(FFlist* result) { struct if_nameindex* infs = if_nameindex(); if(!infs) return "if_nameindex() failed"; - FFstrbuf path; - ffStrbufInit(&path); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); for(struct if_nameindex* i = infs; !(i->if_index == 0 && i->if_name == NULL); ++i) { @@ -241,7 +249,7 @@ static const char* detectWifiWithIoctls(FF_MAYBE_UNUSED const FFinstance* instan if(!ffAppendFileBuffer(path.chars, &item->inf.status) || !ffStrbufEqualS(&item->inf.status, "up")) continue; - int sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + FF_AUTO_CLOSE_FD int sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if(sock < 0) continue; @@ -254,10 +262,10 @@ static const char* detectWifiWithIoctls(FF_MAYBE_UNUSED const FFinstance* instan if(ioctl(sock, SIOCGIWESSID, &iwr) >= 0) ffStrbufRecalculateLength(&item->conn.ssid); - if(ioctl(sock, SIOCGIWNAME, &iwr) >= 0) + if(ioctl(sock, SIOCGIWNAME, &iwr) >= 0 && !ffStrEqualsIgnCase(iwr.u.name, "IEEE 802.11")) { - if(strncasecmp(iwr.u.name, "IEEE ", 5) == 0) - ffStrbufSetS(&item->conn.protocol, iwr.u.name + 5); + if(ffStrStartsWithIgnCase(iwr.u.name, "IEEE ")) + ffStrbufSetS(&item->conn.protocol, iwr.u.name + strlen("IEEE ")); else ffStrbufSetS(&item->conn.protocol, iwr.u.name); } @@ -269,9 +277,16 @@ static const char* detectWifiWithIoctls(FF_MAYBE_UNUSED const FFinstance* instan ffStrbufTrimRight(&item->conn.macAddress, '-'); } - //FIXME: doesn't work - if(ioctl(sock, SIOCGIWSPY, &iwr) >= 0) - item->conn.signalQuality = iwr.u.qual.level; + struct iw_statistics stats; + iwr.u.data.pointer = &stats; + iwr.u.data.length = sizeof(stats); + iwr.u.data.flags = 0; + + if(ioctl(sock, SIOCGIWSTATS, &iwr) >= 0) + { + int8_t level = (int8_t) stats.qual.level; // https://stackoverflow.com/questions/18079771/wireless-h-how-do-i-print-out-the-signal-level + item->conn.signalQuality = level >= -50 ? 100 : level <= -100 ? 0 : (level + 100) * 2; + } //FIXME: doesn't work struct iw_encode_ext iwe; @@ -303,21 +318,24 @@ static const char* detectWifiWithIoctls(FF_MAYBE_UNUSED const FFinstance* instan break; } } - - close(sock); } if_freenameindex(infs); - ffStrbufDestroy(&path); return NULL; } -const char* ffDetectWifi(const FFinstance* instance, FFlist* result) +#endif + +const char* ffDetectWifi(FFlist* result) { #ifdef FF_HAVE_LIBNM - if(!detectWifiWithLibnm(instance, result)) + if(!detectWifiWithLibnm(result)) return NULL; #endif - return detectWifiWithIoctls(instance, result); + #ifdef FF_DETECT_WIFI_WITH_IOCTLS + return detectWifiWithIoctls(result); + #endif + + return "linux/wireless.h not found during compilation"; } diff --git a/src/detection/wifi/wifi_nosupport.c b/src/detection/wifi/wifi_nosupport.c deleted file mode 100644 index d09116c9b1..0000000000 --- a/src/detection/wifi/wifi_nosupport.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "wifi.h" - -const char* ffDetectWifi(const FFinstance* instance, FFlist* result) -{ - FF_UNUSED(instance, result); - return "Not supported on this platform"; -} diff --git a/src/detection/wifi/wifi_windows.c b/src/detection/wifi/wifi_windows.c index a0bd0af4b0..3b7ac5a1cc 100644 --- a/src/detection/wifi/wifi_windows.c +++ b/src/detection/wifi/wifi_windows.c @@ -41,7 +41,7 @@ static void convertIfStateToString(WLAN_INTERFACE_STATE state, FFstrbuf* result) } } -const char* ffDetectWifi(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* result) +const char* ffDetectWifi(FFlist* result) { FF_LIBRARY_LOAD(wlanapi, NULL, "dlopen wlanapi"FF_LIBRARY_EXTENSION" failed", "wlanapi"FF_LIBRARY_EXTENSION, 1) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wlanapi, WlanOpenHandle) diff --git a/src/detection/wmtheme/wmtheme.h b/src/detection/wmtheme/wmtheme.h index 33a15dd0fb..baf3e1edeb 100644 --- a/src/detection/wmtheme/wmtheme.h +++ b/src/detection/wmtheme/wmtheme.h @@ -5,6 +5,6 @@ #include "fastfetch.h" -bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError); +bool ffDetectWmTheme(FFstrbuf* themeOrError); #endif diff --git a/src/detection/wmtheme/wmtheme_apple.m b/src/detection/wmtheme/wmtheme_apple.m index 817a2cd652..08810b6cc5 100644 --- a/src/detection/wmtheme/wmtheme_apple.m +++ b/src/detection/wmtheme/wmtheme_apple.m @@ -3,10 +3,10 @@ #import -bool ffDetectWmTheme(FF_MAYBE_UNUSED FFinstance* instance, FFstrbuf* themeOrError) +bool ffDetectWmTheme(FFstrbuf* themeOrError) { NSError* error; - NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/.GlobalPreferences.plist", instance->state.platform.homeDir.chars]; + NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/.GlobalPreferences.plist", instance.state.platform.homeDir.chars]; NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName] error:&error]; if(error) diff --git a/src/detection/wmtheme/wmtheme_linux.c b/src/detection/wmtheme/wmtheme_linux.c index e325e0bcea..92eac7cfb2 100644 --- a/src/detection/wmtheme/wmtheme_linux.c +++ b/src/detection/wmtheme/wmtheme_linux.c @@ -6,11 +6,11 @@ #include "detection/displayserver/displayserver.h" #include "util/stringUtils.h" -static bool detectWMThemeFromConfigFile(FFinstance* instance, const char* configFile, const char* themeRegex, const char* defaultValue, FFstrbuf* themeOrError) +static bool detectWMThemeFromConfigFile(const char* configFile, const char* themeRegex, const char* defaultValue, FFstrbuf* themeOrError) { - if(!ffParsePropFileConfig(instance, configFile, themeRegex, themeOrError)) + if(!ffParsePropFileConfig(configFile, themeRegex, themeOrError)) { - ffStrbufInitF(themeOrError, "Config file %s doesn't exist", configFile); + ffStrbufAppendF(themeOrError, "Config file %s doesn't exist", configFile); return false; } @@ -40,9 +40,9 @@ static bool detectWMThemeFromConfigFile(FFinstance* instance, const char* config return true; } -static bool detectWMThemeFromSettings(FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFstrbuf* themeOrError) +static bool detectWMThemeFromSettings(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFstrbuf* themeOrError) { - const char* theme = ffSettingsGet(instance, dconfKey, gsettingsSchemaName, gsettingsPath, gsettingsKey, FF_VARIANT_TYPE_STRING).strValue; + const char* theme = ffSettingsGet(dconfKey, gsettingsSchemaName, gsettingsPath, gsettingsKey, FF_VARIANT_TYPE_STRING).strValue; if(!ffStrSet(theme)) { @@ -54,17 +54,17 @@ static bool detectWMThemeFromSettings(FFinstance* instance, const char* dconfKey return true; } -static bool detectGTKThemeAsWMTheme(FFinstance* instance, FFstrbuf* themeOrError) +static bool detectGTKThemeAsWMTheme(FFstrbuf* themeOrError) { - const FFGTKResult* gtk = ffDetectGTK4(instance); + const FFGTKResult* gtk = ffDetectGTK4(); if(gtk->theme.length > 0) goto ok; - gtk = ffDetectGTK3(instance); + gtk = ffDetectGTK3(); if(gtk->theme.length > 0) goto ok; - gtk = ffDetectGTK2(instance); + gtk = ffDetectGTK2(); if(gtk->theme.length > 0) goto ok; @@ -76,22 +76,22 @@ static bool detectGTKThemeAsWMTheme(FFinstance* instance, FFstrbuf* themeOrError return true; } -static bool detectMutter(FFinstance* instance, FFstrbuf* themeOrError) +static bool detectMutter(FFstrbuf* themeOrError) { - const char* theme = ffSettingsGet(instance, "/org/gnome/shell/extensions/user-theme/name", "org.gnome.shell.extensions.user-theme", NULL, "name", FF_VARIANT_TYPE_STRING).strValue; + const char* theme = ffSettingsGet("/org/gnome/shell/extensions/user-theme/name", "org.gnome.shell.extensions.user-theme", NULL, "name", FF_VARIANT_TYPE_STRING).strValue; if(ffStrSet(theme)) { ffStrbufAppendS(themeOrError, theme); return true; } - return detectGTKThemeAsWMTheme(instance, themeOrError); + return detectGTKThemeAsWMTheme(themeOrError); } -static bool detectMuffin(FFinstance* instance, FFstrbuf* themeOrError) +static bool detectMuffin(FFstrbuf* themeOrError) { - const char* name = ffSettingsGet(instance, "/org/cinnamon/theme/name", "org.cinnamon.theme", NULL, "name", FF_VARIANT_TYPE_STRING).strValue; - const char* theme = ffSettingsGet(instance, "/org/cinnamon/desktop/wm/preferences/theme", "org.cinnamon.desktop.wm.preferences", NULL, "theme", FF_VARIANT_TYPE_STRING).strValue; + const char* name = ffSettingsGet("/org/cinnamon/theme/name", "org.cinnamon.theme", NULL, "name", FF_VARIANT_TYPE_STRING).strValue; + const char* theme = ffSettingsGet("/org/cinnamon/desktop/wm/preferences/theme", "org.cinnamon.desktop.wm.preferences", NULL, "theme", FF_VARIANT_TYPE_STRING).strValue; if(name == NULL && theme == NULL) { @@ -115,9 +115,9 @@ static bool detectMuffin(FFinstance* instance, FFstrbuf* themeOrError) return true; } -static bool detectXFWM4(FFinstance* instance, FFstrbuf* themeOrError) +static bool detectXFWM4(FFstrbuf* themeOrError) { - const char* theme = ffSettingsGetXFConf(instance, "xfwm4", "/general/theme", FF_VARIANT_TYPE_STRING).strValue; + const char* theme = ffSettingsGetXFConf("xfwm4", "/general/theme", FF_VARIANT_TYPE_STRING).strValue; if(theme == NULL) { @@ -129,11 +129,10 @@ static bool detectXFWM4(FFinstance* instance, FFstrbuf* themeOrError) return true; } -static bool detectOpenbox(FFinstance* instance, const FFstrbuf* dePrettyName, FFstrbuf* themeOrError) +static bool detectOpenbox(const FFstrbuf* dePrettyName, FFstrbuf* themeOrError) { - FFstrbuf absolutePath; - ffStrbufInitA(&absolutePath, 64); - ffStrbufAppend(&absolutePath, &instance->state.platform.homeDir); + FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateA(64); + ffStrbufAppend(&absolutePath, &instance.state.platform.homeDir); //TODO: use config dirs if(ffStrbufIgnCaseCompS(dePrettyName, "LXQT") == 0) @@ -150,7 +149,6 @@ static bool detectOpenbox(FFinstance* instance, const FFstrbuf* dePrettyName, FF if(file == NULL) { ffStrbufAppendF(themeOrError, "Couldn't open \"%s\"", absolutePath.chars); - ffStrbufDestroy(&absolutePath); return false; } @@ -166,7 +164,7 @@ static bool detectOpenbox(FFinstance* instance, const FFstrbuf* dePrettyName, FF if(strstr(line, "") != 0) { ffStrbufAppendS(themeOrError, line); - ffStrbufRemoveStrings(themeOrError, 2, "", ""); + ffStrbufRemoveStrings(themeOrError, 2, (const char*[]) { "", "" }); ffStrbufTrimRight(themeOrError, '\n'); ffStrbufTrim(themeOrError, ' '); break; @@ -184,17 +182,15 @@ static bool detectOpenbox(FFinstance* instance, const FFstrbuf* dePrettyName, FF if(themeOrError->length == 0) { ffStrbufAppendF(themeOrError, "Couldn't find theme name in \"%s\"", absolutePath.chars); - ffStrbufDestroy(&absolutePath); return false; } - ffStrbufDestroy(&absolutePath); return true; } -bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError) +bool ffDetectWmTheme(FFstrbuf* themeOrError) { - const FFDisplayServerResult* wm = ffConnectDisplayServer(instance); + const FFDisplayServerResult* wm = ffConnectDisplayServer(); if(wm->wmPrettyName.length == 0) { @@ -203,27 +199,30 @@ bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError) } if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_KWIN) == 0) - return detectWMThemeFromConfigFile(instance, "kwinrc", "theme =", "Breeze", themeOrError); + return detectWMThemeFromConfigFile("kwinrc", "theme =", "Breeze", themeOrError); if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_XFWM4) == 0) - return detectXFWM4(instance, themeOrError); + return detectXFWM4(themeOrError); if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_MUTTER) == 0) { - if(ffStrbufIgnCaseCompS(&wm->dePrettyName, FF_DE_PRETTY_GNOME) == 0) - return detectMutter(instance, themeOrError); + if( + ffStrbufIgnCaseCompS(&wm->dePrettyName, FF_DE_PRETTY_GNOME) == 0 || + ffStrbufIgnCaseEqualS(&wm->dePrettyName, FF_DE_PRETTY_GNOME_CLASSIC) + ) + return detectMutter(themeOrError); else - return detectGTKThemeAsWMTheme(instance, themeOrError); + return detectGTKThemeAsWMTheme(themeOrError); } if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_MUFFIN) == 0) - return detectMuffin(instance, themeOrError); + return detectMuffin(themeOrError); if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_MARCO) == 0) - return detectWMThemeFromSettings(instance, "/org/mate/Marco/general/theme", "org.mate.Marco.general", NULL, "theme", themeOrError); + return detectWMThemeFromSettings("/org/mate/Marco/general/theme", "org.mate.Marco.general", NULL, "theme", themeOrError); if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_OPENBOX) == 0) - return detectOpenbox(instance, &wm->dePrettyName, themeOrError); + return detectOpenbox(&wm->dePrettyName, themeOrError); ffStrbufAppendS(themeOrError, "Unknown WM: "); ffStrbufAppend(themeOrError, &wm->wmPrettyName); diff --git a/src/detection/wmtheme/wmtheme_nosupport.c b/src/detection/wmtheme/wmtheme_nosupport.c index 1f1dca61cf..2b899e98ca 100644 --- a/src/detection/wmtheme/wmtheme_nosupport.c +++ b/src/detection/wmtheme/wmtheme_nosupport.c @@ -1,9 +1,8 @@ #include "fastfetch.h" #include "wmtheme.h" -bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError) +bool ffDetectWmTheme(FFstrbuf* themeOrError) { - FF_UNUSED(instance); ffStrbufAppendS(themeOrError, "Not supported on this platform"); return false; } diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c index 0522b933b5..5e5cc26e19 100644 --- a/src/detection/wmtheme/wmtheme_windows.c +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -60,14 +60,13 @@ const char* colorHexToString(DWORD hex) } } -bool ffDetectWmTheme(FF_MAYBE_UNUSED FFinstance* instance, FFstrbuf* themeOrError) +bool ffDetectWmTheme(FFstrbuf* themeOrError) { { FF_HKEY_AUTO_DESTROY hKey = NULL; if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes", &hKey, NULL)) { - FF_STRBUF_AUTO_DESTROY theme; - ffStrbufInit(&theme); + FF_STRBUF_AUTO_DESTROY theme = ffStrbufCreate(); if(ffRegReadStrbuf(hKey, L"CurrentTheme", &theme, NULL)) { ffStrbufSubstrBeforeLastC(&theme, '.'); diff --git a/src/fastfetch.c b/src/fastfetch.c index 117ed9d476..e0e32f9d71 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -3,8 +3,10 @@ #include "common/parsing.h" #include "common/io/io.h" #include "common/time.h" -#include "util/FFvaluestore.h" +#include "common/jsonconfig.h" #include "util/stringUtils.h" +#include "logo/logo.h" +#include "fastfetch_datatext.h" #include #include @@ -15,19 +17,20 @@ #include "util/windows/getline.h" #endif -#pragma GCC diagnostic ignored "-Wsign-conversion" +#include "modules/modules.h" -typedef struct CustomValue +typedef struct FFCustomValue { bool printKey; + FFstrbuf key; FFstrbuf value; -} CustomValue; +} FFCustomValue; // Things only needed by fastfetch typedef struct FFdata { - FFvaluestore customValues; FFstrbuf structure; + FFlist customValues; // List of FFCustomValue bool loadUserConfig; } FFdata; @@ -53,13 +56,13 @@ static inline void printCommandHelp(const char* command) { if(command == NULL) puts(FASTFETCH_DATATEXT_HELP); - else if(strcasecmp(command, "c") == 0 || strcasecmp(command, "color") == 0) + else if(ffStrEqualsIgnCase(command, "c") || ffStrEqualsIgnCase(command, "color")) puts(FASTFETCH_DATATEXT_HELP_COLOR); - else if(strcasecmp(command, "format") == 0) + else if(ffStrEqualsIgnCase(command, "format")) puts(FASTFETCH_DATATEXT_HELP_FORMAT); - else if(strcasecmp(command, "load-config") == 0 || strcasecmp(command, "loadconfig") == 0 || strcasecmp(command, "config") == 0) + else if(ffStrEqualsIgnCase(command, "load-config") || ffStrEqualsIgnCase(command, "loadconfig") || ffStrEqualsIgnCase(command, "config")) puts(FASTFETCH_DATATEXT_HELP_CONFIG); - else if(strcasecmp(command, "os-format") == 0) + else if(ffStrEqualsIgnCase(command, "os-format")) { constructAndPrintCommandHelpFormat("os", "{3} {12}", 12, "System name (typically just Linux)", @@ -76,7 +79,7 @@ static inline void printCommandHelp(const char* command) "Architecture of the OS" ); } - else if(strcasecmp(command, "host-format") == 0) + else if(ffStrEqualsIgnCase(command, "host-format")) { constructAndPrintCommandHelpFormat("host", "{2} {3}", 8, "product family", @@ -89,7 +92,7 @@ static inline void printCommandHelp(const char* command) "sys vendor" ); } - else if(strcasecmp(command, "bios-format") == 0) + else if(ffStrEqualsIgnCase(command, "bios-format")) { constructAndPrintCommandHelpFormat("bios", "{2} {3}", 4, "bios date", @@ -98,7 +101,7 @@ static inline void printCommandHelp(const char* command) "bios version" ); } - else if(strcasecmp(command, "board-format") == 0) + else if(ffStrEqualsIgnCase(command, "board-format")) { constructAndPrintCommandHelpFormat("board", "{2} {3}", 3, "board name", @@ -106,7 +109,7 @@ static inline void printCommandHelp(const char* command) "board version" ); } - else if(strcasecmp(command, "chassis-format") == 0) + else if(ffStrEqualsIgnCase(command, "chassis-format")) { constructAndPrintCommandHelpFormat("chassis", "{2} {3}", 4, "chassis type", @@ -114,7 +117,7 @@ static inline void printCommandHelp(const char* command) "chassis version" ); } - else if(strcasecmp(command, "kernel-format") == 0) + else if(ffStrEqualsIgnCase(command, "kernel-format")) { constructAndPrintCommandHelpFormat("kernel", "{2}", 3, "Kernel sysname", @@ -122,7 +125,7 @@ static inline void printCommandHelp(const char* command) "Kernel version" ); } - else if(strcasecmp(command, "uptime-format") == 0) + else if(ffStrEqualsIgnCase(command, "uptime-format")) { constructAndPrintCommandHelpFormat("uptime", "{} days {} hours {} mins", 4, "Days", @@ -131,15 +134,15 @@ static inline void printCommandHelp(const char* command) "Seconds" ); } - else if(strcasecmp(command, "processes-format") == 0) + else if(ffStrEqualsIgnCase(command, "processes-format")) { constructAndPrintCommandHelpFormat("processes", "{}", 1, "Count" ); } - else if(strcasecmp(command, "packages-format") == 0) + else if(ffStrEqualsIgnCase(command, "packages-format")) { - constructAndPrintCommandHelpFormat("packages", "{2} (pacman){?3}[{3}]{?}, {4} (dpkg), {5} (rpm), {6} (emerge), {7} (eopkg), {8} (xbps), {9} (nix-system), {10} (nix-user), {11} (nix-default), {12} (apk), {13} (pkg), {14} (flatpak-system), {15} (flatpack-user), {16} (snap), {17} (brew), {18} (brew-cask), {19} (port), {20} (scoop), {21} (choco), {22} (pkgtool)", 22, + constructAndPrintCommandHelpFormat("packages", "{2} (pacman){?3}[{3}]{?}, {4} (dpkg), {5} (rpm), {6} (emerge), {7} (eopkg), {8} (xbps), {9} (nix-system), {10} (nix-user), {11} (nix-default), {12} (apk), {13} (pkg), {14} (flatpak-system), {15} (flatpack-user), {16} (snap), {17} (brew), {18} (brew-cask), {19} (port), {20} (scoop), {21} (choco), {22} (pkgtool), {23} (paludis)", 23, "Number of all packages", "Number of pacman packages", "Pacman branch on manjaro", @@ -161,10 +164,11 @@ static inline void printCommandHelp(const char* command) "Number of macports packages", "Number of scoop packages", "Number of choco packages", - "Number of pkgtool packages" + "Number of pkgtool packages", + "Number of paludis packages" ); } - else if(strcasecmp(command, "shell-format") == 0) + else if(ffStrEqualsIgnCase(command, "shell-format")) { constructAndPrintCommandHelpFormat("shell", "{3} {4}", 7, "Shell process name", @@ -176,17 +180,39 @@ static inline void printCommandHelp(const char* command) "User shell version" ); } - else if(strcasecmp(command, "display-format") == 0) + else if(ffStrEqualsIgnCase(command, "display-format")) { - constructAndPrintCommandHelpFormat("display", "{}x{} @ {}Hz", 5, + constructAndPrintCommandHelpFormat("display", "{}x{} @ {}Hz", 7, "Screen width", "Screen height", "Screen refresh rate", "Screen scaled width", - "Screen scaled height" + "Screen scaled height", + "Screen name", + "Screen type", + "Screen rotation" ); } - else if(strcasecmp(command, "de-format") == 0) + else if(ffStrEqualsIgnCase(command, "brightness-format")) + { + constructAndPrintCommandHelpFormat("brightness", "{}", 2, + "Screen brightness", + "Screen name" + ); + } + else if(ffStrEqualsIgnCase(command, "monitor-format")) + { + constructAndPrintCommandHelpFormat("monitor", "{}", 6, + "Display name", + "Display native resolution width in pixels", + "Display native resolution height in pixels", + "Display physical width in millimeters", + "Display physical height in millimeters", + "Display physical diagonal length in inches", + "Display physical pixels per inch (PPI)" + ); + } + else if(ffStrEqualsIgnCase(command, "de-format")) { constructAndPrintCommandHelpFormat("de", "{2} {3}", 3, "DE process name", @@ -194,7 +220,7 @@ static inline void printCommandHelp(const char* command) "DE version" ); } - else if(strcasecmp(command, "wm-format") == 0) + else if(ffStrEqualsIgnCase(command, "wm-format")) { constructAndPrintCommandHelpFormat("wm", "{2} ({3})", 3, "WM process name", @@ -202,31 +228,31 @@ static inline void printCommandHelp(const char* command) "WM protocol name" ); } - else if(strcasecmp(command, "wm-theme-format") == 0) + else if(ffStrEqualsIgnCase(command, "wmtheme-format")) { - constructAndPrintCommandHelpFormat("wm-theme", "{}", 1, + constructAndPrintCommandHelpFormat("wmtheme", "{}", 1, "WM theme name" ); } - else if(strcasecmp(command, "theme-format") == 0) + else if(ffStrEqualsIgnCase(command, "theme-format")) { constructAndPrintCommandHelpFormat("theme", "{}", 1, "Combined themes" ); } - else if(strcasecmp(command, "icons-format") == 0) + else if(ffStrEqualsIgnCase(command, "icons-format")) { constructAndPrintCommandHelpFormat("icons", "{}", 1, "Combined icons" ); } - else if(strcasecmp(command, "wallpaper-format") == 0) + else if(ffStrEqualsIgnCase(command, "wallpaper-format")) { constructAndPrintCommandHelpFormat("wallpaper", "{}", 1, "Wallpaper image file" ); } - else if(strcasecmp(command, "font-format") == 0) + else if(ffStrEqualsIgnCase(command, "font-format")) { constructAndPrintCommandHelpFormat("font", "{} [QT], {} [GTK2], {} [GTK3], {} [GTK4]", 4, "Font 1", @@ -235,14 +261,14 @@ static inline void printCommandHelp(const char* command) "Font 4" ); } - else if(strcasecmp(command, "cursor-format") == 0) + else if(ffStrEqualsIgnCase(command, "cursor-format")) { constructAndPrintCommandHelpFormat("cursor", "{} ({}pt)", 2, "Cursor theme", "Cursor size" ); } - else if(strcasecmp(command, "terminal-format") == 0) + else if(ffStrEqualsIgnCase(command, "terminal-format")) { constructAndPrintCommandHelpFormat("terminal", "{3}", 10, "Terminal process name", @@ -257,16 +283,16 @@ static inline void printCommandHelp(const char* command) "User shell version" ); } - else if(strcasecmp(command, "terminal-font-format") == 0) + else if(ffStrEqualsIgnCase(command, "terminalfont-format")) { - constructAndPrintCommandHelpFormat("terminal-font", "{}", 4, + constructAndPrintCommandHelpFormat("terminalfont", "{}", 4, "Terminal font", "Terminal font name", "Termianl font size", "Terminal font styles" ); } - else if(strcasecmp(command, "cpu-format") == 0) + else if(ffStrEqualsIgnCase(command, "cpu-format")) { constructAndPrintCommandHelpFormat("cpu", "{1} ({5}) @ {7}GHz", 8, "Name", @@ -279,13 +305,13 @@ static inline void printCommandHelp(const char* command) "Temperature" ); } - else if(strcasecmp(command, "cpu-usage-format") == 0) + else if(ffStrEqualsIgnCase(command, "cpu-usage-format")) { constructAndPrintCommandHelpFormat("cpu-usage", "{0}%", 1, "CPU usage without percent mark" ); } - else if(strcasecmp(command, "gpu-format") == 0) + else if(ffStrEqualsIgnCase(command, "gpu-format")) { constructAndPrintCommandHelpFormat("gpu", "{} {}", 6, "GPU vendor", @@ -296,7 +322,7 @@ static inline void printCommandHelp(const char* command) "GPU type" ); } - else if(strcasecmp(command, "memory-format") == 0) + else if(ffStrEqualsIgnCase(command, "memory-format")) { constructAndPrintCommandHelpFormat("memory", "{} / {} ({}%)", 3, "Used size", @@ -304,7 +330,7 @@ static inline void printCommandHelp(const char* command) "Percentage used" ); } - else if(strcasecmp(command, "swap-format") == 0) + else if(ffStrEqualsIgnCase(command, "swap-format")) { constructAndPrintCommandHelpFormat("swap", "{} / {} ({}%)", 3, "Used size", @@ -312,7 +338,7 @@ static inline void printCommandHelp(const char* command) "Percentage used" ); } - else if(strcasecmp(command, "disk-format") == 0) + else if(ffStrEqualsIgnCase(command, "disk-format")) { constructAndPrintCommandHelpFormat("disk", "{1} / {2} ({3}%)", 9, "Size used", @@ -321,12 +347,12 @@ static inline void printCommandHelp(const char* command) "Files used", "Files total", "Files percentage", - "True if removable volume", + "True if external volume", "True if hidden volume", "Filesystem" ); } - else if(strcasecmp(command, "battery-format") == 0) + else if(ffStrEqualsIgnCase(command, "battery-format")) { constructAndPrintCommandHelpFormat("battery", "{}%, {}", 5, "Battery manufactor", @@ -336,7 +362,7 @@ static inline void printCommandHelp(const char* command) "Battery status" ); } - else if(strcasecmp(command, "poweradapter-format") == 0) + else if(ffStrEqualsIgnCase(command, "poweradapter-format")) { constructAndPrintCommandHelpFormat("poweradapter", "{}%, {}", 5, "PowerAdapter watts", @@ -346,25 +372,32 @@ static inline void printCommandHelp(const char* command) "PowerAdapter description" ); } - else if(strcasecmp(command, "locale-format") == 0) + else if(ffStrEqualsIgnCase(command, "lm-format")) + { + constructAndPrintCommandHelpFormat("lm", "{} ({})", 2, + "LM service", + "LM type" + ); + } + else if(ffStrEqualsIgnCase(command, "locale-format")) { constructAndPrintCommandHelpFormat("locale", "{}", 1, "Locale code" ); } - else if(strcasecmp(command, "local-ip-format") == 0) + else if(ffStrEqualsIgnCase(command, "local-ip-format")) { constructAndPrintCommandHelpFormat("local-ip", "{}", 1, "Local IP address" ); } - else if(strcasecmp(command, "public-ip-format") == 0) + else if(ffStrEqualsIgnCase(command, "public-ip-format")) { constructAndPrintCommandHelpFormat("public-ip", "{}", 1, "Public IP address" ); } - else if(strcasecmp(command, "wifi-format") == 0) + else if(ffStrEqualsIgnCase(command, "wifi-format")) { constructAndPrintCommandHelpFormat("wifi", "{4} - {6}", 3, "Interface description", @@ -379,7 +412,7 @@ static inline void printCommandHelp(const char* command) "Connection Security algorithm" ); } - else if(strcasecmp(command, "player-format") == 0) + else if(ffStrEqualsIgnCase(command, "player-format")) { constructAndPrintCommandHelpFormat("player", "{}", 4, "Pretty player name", @@ -388,7 +421,7 @@ static inline void printCommandHelp(const char* command) "URL name" ); } - else if(strcasecmp(command, "media-format") == 0) + else if(ffStrEqualsIgnCase(command, "media-format")) { constructAndPrintCommandHelpFormat("media", "{3} - {1}", 4, "Pretty media name", @@ -397,7 +430,7 @@ static inline void printCommandHelp(const char* command) "Album name" ); } - else if(strcasecmp(command, "datetime-format") == 0 || strcasecmp(command, "date-format") == 0 || strcasecmp(command, "time-format") == 0) + else if(ffStrEqualsIgnCase(command, "datetime-format") == 0 || ffStrEqualsIgnCase(command, "date-format") || ffStrEqualsIgnCase(command, "time-format")) { constructAndPrintCommandHelpFormat("[date][time]", "{1}-{4}-{11} {14}:{18}:{20}", 20, "year", @@ -422,7 +455,7 @@ static inline void printCommandHelp(const char* command) "second with leading zero" ); } - else if(strcasecmp(command, "vulkan-format") == 0) + else if(ffStrEqualsIgnCase(command, "vulkan-format")) { constructAndPrintCommandHelpFormat("vulkan", "{} (driver), {} (api version)", 3, "Driver name", @@ -430,7 +463,7 @@ static inline void printCommandHelp(const char* command) "Conformance version" ); } - else if(strcasecmp(command, "opengl-format") == 0) + else if(ffStrEqualsIgnCase(command, "opengl-format")) { constructAndPrintCommandHelpFormat("opengl", "{}", 3, "version", @@ -439,7 +472,7 @@ static inline void printCommandHelp(const char* command) "shading language version" ); } - else if(strcasecmp(command, "opencl-format") == 0) + else if(ffStrEqualsIgnCase(command, "opencl-format")) { constructAndPrintCommandHelpFormat("opencl", "{}", 3, "version", @@ -447,7 +480,7 @@ static inline void printCommandHelp(const char* command) "vendor" ); } - else if(strcasecmp(command, "bluetooth-format") == 0) + else if(ffStrEqualsIgnCase(command, "bluetooth-format")) { constructAndPrintCommandHelpFormat("bluetooth", "{1} (4%)", 4, "Name", @@ -456,7 +489,7 @@ static inline void printCommandHelp(const char* command) "Battery percentage" ); } - else if(strcasecmp(command, "sound-format") == 0) + else if(ffStrEqualsIgnCase(command, "sound-format")) { constructAndPrintCommandHelpFormat("sound", "{2} (3%)", 4, "Main", @@ -465,7 +498,7 @@ static inline void printCommandHelp(const char* command) "Identifier" ); } - else if(strcasecmp(command, "gamepad-format") == 0) + else if(ffStrEqualsIgnCase(command, "gamepad-format")) { constructAndPrintCommandHelpFormat("gamepad", "{1}", 1, "Name", @@ -476,45 +509,73 @@ static inline void printCommandHelp(const char* command) fprintf(stderr, "No specific help for command %s provided\n", command); } -static void listAvailablePresets(FFinstance* instance) +static void listAvailablePresets(void) { - FF_LIST_FOR_EACH(FFstrbuf, path, instance->state.platform.dataDirs) + FF_LIST_FOR_EACH(FFstrbuf, path, instance.state.platform.dataDirs) { ffStrbufAppendS(path, "fastfetch/presets/"); ffListFilesRecursively(path->chars); } } -static void listAvailableLogos(FFinstance* instance) +static void listAvailableLogos(void) { - FF_LIST_FOR_EACH(FFstrbuf, path, instance->state.platform.dataDirs) + FF_LIST_FOR_EACH(FFstrbuf, path, instance.state.platform.dataDirs) { ffStrbufAppendS(path, "fastfetch/logos/"); ffListFilesRecursively(path->chars); } } -static void listConfigPaths(FFinstance* instance) +static void listConfigPaths(void) { - FF_LIST_FOR_EACH(FFstrbuf, folder, instance->state.platform.configDirs) + FF_LIST_FOR_EACH(FFstrbuf, folder, instance.state.platform.configDirs) { - ffStrbufAppendS(folder, "fastfetch/config.conf"); - printf("%s%s\n", folder->chars, ffPathExists(folder->chars, FF_PATHTYPE_FILE) ? " (*)" : ""); + bool exists = false; + ffStrbufAppendS(folder, "fastfetch/config.jsonc"); + exists = ffPathExists(folder->chars, FF_PATHTYPE_FILE); + if (!exists) + { + ffStrbufSubstrBefore(folder, folder->length - (uint32_t) strlen("jsonc")); + ffStrbufAppendS(folder, "conf"); + exists = ffPathExists(folder->chars, FF_PATHTYPE_FILE); + } + printf("%s%s\n", folder->chars, exists ? " (*)" : ""); } } -static void listDataPaths(FFinstance* instance) +static void listDataPaths(void) { - FF_LIST_FOR_EACH(FFstrbuf, folder, instance->state.platform.dataDirs) + FF_LIST_FOR_EACH(FFstrbuf, folder, instance.state.platform.dataDirs) { ffStrbufAppendS(folder, "fastfetch/"); puts(folder->chars); } } -static void parseOption(FFinstance* instance, FFdata* data, const char* key, const char* value); +static void parseOption(FFdata* data, const char* key, const char* value); + +static bool parseJsoncFile(const char* path) +{ + yyjson_read_err error; + yyjson_doc* doc = yyjson_read_file(path, YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_TRAILING_COMMAS | YYJSON_READ_ALLOW_INF_AND_NAN, NULL, &error); + if (!doc) + { + if (error.code != YYJSON_READ_ERROR_FILE_OPEN) + { + fprintf(stderr, "ERROR: failed to parse JSON config file `%s` at pos %zu: %s\n", path, error.pos, error.msg); + exit(477); + } + return false; + } + if (instance.state.configDoc) + yyjson_doc_free(instance.state.configDoc); // for `--load-config` + + instance.state.configDoc = doc; + return true; +} -static bool parseConfigFile(FFinstance* instance, FFdata* data, const char* path) +static bool parseConfigFile(FFdata* data, const char* path) { FILE* file = fopen(path, "r"); if(file == NULL) @@ -547,7 +608,7 @@ static bool parseConfigFile(FFinstance* instance, FFdata* data, const char* path //If the line has no white space, it is only a key if(valueStart == NULL) { - parseOption(instance, data, lineStart, NULL); + parseOption(data, lineStart, NULL); continue; } @@ -567,7 +628,7 @@ static bool parseConfigFile(FFinstance* instance, FFdata* data, const char* path --lineEnd; } - parseOption(instance, data, lineStart, valueStart); + parseOption(data, lineStart, valueStart); } if(line != NULL) @@ -577,11 +638,23 @@ static bool parseConfigFile(FFinstance* instance, FFdata* data, const char* path return true; } -static void generateConfigFile(FFinstance* instance, bool force) +static void generateConfigFile(bool force, const char* type) { - FFstrbuf* filename = (FFstrbuf*) ffListGet(&instance->state.platform.configDirs, 0); + FFstrbuf* filename = (FFstrbuf*) ffListGet(&instance.state.platform.configDirs, 0); // Paths generated in `init.c/initConfigDirs` end with `/` - ffStrbufAppendS(filename, "fastfetch/config.conf"); + bool isJsonc = false; + if (type) + { + if (ffStrEqualsIgnCase(type, "jsonc")) + isJsonc = true; + else if (!ffStrEqualsIgnCase(type, "conf")) + { + fputs("config type can only be `jsonc` or `conf`\n", stderr); + exit(1); + } + } + + ffStrbufAppendS(filename, isJsonc ? "fastfetch/config.jsonc" : "fastfetch/config.conf"); if (!force && ffPathExists(filename->chars, FF_PATHTYPE_FILE)) { @@ -590,38 +663,55 @@ static void generateConfigFile(FFinstance* instance, bool force) } else { - ffWriteFileData(filename->chars, sizeof(FASTFETCH_DATATEXT_CONFIG_USER), FASTFETCH_DATATEXT_CONFIG_USER); + ffWriteFileData( + filename->chars, + isJsonc ? strlen(FASTFETCH_DATATEXT_CONFIG_USER_JSONC) : strlen(FASTFETCH_DATATEXT_CONFIG_USER), + isJsonc ? FASTFETCH_DATATEXT_CONFIG_USER_JSONC : FASTFETCH_DATATEXT_CONFIG_USER); printf("A sample config file has been written in `%s`\n", filename->chars); exit(0); } } -static void optionParseConfigFile(FFinstance* instance, FFdata* data, const char* key, const char* value) +static void optionParseConfigFile(FFdata* data, const char* key, const char* value) { if(value == NULL) { fprintf(stderr, "Error: usage: %s \n", key); exit(413); } + uint32_t fileNameLen = (uint32_t) strlen(value); + if(fileNameLen == 0) + { + fprintf(stderr, "Error: usage: %s \n", key); + exit(413); + } + + bool isJsonConfig = fileNameLen > strlen(".jsonc") && strcasecmp(value + fileNameLen - strlen(".jsonc"), ".jsonc") == 0; //Try to load as an absolute path - if(parseConfigFile(instance, data, value)) + if(isJsonConfig ? parseJsoncFile(value) : parseConfigFile(data, value)) return; - //Try to load as a relative path + FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateA(128); + if (ffPathExpandEnv(value, &absolutePath)) + { + bool success = isJsonConfig ? parseJsoncFile(value) : parseConfigFile(data, absolutePath.chars); + + if(success) + return; + } - FF_STRBUF_AUTO_DESTROY absolutePath; - ffStrbufInitA(&absolutePath, 128); + //Try to load as a relative path - FF_LIST_FOR_EACH(FFstrbuf, path, instance->state.platform.dataDirs) + FF_LIST_FOR_EACH(FFstrbuf, path, instance.state.platform.dataDirs) { //We need to copy it, because if a config file loads a config file, the value of path must be unchanged ffStrbufSet(&absolutePath, path); ffStrbufAppendS(&absolutePath, "fastfetch/presets/"); ffStrbufAppendS(&absolutePath, value); - bool success = parseConfigFile(instance, data, absolutePath.chars); + bool success = isJsonConfig ? parseJsoncFile(value) : parseConfigFile(data, absolutePath.chars); if(success) return; @@ -633,17 +723,6 @@ static void optionParseConfigFile(FFinstance* instance, FFdata* data, const char exit(414); } -static bool optionParseBoolean(const char* str) -{ - return ( - !ffStrSet(str) || - strcasecmp(str, "true") == 0 || - strcasecmp(str, "yes") == 0 || - strcasecmp(str, "on") == 0 || - strcasecmp(str, "1") == 0 - ); -} - static inline void optionCheckString(const char* key, const char* value, FFstrbuf* buffer) { if(value == NULL) @@ -654,170 +733,18 @@ static inline void optionCheckString(const char* key, const char* value, FFstrbu ffStrbufEnsureFree(buffer, 63); //This is not needed, as ffStrbufSetS will resize capacity if needed, but giving a higher start should improve performance } -static void optionParseString(const char* key, const char* value, FFstrbuf* buffer) -{ - optionCheckString(key, value, buffer); - ffStrbufSetS(buffer, value); -} - -static inline bool startsWith(const char* str, const char* compareTo) -{ - return strncasecmp(str, compareTo, strlen(compareTo)) == 0; -} - -static void optionParseColor(const char* key, const char* value, FFstrbuf* buffer) -{ - optionCheckString(key, value, buffer); - - while(*value != '\0') - { - #define FF_APPEND_COLOR_CODE_COND(prefix, code) \ - if(startsWith(value, #prefix)) { ffStrbufAppendS(buffer, code); value += strlen(#prefix); } - - FF_APPEND_COLOR_CODE_COND(reset_, "0;") - else FF_APPEND_COLOR_CODE_COND(bright_, "1;") - else FF_APPEND_COLOR_CODE_COND(black, "30") - else FF_APPEND_COLOR_CODE_COND(red, "31") - else FF_APPEND_COLOR_CODE_COND(green, "32") - else FF_APPEND_COLOR_CODE_COND(yellow, "33") - else FF_APPEND_COLOR_CODE_COND(blue, "34") - else FF_APPEND_COLOR_CODE_COND(magenta, "35") - else FF_APPEND_COLOR_CODE_COND(cyan, "36") - else FF_APPEND_COLOR_CODE_COND(white, "37") - else - { - ffStrbufAppendC(buffer, *value); - ++value; - } - - #undef FF_APPEND_COLOR_CODE_COND - } -} - -static uint32_t optionParseUInt32(const char* key, const char* value) -{ - if(value == NULL) - { - fprintf(stderr, "Error: usage: %s \n", key); - exit(480); - } - - char* end; - uint32_t num = (uint32_t) strtoul(value, &end, 10); - if(*end != '\0') - { - fprintf(stderr, "Error: usage: %s \n", key); - exit(479); - } - - return num; -} - -static void optionParseCustomValue(FFdata* data, const char* key, const char* value, bool printKey) -{ - if(value == NULL) - { - fprintf(stderr, "Error: usage: %s \n", key); - exit(411); - } - - char* separator = strchr(value, '='); - - if(separator == NULL) - { - fprintf(stderr, "Error: usage: %s , '=' missing\n", key); - exit(412); - } - - *separator = '\0'; - - bool created; - CustomValue* customValue = ffValuestoreSet(&data->customValues, value, &created); - if(created) - ffStrbufInit(&customValue->value); - ffStrbufSetS(&customValue->value, separator + 1); - customValue->printKey = printKey; -} - -static void optionParseEnum(const char* argumentKey, const char* requestedKey, void* result, ...) -{ - if(requestedKey == NULL) - { - fprintf(stderr, "Error: usage: %s \n", argumentKey); - exit(476); - } - - va_list args; - va_start(args, result); - - while(true) - { - const char* key = va_arg(args, const char*); - if(key == NULL) - break; - - int value = va_arg(args, int); //C standard guarantees that enumeration constants are presented as ints - - if(strcasecmp(requestedKey, key) == 0) - { - *(int*)result = value; - va_end(args); - return; - } - } - - va_end(args); - - fprintf(stderr, "Error: unknown %s value: %s\n", argumentKey, requestedKey); - exit(478); -} - -static bool optionParseModuleArgs(const char* argumentKey, const char* value, const char* moduleName, struct FFModuleArgs* result) -{ - const char* pkey = argumentKey; - if(!(pkey[0] == '-' && pkey[1] == '-')) - return false; - - pkey += 2; - uint32_t moduleNameLen = (uint32_t)strlen(moduleName); - if(strncasecmp(pkey, moduleName, moduleNameLen) != 0) - return false; - - pkey += moduleNameLen; - if(pkey[0] != '-') - return false; - - pkey += 1; - if(strcasecmp(pkey, "key") == 0) - { - optionParseString(argumentKey, value, &result->key); - return true; - } - else if(strcasecmp(pkey, "format") == 0) - { - optionParseString(argumentKey, value, &result->outputFormat); - return true; - } - else if(strcasecmp(pkey, "error") == 0) - { - optionParseString(argumentKey, value, &result->errorFormat); - return true; - } - return false; -} - -static void parseOption(FFinstance* instance, FFdata* data, const char* key, const char* value) +static void parseOption(FFdata* data, const char* key, const char* value) { /////////////////////// //Informative options// /////////////////////// - if(strcasecmp(key, "-h") == 0 || strcasecmp(key, "--help") == 0) + if(ffStrEqualsIgnCase(key, "-h") || ffStrEqualsIgnCase(key, "--help")) { printCommandHelp(value); exit(0); } - else if(strcasecmp(key, "-v") == 0 || strcasecmp(key, "--version") == 0) + else if(ffStrEqualsIgnCase(key, "-v") || ffStrEqualsIgnCase(key, "--version")) { #ifndef NDEBUG #define FF_BUILD_TYPE "-debug" @@ -852,74 +779,74 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con exit(0); } - else if(strcasecmp(key, "--version-raw") == 0) + else if(ffStrEqualsIgnCase(key, "--version-raw")) { puts(FASTFETCH_PROJECT_VERSION); exit(0); } - else if(startsWith(key, "--print")) + else if(ffStrStartsWithIgnCase(key, "--print")) { const char* subkey = key + strlen("--print"); - if(strcasecmp(subkey, "-config-system") == 0) + if(ffStrEqualsIgnCase(subkey, "-config-system")) { puts(FASTFETCH_DATATEXT_CONFIG_SYSTEM); exit(0); } - else if(strcasecmp(subkey, "-config-user") == 0) + else if(ffStrEqualsIgnCase(subkey, "-config-user")) { puts(FASTFETCH_DATATEXT_CONFIG_USER); exit(0); } - else if(strcasecmp(subkey, "-structure") == 0) + else if(ffStrEqualsIgnCase(subkey, "-structure")) { puts(FASTFETCH_DATATEXT_STRUCTURE); exit(0); } - else if(strcasecmp(subkey, "-logos") == 0) + else if(ffStrEqualsIgnCase(subkey, "-logos")) { - ffLogoBuiltinPrint(instance); + ffLogoBuiltinPrint(); exit(0); } else goto error; } - else if(startsWith(key, "--list")) + else if(ffStrStartsWithIgnCase(key, "--list")) { const char* subkey = key + strlen("--list"); - if(strcasecmp(subkey, "-modules") == 0) + if(ffStrEqualsIgnCase(subkey, "-modules")) { puts(FASTFETCH_DATATEXT_MODULES); exit(0); } - else if(strcasecmp(subkey, "-presets") == 0) + else if(ffStrEqualsIgnCase(subkey, "-presets")) { - listAvailablePresets(instance); + listAvailablePresets(); exit(0); } - else if(strcasecmp(subkey, "-config-paths") == 0) + else if(ffStrEqualsIgnCase(subkey, "-config-paths")) { - listConfigPaths(instance); + listConfigPaths(); exit(0); } - else if(strcasecmp(subkey, "-data-paths") == 0) + else if(ffStrEqualsIgnCase(subkey, "-data-paths")) { - listDataPaths(instance); + listDataPaths(); exit(0); } - else if(strcasecmp(subkey, "-features") == 0) + else if(ffStrEqualsIgnCase(subkey, "-features")) { ffListFeatures(); exit(0); } - else if(strcasecmp(subkey, "-logos") == 0) + else if(ffStrEqualsIgnCase(subkey, "-logos")) { puts("Builtin logos:"); ffLogoBuiltinList(); puts("\nCustom logos:"); - listAvailableLogos(instance); + listAvailableLogos(); exit(0); } - else if(strcasecmp(subkey, "-logos-autocompletion") == 0) + else if(ffStrEqualsIgnCase(subkey, "-logos-autocompletion")) { ffLogoBuiltinListAutocompletion(); exit(0); @@ -927,428 +854,281 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con else goto error; } + else if(ffStrStartsWithIgnCase(key, "--set")) + { + const char* subkey = key + strlen("--set"); + if(*subkey != '\0' && !ffStrEqualsIgnCase(subkey, "-keyless")) + goto error; + + FF_STRBUF_AUTO_DESTROY customValueStr = ffStrbufCreate(); + ffOptionParseString(key, value, &customValueStr); + uint32_t index = ffStrbufFirstIndexC(&customValueStr, '='); + if(index == 0 || index == customValueStr.length) + { + fprintf(stderr, "Error: usage: %s =\n", key); + exit(477); + } + + FF_STRBUF_AUTO_DESTROY customKey = ffStrbufCreateNS(index, customValueStr.chars); + + FFCustomValue* customValue = NULL; + FF_LIST_FOR_EACH(FFCustomValue, x, data->customValues) + { + if(ffStrbufEqual(&x->key, &customKey)) + { + ffStrbufDestroy(&x->key); + ffStrbufDestroy(&x->value); + customValue = x; + break; + } + } + if(!customValue) customValue = (FFCustomValue*) ffListAdd(&data->customValues); + ffStrbufInitMove(&customValue->key, &customKey); + ffStrbufSubstrAfter(&customValueStr, index); + ffStrbufInitMove(&customValue->value, &customValueStr); + customValue->printKey = *subkey == '\0'; + } /////////////////// //General options// /////////////////// - else if(strcasecmp(key, "-r") == 0 || strcasecmp(key, "--recache") == 0) - instance->config.recache = optionParseBoolean(value); - else if(strcasecmp(key, "--load-config") == 0) - optionParseConfigFile(instance, data, key, value); - else if(strcasecmp(key, "--gen-config") == 0) - generateConfigFile(instance, false); - else if(strcasecmp(key, "--gen-config-force") == 0) - generateConfigFile(instance, true); - else if(strcasecmp(key, "--thread") == 0 || strcasecmp(key, "--multithreading") == 0) - instance->config.multithreading = optionParseBoolean(value); - else if(strcasecmp(key, "--stat") == 0) - { - if((instance->config.stat = optionParseBoolean(value))) - instance->config.showErrors = true; - } - else if(strcasecmp(key, "--allow-slow-operations") == 0) - instance->config.allowSlowOperations = optionParseBoolean(value); - else if(strcasecmp(key, "--escape-bedrock") == 0) - instance->config.escapeBedrock = optionParseBoolean(value); - else if(strcasecmp(key, "--pipe") == 0) - instance->config.pipe = optionParseBoolean(value); - else if(strcasecmp(key, "--load-user-config") == 0) - data->loadUserConfig = optionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "-r") || ffStrEqualsIgnCase(key, "--recache")) + instance.config.recache = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--load-config")) + optionParseConfigFile(data, key, value); + else if(ffStrEqualsIgnCase(key, "--gen-config")) + generateConfigFile(false, value); + else if(ffStrEqualsIgnCase(key, "--gen-config-force")) + generateConfigFile(true, value); + else if(ffStrEqualsIgnCase(key, "--thread") || ffStrEqualsIgnCase(key, "--multithreading")) + instance.config.multithreading = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--stat")) + { + if((instance.config.stat = ffOptionParseBoolean(value))) + instance.config.showErrors = true; + } + else if(ffStrEqualsIgnCase(key, "--allow-slow-operations")) + instance.config.allowSlowOperations = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--escape-bedrock")) + instance.config.escapeBedrock = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--pipe")) + instance.config.pipe = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--load-user-config")) + data->loadUserConfig = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--processing-timeout")) + instance.config.processingTimeout = ffOptionParseInt32(key, value); + + #if defined(__linux__) || defined(__FreeBSD__) + else if(ffStrEqualsIgnCase(key, "--player-name")) + ffOptionParseString(key, value, &instance.config.playerName); + else if (ffStrEqualsIgnCase(key, "--os-file")) + ffOptionParseString(key, value, &instance.config.osFile); + else if(ffStrEqualsIgnCase(key, "--ds-force-drm")) + instance.config.dsForceDrm = ffOptionParseBoolean(value); + #elif defined(_WIN32) + else if (ffStrEqualsIgnCase(key, "--wmi-timeout")) + instance.config.wmiTimeout = ffOptionParseInt32(key, value); + #endif //////////////// //Logo options// //////////////// - else if(strcasecmp(key, "-l") == 0 || strcasecmp(key, "--logo") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - - //this is usally wanted when using the none logo - if(strcasecmp(value, "none") == 0) - { - instance->config.logo.paddingTop = 0; - instance->config.logo.paddingRight = 0; - instance->config.logo.paddingLeft = 0; - instance->config.logo.type = FF_LOGO_TYPE_NONE; - } - } - else if(startsWith(key, "--logo")) - { - const char* subkey = key + strlen("--logo"); - if(strcasecmp(subkey, "-type") == 0) - { - optionParseEnum(key, value, &instance->config.logo.type, - "auto", FF_LOGO_TYPE_AUTO, - "builtin", FF_LOGO_TYPE_BUILTIN, - "file", FF_LOGO_TYPE_FILE, - "file-raw", FF_LOGO_TYPE_FILE_RAW, - "data", FF_LOGO_TYPE_DATA, - "data-raw", FF_LOGO_TYPE_DATA_RAW, - "sixel", FF_LOGO_TYPE_IMAGE_SIXEL, - "kitty", FF_LOGO_TYPE_IMAGE_KITTY, - "iterm", FF_LOGO_TYPE_IMAGE_ITERM, - "chafa", FF_LOGO_TYPE_IMAGE_CHAFA, - "raw", FF_LOGO_TYPE_IMAGE_RAW, - "none", FF_LOGO_TYPE_NONE, - NULL - ); - } - else if(startsWith(subkey, "-color-") && key[13] != '\0' && key[14] == '\0') // matches "--logo-color-*" - { - //Map the number to an array index, so that '1' -> 0, '2' -> 1, etc. - int index = (int)key[13] - 49; - - //Match only --logo-color-[1-9] - if(index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS) - { - fprintf(stderr, "Error: invalid --color-[1-9] index: %c\n", key[13]); - exit(472); - } - - optionParseColor(key, value, &instance->config.logo.colors[index]); - } - else if(strcasecmp(subkey, "-width") == 0) - instance->config.logo.width = optionParseUInt32(key, value); - else if(strcasecmp(subkey, "-height") == 0) - instance->config.logo.height = optionParseUInt32(key, value); - else if(strcasecmp(subkey, "-padding") == 0) - { - uint32_t padding = optionParseUInt32(key, value); - instance->config.logo.paddingLeft = padding; - instance->config.logo.paddingRight = padding; - } - else if(strcasecmp(subkey, "-padding-top") == 0) - instance->config.logo.paddingTop = optionParseUInt32(key, value); - else if(strcasecmp(subkey, "-padding-left") == 0) - instance->config.logo.paddingLeft = optionParseUInt32(key, value); - else if(strcasecmp(subkey, "-padding-right") == 0) - instance->config.logo.paddingRight = optionParseUInt32(key, value); - else if(strcasecmp(subkey, "-print-remaining") == 0) - instance->config.logo.printRemaining = optionParseBoolean(value); - else if(strcasecmp(subkey, "-preserve-aspect-radio") == 0) - instance->config.logo.preserveAspectRadio = optionParseBoolean(value); - else - goto error; - } - else if(strcasecmp(key, "--file") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_FILE; - } - else if(strcasecmp(key, "--file-raw") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_FILE_RAW; - } - else if(strcasecmp(key, "--data") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_DATA; - } - else if(strcasecmp(key, "--data-raw") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_DATA_RAW; - } - else if(strcasecmp(key, "--sixel") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_IMAGE_SIXEL; - } - else if(strcasecmp(key, "--kitty") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_IMAGE_KITTY; - } - else if(strcasecmp(key, "--chafa") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_IMAGE_CHAFA; - } - else if(strcasecmp(key, "--iterm") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_IMAGE_ITERM; - } - else if(strcasecmp(key, "--raw") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_IMAGE_RAW; - } - else if(strcasecmp(key, "--chafa-fg-only") == 0) - instance->config.logo.chafaFgOnly = optionParseBoolean(value); - else if(strcasecmp(key, "--chafa-symbols") == 0) - optionParseString(key, value, &instance->config.logo.chafaSymbols); - else if(strcasecmp(key, "--chafa-canvas-mode") == 0) - instance->config.logo.chafaCanvasMode = optionParseUInt32(key, value); - else if(strcasecmp(key, "--chafa-color-space") == 0) - instance->config.logo.chafaColorSpace = optionParseUInt32(key, value); - else if(strcasecmp(key, "--chafa-dither-mode") == 0) - instance->config.logo.chafaDitherMode = optionParseUInt32(key, value); + else if(ffParseLogoCommandOptions(&instance.config.logo, key, value)) {} /////////////////// //Display options// /////////////////// - else if(strcasecmp(key, "--show-errors") == 0) - instance->config.showErrors = optionParseBoolean(value); - else if(strcasecmp(key, "--disable-linewrap") == 0) - instance->config.disableLinewrap = optionParseBoolean(value); - else if(strcasecmp(key, "--hide-cursor") == 0) - instance->config.hideCursor = optionParseBoolean(value); - else if(strcasecmp(key, "-s") == 0 || strcasecmp(key, "--structure") == 0) - optionParseString(key, value, &data->structure); - else if(strcasecmp(key, "--separator") == 0) - optionParseString(key, value, &instance->config.separator); - else if(strcasecmp(key, "--color-keys") == 0) - optionParseColor(key, value, &instance->config.colorKeys); - else if(strcasecmp(key, "--color-title") == 0) - optionParseColor(key, value, &instance->config.colorTitle); - else if(strcasecmp(key, "-c") == 0 || strcasecmp(key, "--color") == 0) - { - optionParseColor(key, value, &instance->config.colorKeys); - ffStrbufSet(&instance->config.colorTitle, &instance->config.colorKeys); - } - else if(strcasecmp(key, "--set") == 0) - optionParseCustomValue(data, key, value, true); - else if(strcasecmp(key, "--set-keyless") == 0) - optionParseCustomValue(data, key, value, false); - else if(strcasecmp(key, "--binary-prefix") == 0) - { - optionParseEnum(key, value, &instance->config.binaryPrefixType, - "iec", FF_BINARY_PREFIX_TYPE_IEC, - "si", FF_BINARY_PREFIX_TYPE_SI, - "jedec", FF_BINARY_PREFIX_TYPE_JEDEC, - NULL - ); - } + else if(ffStrEqualsIgnCase(key, "--show-errors")) + instance.config.showErrors = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--disable-linewrap")) + instance.config.disableLinewrap = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--hide-cursor")) + instance.config.hideCursor = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "-s") || ffStrEqualsIgnCase(key, "--structure")) + ffOptionParseString(key, value, &data->structure); + else if(ffStrEqualsIgnCase(key, "--separator")) + ffOptionParseString(key, value, &instance.config.keyValueSeparator); + else if(ffStrEqualsIgnCase(key, "--color-keys")) + { + optionCheckString(key, value, &instance.config.colorKeys); + ffOptionParseColor(value, &instance.config.colorKeys); + } + else if(ffStrEqualsIgnCase(key, "--color-title")) + { + optionCheckString(key, value, &instance.config.colorTitle); + ffOptionParseColor(value, &instance.config.colorTitle); + } + else if(ffStrEqualsIgnCase(key, "--bright-color")) + instance.config.brightColor = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "-c") || ffStrEqualsIgnCase(key, "--color")) + { + optionCheckString(key, value, &instance.config.colorKeys); + ffOptionParseColor(value, &instance.config.colorKeys); + ffStrbufSet(&instance.config.colorTitle, &instance.config.colorKeys); + } + else if(ffStrEqualsIgnCase(key, "--binary-prefix")) + { + instance.config.binaryPrefixType = (FFBinaryPrefixType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "iec", FF_BINARY_PREFIX_TYPE_IEC }, + { "si", FF_BINARY_PREFIX_TYPE_SI }, + { "jedec", FF_BINARY_PREFIX_TYPE_JEDEC }, + {} + }); + } + else if(ffStrEqualsIgnCase(key, "--size-ndigits")) + instance.config.sizeNdigits = (uint8_t) ffOptionParseUInt32(key, value); + else if(ffStrEqualsIgnCase(key, "--size-max-prefix")) + { + instance.config.sizeMaxPrefix = (uint8_t) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "B", 0 }, + { "kB", 1 }, + { "MB", 2 }, + { "GB", 3 }, + { "TB", 4 }, + { "PB", 5 }, + { "EB", 6 }, + { "ZB", 7 }, + { "YB", 8 }, + {} + }); + } + else if(ffStrEqualsIgnCase(key, "--temperature-unit")) + { + instance.config.temperatureUnit = (FFTemperatureUnit) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "CELSIUS", FF_TEMPERATURE_UNIT_CELSIUS }, + { "C", FF_TEMPERATURE_UNIT_CELSIUS }, + { "FAHRENHEIT", FF_TEMPERATURE_UNIT_FAHRENHEIT }, + { "F", FF_TEMPERATURE_UNIT_FAHRENHEIT }, + { "KELVIN", FF_TEMPERATURE_UNIT_KELVIN }, + { "K", FF_TEMPERATURE_UNIT_KELVIN }, + {}, + }); + } + else if(ffStrEqualsIgnCase(key, "--percent-type")) + instance.config.percentType = ffOptionParseUInt32(key, value); + else if(ffStrEqualsIgnCase(key, "--no-buffer")) + instance.config.noBuffer = ffOptionParseBoolean(value); /////////////////////// //Module args options// /////////////////////// - else if(optionParseModuleArgs(key, value, "os", &instance->config.os)) {} - else if(optionParseModuleArgs(key, value, "host", &instance->config.host)) {} - else if(optionParseModuleArgs(key, value, "bios", &instance->config.bios)) {} - else if(optionParseModuleArgs(key, value, "board", &instance->config.board)) {} - else if(optionParseModuleArgs(key, value, "chassis", &instance->config.chassis)) {} - else if(optionParseModuleArgs(key, value, "kernel", &instance->config.kernel)) {} - else if(optionParseModuleArgs(key, value, "uptime", &instance->config.uptime)) {} - else if(optionParseModuleArgs(key, value, "processes", &instance->config.processes)) {} - else if(optionParseModuleArgs(key, value, "packages", &instance->config.packages)) {} - else if(optionParseModuleArgs(key, value, "shell", &instance->config.shell)) {} - else if(optionParseModuleArgs(key, value, "display", &instance->config.display)) {} - else if(optionParseModuleArgs(key, value, "brightness", &instance->config.brightness)) {} - else if(optionParseModuleArgs(key, value, "de", &instance->config.de)) {} - else if(optionParseModuleArgs(key, value, "wifi", &instance->config.wifi)) {} - else if(optionParseModuleArgs(key, value, "wm", &instance->config.wm)) {} - else if(optionParseModuleArgs(key, value, "wm-theme", &instance->config.wmTheme)) {} - else if(optionParseModuleArgs(key, value, "theme", &instance->config.theme)) {} - else if(optionParseModuleArgs(key, value, "icons", &instance->config.icons)) {} - else if(optionParseModuleArgs(key, value, "wallpaper", &instance->config.wallpaper)) {} - else if(optionParseModuleArgs(key, value, "font", &instance->config.font)) {} - else if(optionParseModuleArgs(key, value, "cursor", &instance->config.cursor)) {} - else if(optionParseModuleArgs(key, value, "terminal", &instance->config.terminal)) {} - else if(optionParseModuleArgs(key, value, "terminal-font", &instance->config.terminalFont)) {} - else if(optionParseModuleArgs(key, value, "cpu", &instance->config.cpu)) {} - else if(optionParseModuleArgs(key, value, "cpu-usage", &instance->config.cpuUsage)) {} - else if(optionParseModuleArgs(key, value, "gpu", &instance->config.gpu)) {} - else if(optionParseModuleArgs(key, value, "memory", &instance->config.memory)) {} - else if(optionParseModuleArgs(key, value, "swap", &instance->config.swap)) {} - else if(optionParseModuleArgs(key, value, "disk", &instance->config.disk)) {} - else if(optionParseModuleArgs(key, value, "battery", &instance->config.battery)) {} - else if(optionParseModuleArgs(key, value, "poweradapter", &instance->config.powerAdapter)) {} - else if(optionParseModuleArgs(key, value, "locale", &instance->config.locale)) {} - else if(optionParseModuleArgs(key, value, "localip", &instance->config.localIP)) {} - else if(optionParseModuleArgs(key, value, "publicip", &instance->config.publicIP)) {} - else if(optionParseModuleArgs(key, value, "weather", &instance->config.weather)) {} - else if(optionParseModuleArgs(key, value, "player", &instance->config.player)) {} - else if(optionParseModuleArgs(key, value, "media", &instance->config.media)) {} - else if(optionParseModuleArgs(key, value, "datetime", &instance->config.dateTime)) {} - else if(optionParseModuleArgs(key, value, "date", &instance->config.date)) {} - else if(optionParseModuleArgs(key, value, "time", &instance->config.time)) {} - else if(optionParseModuleArgs(key, value, "vulkan", &instance->config.vulkan)) {} - else if(optionParseModuleArgs(key, value, "opengl", &instance->config.openGL)) {} - else if(optionParseModuleArgs(key, value, "opencl", &instance->config.openCL)) {} - else if(optionParseModuleArgs(key, value, "users", &instance->config.users)) {} - else if(optionParseModuleArgs(key, value, "bluetooth", &instance->config.bluetooth)) {} - else if(optionParseModuleArgs(key, value, "sound", &instance->config.sound)) {} - else if(optionParseModuleArgs(key, value, "gamepad", &instance->config.gamepad)) {} + else if(ffParseOSCommandOptions(&instance.config.os, key, value)) {} + else if(ffParseHostCommandOptions(&instance.config.host, key, value)) {} + else if(ffParseOSCommandOptions(&instance.config.os, key, value)) {} + else if(ffParseBiosCommandOptions(&instance.config.bios, key, value)) {} + else if(ffParseBoardCommandOptions(&instance.config.board, key, value)) {} + else if(ffParseChassisCommandOptions(&instance.config.chassis, key, value)) {} + else if(ffParseCommandCommandOptions(&instance.config.command, key, value)) {} + else if(ffParseCustomCommandOptions(&instance.config.custom, key, value)) {} + else if(ffParseKernelCommandOptions(&instance.config.kernel, key, value)) {} + else if(ffParseUptimeCommandOptions(&instance.config.uptime, key, value)) {} + else if(ffParseProcessesCommandOptions(&instance.config.processes, key, value)) {} + else if(ffParsePackagesCommandOptions(&instance.config.packages, key, value)) {} + else if(ffParseShellCommandOptions(&instance.config.shell, key, value)) {} + else if(ffParseDisplayCommandOptions(&instance.config.display, key, value)) {} + else if(ffParseBrightnessCommandOptions(&instance.config.brightness, key, value)) {} + else if(ffParseMonitorCommandOptions(&instance.config.nativeResolution, key, value)) {} + else if(ffParseDECommandOptions(&instance.config.de, key, value)) {} + else if(ffParseWifiCommandOptions(&instance.config.wifi, key, value)) {} + else if(ffParseWMCommandOptions(&instance.config.wm, key, value)) {} + else if(ffParseWMThemeCommandOptions(&instance.config.wmTheme, key, value)) {} + else if(ffParseTitleCommandOptions(&instance.config.title, key, value)) {} + else if(ffParseThemeCommandOptions(&instance.config.theme, key, value)) {} + else if(ffParseIconsCommandOptions(&instance.config.icons, key, value)) {} + else if(ffParseWallpaperCommandOptions(&instance.config.wallpaper, key, value)) {} + else if(ffParseFontCommandOptions(&instance.config.font, key, value)) {} + else if(ffParseCursorCommandOptions(&instance.config.cursor, key, value)) {} + else if(ffParseTerminalCommandOptions(&instance.config.terminal, key, value)) {} + else if(ffParseTerminalFontCommandOptions(&instance.config.terminalFont, key, value)) {} + else if(ffParseTerminalSizeCommandOptions(&instance.config.terminalSize, key, value)) {} + else if(ffParseCPUCommandOptions(&instance.config.cpu, key, value)) {} + else if(ffParseCPUUsageCommandOptions(&instance.config.cpuUsage, key, value)) {} + else if(ffParseGPUCommandOptions(&instance.config.gpu, key, value)) {} + else if(ffParseMemoryCommandOptions(&instance.config.memory, key, value)) {} + else if(ffParseSwapCommandOptions(&instance.config.swap, key, value)) {} + else if(ffParseDiskCommandOptions(&instance.config.disk, key, value)) {} + else if(ffParseBatteryCommandOptions(&instance.config.battery, key, value)) {} + else if(ffParsePowerAdapterCommandOptions(&instance.config.powerAdapter, key, value)) {} + else if(ffParseLocaleCommandOptions(&instance.config.locale, key, value)) {} + else if(ffParseLocalIpCommandOptions(&instance.config.localIP, key, value)) {} + else if(ffParsePublicIpCommandOptions(&instance.config.publicIP, key, value)) {} + else if(ffParseWeatherCommandOptions(&instance.config.weather, key, value)) {} + else if(ffParsePlayerCommandOptions(&instance.config.player, key, value)) {} + else if(ffParseMediaCommandOptions(&instance.config.media, key, value)) {} + else if(ffParseDateTimeCommandOptions(&instance.config.dateTime, key, value)) {} + else if(ffParseVulkanCommandOptions(&instance.config.vulkan, key, value)) {} + else if(ffParseOpenGLCommandOptions(&instance.config.openGL, key, value)) {} + else if(ffParseOpenCLCommandOptions(&instance.config.openCL, key, value)) {} + else if(ffParseUsersCommandOptions(&instance.config.users, key, value)) {} + else if(ffParseBluetoothCommandOptions(&instance.config.bluetooth, key, value)) {} + else if(ffParseSeparatorCommandOptions(&instance.config.separator, key, value)) {} + else if(ffParseSoundCommandOptions(&instance.config.sound, key, value)) {} + else if(ffParseGamepadCommandOptions(&instance.config.gamepad, key, value)) {} + else if(ffParseColorsCommandOptions(&instance.config.colors, key, value)) {} /////////////////// //Library options// /////////////////// - else if(startsWith(key, "--lib")) + else if(ffStrStartsWithIgnCase(key, "--lib")) { const char* subkey = key + strlen("--lib"); - if(strcasecmp(subkey, "-PCI") == 0) - optionParseString(key, value, &instance->config.libPCI); - else if(strcasecmp(subkey, "-vulkan") == 0) - optionParseString(key, value, &instance->config.libVulkan); - else if(strcasecmp(subkey, "-freetype") == 0) - optionParseString(key, value, &instance->config.libfreetype); - else if(strcasecmp(subkey, "-wayland") == 0) - optionParseString(key, value, &instance->config.libWayland); - else if(strcasecmp(subkey, "-xcb-randr") == 0) - optionParseString(key, value, &instance->config.libXcbRandr); - else if(strcasecmp(subkey, "-xcb") == 0) - optionParseString(key, value, &instance->config.libXcb); - else if(strcasecmp(subkey, "-Xrandr") == 0) - optionParseString(key, value, &instance->config.libXrandr); - else if(strcasecmp(subkey, "-X11") == 0) - optionParseString(key, value, &instance->config.libX11); - else if(strcasecmp(subkey, "-gio") == 0) - optionParseString(key, value, &instance->config.libGIO); - else if(strcasecmp(subkey, "-DConf") == 0) - optionParseString(key, value, &instance->config.libDConf); - else if(strcasecmp(subkey, "-dbus") == 0) - optionParseString(key, value, &instance->config.libDBus); - else if(strcasecmp(subkey, "-XFConf") == 0) - optionParseString(key, value, &instance->config.libXFConf); - else if(strcasecmp(subkey, "-sqlite") == 0 || strcasecmp(subkey, "-sqlite3") == 0) - optionParseString(key, value, &instance->config.libSQLite3); - else if(strcasecmp(subkey, "-rpm") == 0) - optionParseString(key, value, &instance->config.librpm); - else if(strcasecmp(subkey, "-imagemagick") == 0) - optionParseString(key, value, &instance->config.libImageMagick); - else if(strcasecmp(subkey, "-z") == 0) - optionParseString(key, value, &instance->config.libZ); - else if(strcasecmp(subkey, "-chafa") == 0) - optionParseString(key, value, &instance->config.libChafa); - else if(strcasecmp(subkey, "-egl") == 0) - optionParseString(key, value, &instance->config.libEGL); - else if(strcasecmp(subkey, "-glx") == 0) - optionParseString(key, value, &instance->config.libGLX); - else if(strcasecmp(subkey, "-osmesa") == 0) - optionParseString(key, value, &instance->config.libOSMesa); - else if(strcasecmp(subkey, "-opencl") == 0) - optionParseString(key, value, &instance->config.libOpenCL); - else if(strcasecmp(subkey, "-cjson") == 0) - optionParseString(key, value, &instance->config.libcJSON); - else if(strcasecmp(subkey, "-wlanapi") == 0) - optionParseString(key, value, &instance->config.libwlanapi); - else if(strcasecmp(key, "-pulse") == 0) - optionParseString(key, value, &instance->config.libPulse); - else if(strcasecmp(subkey, "-nm") == 0) - optionParseString(key, value, &instance->config.libnm); + if(ffStrEqualsIgnCase(subkey, "-PCI")) + ffOptionParseString(key, value, &instance.config.libPCI); + else if(ffStrEqualsIgnCase(subkey, "-vulkan")) + ffOptionParseString(key, value, &instance.config.libVulkan); + else if(ffStrEqualsIgnCase(subkey, "-freetype")) + ffOptionParseString(key, value, &instance.config.libfreetype); + else if(ffStrEqualsIgnCase(subkey, "-wayland")) + ffOptionParseString(key, value, &instance.config.libWayland); + else if(ffStrEqualsIgnCase(subkey, "-xcb-randr")) + ffOptionParseString(key, value, &instance.config.libXcbRandr); + else if(ffStrEqualsIgnCase(subkey, "-xcb")) + ffOptionParseString(key, value, &instance.config.libXcb); + else if(ffStrEqualsIgnCase(subkey, "-Xrandr")) + ffOptionParseString(key, value, &instance.config.libXrandr); + else if(ffStrEqualsIgnCase(subkey, "-X11")) + ffOptionParseString(key, value, &instance.config.libX11); + else if(ffStrEqualsIgnCase(subkey, "-gio")) + ffOptionParseString(key, value, &instance.config.libGIO); + else if(ffStrEqualsIgnCase(subkey, "-DConf")) + ffOptionParseString(key, value, &instance.config.libDConf); + else if(ffStrEqualsIgnCase(subkey, "-dbus")) + ffOptionParseString(key, value, &instance.config.libDBus); + else if(ffStrEqualsIgnCase(subkey, "-XFConf")) + ffOptionParseString(key, value, &instance.config.libXFConf); + else if(ffStrEqualsIgnCase(subkey, "-sqlite") || ffStrEqualsIgnCase(subkey, "-sqlite3")) + ffOptionParseString(key, value, &instance.config.libSQLite3); + else if(ffStrEqualsIgnCase(subkey, "-rpm")) + ffOptionParseString(key, value, &instance.config.librpm); + else if(ffStrEqualsIgnCase(subkey, "-imagemagick")) + ffOptionParseString(key, value, &instance.config.libImageMagick); + else if(ffStrEqualsIgnCase(subkey, "-z")) + ffOptionParseString(key, value, &instance.config.libZ); + else if(ffStrEqualsIgnCase(subkey, "-chafa")) + ffOptionParseString(key, value, &instance.config.libChafa); + else if(ffStrEqualsIgnCase(subkey, "-egl")) + ffOptionParseString(key, value, &instance.config.libEGL); + else if(ffStrEqualsIgnCase(subkey, "-glx")) + ffOptionParseString(key, value, &instance.config.libGLX); + else if(ffStrEqualsIgnCase(subkey, "-osmesa")) + ffOptionParseString(key, value, &instance.config.libOSMesa); + else if(ffStrEqualsIgnCase(subkey, "-opencl")) + ffOptionParseString(key, value, &instance.config.libOpenCL); + else if(ffStrEqualsIgnCase(key, "-pulse")) + ffOptionParseString(key, value, &instance.config.libPulse); + else if(ffStrEqualsIgnCase(subkey, "-nm")) + ffOptionParseString(key, value, &instance.config.libnm); + else if(ffStrEqualsIgnCase(subkey, "-ddcutil")) + ffOptionParseString(key, value, &instance.config.libDdcutil); else goto error; } - ////////////////// - //Module options// - ////////////////// - - else if(strcasecmp(key, "--cpu-temp") == 0) - instance->config.cpuTemp = optionParseBoolean(value); - else if(strcasecmp(key, "--gpu-temp") == 0) - instance->config.gpuTemp = optionParseBoolean(value); - else if(strcasecmp(key, "--gpu-force-vulkan") == 0) - instance->config.gpuForceVulkan = optionParseBoolean(value); - else if(strcasecmp(key, "--battery-temp") == 0) - instance->config.batteryTemp = optionParseBoolean(value); - else if(strcasecmp(key, "--gpu-hide-integrated") == 0) - instance->config.gpuHideIntegrated = optionParseBoolean(value); - else if(strcasecmp(key, "--gpu-hide-discrete") == 0) - instance->config.gpuHideDiscrete = optionParseBoolean(value); - else if(strcasecmp(key, "--title-fqdn") == 0) - instance->config.titleFQDN = optionParseBoolean(value); - else if(strcasecmp(key, "--shell-version") == 0) - instance->config.shellVersion = optionParseBoolean(value); - else if(strcasecmp(key, "--terminal-version") == 0) - instance->config.terminalVersion = optionParseBoolean(value); - else if(strcasecmp(key, "--disk-folders") == 0) - optionParseString(key, value, &instance->config.diskFolders); - else if(strcasecmp(key, "--disk-show-regular") == 0) - optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_REGULAR_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_REGULAR_BIT); - else if(strcasecmp(key, "--disk-show-removable") == 0) - optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_EXTERNAL_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_EXTERNAL_BIT); - else if(strcasecmp(key, "--disk-show-hidden") == 0) - optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_HIDDEN_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_HIDDEN_BIT); - else if(strcasecmp(key, "--disk-show-subvolumes") == 0) - optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_SUBVOLUME_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_SUBVOLUME_BIT); - else if(strcasecmp(key, "--disk-show-unknown") == 0) - optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_UNKNOWN_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_UNKNOWN_BIT); - else if(strcasecmp(key, "--display-compact-type") == 0) - { - optionParseEnum(key, value, &instance->config.displayCompactType, - "none", FF_DISPLAY_COMPACT_TYPE_NONE, - "original", FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT, - "scaled", FF_DISPLAY_COMPACT_TYPE_SCALED_BIT, - NULL); - } - else if(strcasecmp(key, "--display-precise-refresh-rate") == 0) - instance->config.displayPreciseRefreshRate = optionParseBoolean(value); - else if(strcasecmp(key, "--display-detect-name") == 0) - instance->config.displayDetectName = optionParseBoolean(value); - else if(strcasecmp(key, "--bluetooth-show-disconnected") == 0) - instance->config.bluetoothShowDisconnected = optionParseBoolean(value); - else if(strcasecmp(key, "--sound-type") == 0) - { - optionParseEnum(key, value, &instance->config.soundType, - "main", FF_SOUND_TYPE_MAIN, - "active", FF_SOUND_TYPE_ACTIVE, - "all", FF_SOUND_TYPE_ALL, - NULL - ); - } - else if(strcasecmp(key, "--battery-dir") == 0) - optionParseString(key, value, &instance->config.batteryDir); - else if(strcasecmp(key, "--separator-string") == 0) - optionParseString(key, value, &instance->config.separatorString); - else if(strcasecmp(key, "--localip-show-ipv4") == 0) - optionParseBoolean(value) ? (instance->config.localIpShowType |= FF_LOCALIP_TYPE_IPV4_BIT) : (instance->config.localIpShowType &= ~FF_LOCALIP_TYPE_IPV4_BIT); - else if(strcasecmp(key, "--localip-show-ipv6") == 0) - optionParseBoolean(value) ? (instance->config.localIpShowType |= FF_LOCALIP_TYPE_IPV6_BIT) : (instance->config.localIpShowType &= ~FF_LOCALIP_TYPE_IPV6_BIT); - else if(strcasecmp(key, "--localip-show-mac") == 0) - optionParseBoolean(value) ? (instance->config.localIpShowType |= FF_LOCALIP_TYPE_MAC_BIT) : (instance->config.localIpShowType &= ~FF_LOCALIP_TYPE_MAC_BIT); - else if(strcasecmp(key, "--localip-show-loop") == 0) - optionParseBoolean(value) ? (instance->config.localIpShowType |= FF_LOCALIP_TYPE_LOOP_BIT) : (instance->config.localIpShowType &= ~FF_LOCALIP_TYPE_LOOP_BIT); - else if(strcasecmp(key, "--localip-compact") == 0) - optionParseBoolean(value) ? (instance->config.localIpShowType |= FF_LOCALIP_TYPE_COMPACT_BIT) : (instance->config.localIpShowType &= ~FF_LOCALIP_TYPE_COMPACT_BIT); - else if(strcasecmp(key, "--localip-name-prefix") == 0) - optionParseString(key, value, &instance->config.localIpNamePrefix); - else if(strcasecmp(key, "--os-file") == 0) - optionParseString(key, value, &instance->config.osFile); - else if(strcasecmp(key, "--player-name") == 0) - optionParseString(key, value, &instance->config.playerName); - else if(strcasecmp(key, "--publicip-url") == 0) - optionParseString(key, value, &instance->config.publicIpUrl); - else if(strcasecmp(key, "--publicip-timeout") == 0) - instance->config.publicIpTimeout = optionParseUInt32(key, value); - else if(strcasecmp(key, "--weather-output-format") == 0) - optionParseString(key, value, &instance->config.weatherOutputFormat); - else if(strcasecmp(key, "--weather-timeout") == 0) - instance->config.weatherTimeout = optionParseUInt32(key, value); - else if(strcasecmp(key, "--gl") == 0) - { - optionParseEnum(key, value, &instance->config.glType, - "auto", FF_GL_TYPE_AUTO, - "egl", FF_GL_TYPE_EGL, - "glx", FF_GL_TYPE_GLX, - "osmesa", FF_GL_TYPE_OSMESA, - NULL - ); - } - else if(strcasecmp(key, "--percent-type") == 0) - instance->config.percentType = optionParseUInt32(key, value); - else if(strcasecmp(key, "--command-shell") == 0) - optionParseString(key, value, &instance->config.commandShell); - else if(strcasecmp(key, "--command-key") == 0) - { - FFstrbuf* result = (FFstrbuf*) ffListAdd(&instance->config.commandKeys); - ffStrbufInit(result); - optionParseString(key, value, result); - } - else if(strcasecmp(key, "--command-text") == 0) - { - FFstrbuf* result = (FFstrbuf*) ffListAdd(&instance->config.commandTexts); - ffStrbufInit(result); - optionParseString(key, value, result); - } - ////////////////// //Unknown option// ////////////////// @@ -1361,23 +1141,34 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con } } -static void parseConfigFiles(FFinstance* instance, FFdata* data) +static void parseConfigFiles(FFdata* data) { - for(uint32_t i = instance->state.platform.configDirs.length; i > 0; --i) + for(uint32_t i = instance.state.platform.configDirs.length; i > 0; --i) + { + FFstrbuf* dir = ffListGet(&instance.state.platform.configDirs, i - 1); + uint32_t dirLength = dir->length; + + ffStrbufAppendS(dir, "fastfetch/config.jsonc"); + bool success = parseJsoncFile(dir->chars); + ffStrbufSubstrBefore(dir, dirLength); + if (success) return; + } + + for(uint32_t i = instance.state.platform.configDirs.length; i > 0; --i) { if(!data->loadUserConfig) return; - FFstrbuf* dir = ffListGet(&instance->state.platform.configDirs, i - 1); + FFstrbuf* dir = ffListGet(&instance.state.platform.configDirs, i - 1); uint32_t dirLength = dir->length; ffStrbufAppendS(dir, "fastfetch/config.conf"); - parseConfigFile(instance, data, dir->chars); + parseConfigFile(data, dir->chars); ffStrbufSubstrBefore(dir, dirLength); } } -static void parseArguments(FFinstance* instance, FFdata* data, int argc, const char** argv) +static void parseArguments(FFdata* data, int argc, const char** argv) { if(!data->loadUserConfig) return; @@ -1388,204 +1179,282 @@ static void parseArguments(FFinstance* instance, FFdata* data, int argc, const c *argv[i + 1] == '-' && strcasecmp(argv[i], "--separator-string") != 0 // Separator string can start with a - )) { - parseOption(instance, data, argv[i], NULL); + parseOption(data, argv[i], NULL); } else { - parseOption(instance, data, argv[i], argv[i + 1]); + parseOption(data, argv[i], argv[i + 1]); ++i; } } } -static void parseStructureCommand(FFinstance* instance, FFdata* data, const char* line) +static void parseStructureCommand(const char* line, FFlist* customValues) { - CustomValue* customValue = ffValuestoreGet(&data->customValues, line); - if(customValue != NULL) + // handle `--set` and `--set-keyless` + FF_LIST_FOR_EACH(FFCustomValue, customValue, *customValues) { - ffPrintCustom(instance, customValue->printKey ? line : NULL, customValue->value.chars); - return; + if (ffStrbufEqualS(&customValue->key, line)) + { + __attribute__((__cleanup__(ffDestroyCustomOptions))) FFCustomOptions options; + ffInitCustomOptions(&options); + if (customValue->printKey) + ffStrbufAppend(&options.moduleArgs.key, &customValue->key); + ffStrbufAppend(&options.moduleArgs.outputFormat, &customValue->value); + ffPrintCustom(&options); + return; + } } - if(strcasecmp(line, "break") == 0) - ffPrintBreak(instance); - else if(strcasecmp(line, "title") == 0) - ffPrintTitle(instance); - else if(strcasecmp(line, "separator") == 0) - ffPrintSeparator(instance); - else if(strcasecmp(line, "os") == 0) - ffPrintOS(instance); - else if(strcasecmp(line, "host") == 0) - ffPrintHost(instance); - else if(strcasecmp(line, "bios") == 0) - ffPrintBios(instance); - else if(strcasecmp(line, "board") == 0) - ffPrintBoard(instance); - else if(strcasecmp(line, "brightness") == 0) - ffPrintBrightness(instance); - else if(strcasecmp(line, "chassis") == 0) - ffPrintChassis(instance); - else if(strcasecmp(line, "kernel") == 0) - ffPrintKernel(instance); - else if(strcasecmp(line, "uptime") == 0) - ffPrintUptime(instance); - else if(strcasecmp(line, "processes") == 0) - ffPrintProcesses(instance); - else if(strcasecmp(line, "packages") == 0) - ffPrintPackages(instance); - else if(strcasecmp(line, "shell") == 0) - ffPrintShell(instance); - else if(strcasecmp(line, "display") == 0) - ffPrintDisplay(instance); - else if(strcasecmp(line, "desktopenvironment") == 0 || strcasecmp(line, "de") == 0) - ffPrintDesktopEnvironment(instance); - else if(strcasecmp(line, "windowmanager") == 0 || strcasecmp(line, "wm") == 0) - ffPrintWM(instance); - else if(strcasecmp(line, "theme") == 0) - ffPrintTheme(instance); - else if(strcasecmp(line, "wmtheme") == 0) - ffPrintWMTheme(instance); - else if(strcasecmp(line, "icons") == 0) - ffPrintIcons(instance); - else if(strcasecmp(line, "wallpaper") == 0) - ffPrintWallpaper(instance); - else if(strcasecmp(line, "font") == 0) - ffPrintFont(instance); - else if(strcasecmp(line, "cursor") == 0) - ffPrintCursor(instance); - else if(strcasecmp(line, "terminal") == 0) - ffPrintTerminal(instance); - else if(strcasecmp(line, "terminalfont") == 0) - ffPrintTerminalFont(instance); - else if(strcasecmp(line, "cpu") == 0) - ffPrintCPU(instance); - else if(strcasecmp(line, "cpuusage") == 0) - ffPrintCPUUsage(instance); - else if(strcasecmp(line, "gpu") == 0) - ffPrintGPU(instance); - else if(strcasecmp(line, "memory") == 0) - ffPrintMemory(instance); - else if(strcasecmp(line, "swap") == 0) - ffPrintSwap(instance); - else if(strcasecmp(line, "disk") == 0) - ffPrintDisk(instance); - else if(strcasecmp(line, "battery") == 0) - ffPrintBattery(instance); - else if(strcasecmp(line, "poweradapter") == 0) - ffPrintPowerAdapter(instance); - else if(strcasecmp(line, "locale") == 0) - ffPrintLocale(instance); - else if(strcasecmp(line, "localip") == 0) - ffPrintLocalIp(instance); - else if(strcasecmp(line, "publicip") == 0) - ffPrintPublicIp(instance); - else if(strcasecmp(line, "wifi") == 0) - ffPrintWifi(instance); - else if(strcasecmp(line, "weather") == 0) - ffPrintWeather(instance); - else if(strcasecmp(line, "player") == 0) - ffPrintPlayer(instance); - else if(strcasecmp(line, "media") == 0) - ffPrintMedia(instance); - else if(strcasecmp(line, "datetime") == 0) - ffPrintDateTime(instance); - else if(strcasecmp(line, "date") == 0) - ffPrintDate(instance); - else if(strcasecmp(line, "time") == 0) - ffPrintTime(instance); - else if(strcasecmp(line, "colors") == 0) - ffPrintColors(instance); - else if(strcasecmp(line, "vulkan") == 0) - ffPrintVulkan(instance); - else if(strcasecmp(line, "opengl") == 0) - ffPrintOpenGL(instance); - else if(strcasecmp(line, "opencl") == 0) - ffPrintOpenCL(instance); - else if(strcasecmp(line, "users") == 0) - ffPrintUsers(instance); - else if(strcasecmp(line, "command") == 0) - ffPrintCommand(instance); - else if(strcasecmp(line, "bluetooth") == 0) - ffPrintBluetooth(instance); - else if(strcasecmp(line, "sound") == 0) - ffPrintSound(instance); - else if(strcasecmp(line, "gamepad") == 0) - ffPrintGamepad(instance); - else - ffPrintErrorString(instance, line, 0, NULL, NULL, ""); + switch (toupper(line[0])) + { + case 'B': + if(ffStrEqualsIgnCase(line, FF_BATTERY_MODULE_NAME)) + return ffPrintBattery(&instance.config.battery); + if(ffStrEqualsIgnCase(line, FF_BIOS_MODULE_NAME)) + return ffPrintBios(&instance.config.bios); + if(ffStrEqualsIgnCase(line, FF_BLUETOOTH_MODULE_NAME)) + return ffPrintBluetooth(&instance.config.bluetooth); + if(ffStrEqualsIgnCase(line, FF_BOARD_MODULE_NAME)) + return ffPrintBoard(&instance.config.board); + if(ffStrEqualsIgnCase(line, FF_BREAK_MODULE_NAME)) + return ffPrintBreak(); + if(ffStrEqualsIgnCase(line, FF_BRIGHTNESS_MODULE_NAME)) + return ffPrintBrightness(&instance.config.brightness); + break; + case 'C': + if(ffStrEqualsIgnCase(line, FF_CHASSIS_MODULE_NAME)) + return ffPrintChassis(&instance.config.chassis); + if(ffStrEqualsIgnCase(line, FF_COMMAND_MODULE_NAME)) + return ffPrintCommand(&instance.config.command); + if(ffStrEqualsIgnCase(line, FF_CPU_MODULE_NAME)) + return ffPrintCPU(&instance.config.cpu); + if(ffStrEqualsIgnCase(line, FF_CPUUSAGE_MODULE_NAME)) + return ffPrintCPUUsage(&instance.config.cpuUsage); + if(ffStrEqualsIgnCase(line, FF_COLORS_MODULE_NAME)) + return ffPrintColors(&instance.config.colors); + if(ffStrEqualsIgnCase(line, FF_CURSOR_MODULE_NAME)) + return ffPrintCursor(&instance.config.cursor); + if(ffStrEqualsIgnCase(line, FF_CUSTOM_MODULE_NAME)) + return ffPrintCustom(&instance.config.custom); + break; + case 'D': + if(ffStrEqualsIgnCase(line, FF_DATETIME_MODULE_NAME)) + return ffPrintDateTime(&instance.config.dateTime); + if(ffStrEqualsIgnCase(line, FF_DE_MODULE_NAME)) + return ffPrintDE(&instance.config.de); + if(ffStrEqualsIgnCase(line, FF_DISPLAY_MODULE_NAME)) + return ffPrintDisplay(&instance.config.display); + if(ffStrEqualsIgnCase(line, FF_DISK_MODULE_NAME)) + return ffPrintDisk(&instance.config.disk); + break; + case 'F': + if(ffStrEqualsIgnCase(line, FF_FONT_MODULE_NAME)) + return ffPrintFont(&instance.config.font); + break; + case 'G': + if(ffStrEqualsIgnCase(line, FF_GAMEPAD_MODULE_NAME)) + return ffPrintGamepad(&instance.config.gamepad); + if(ffStrEqualsIgnCase(line, FF_GPU_MODULE_NAME)) + return ffPrintGPU(&instance.config.gpu); + break; + case 'H': + if(ffStrEqualsIgnCase(line, FF_HOST_MODULE_NAME)) + return ffPrintHost(&instance.config.host); + break; + case 'I': + if(ffStrEqualsIgnCase(line, FF_ICONS_MODULE_NAME)) + return ffPrintIcons(&instance.config.icons); + break; + case 'K': + if(ffStrEqualsIgnCase(line, FF_KERNEL_MODULE_NAME)) + return ffPrintKernel(&instance.config.kernel); + break; + case 'L': + if(ffStrEqualsIgnCase(line, FF_LM_MODULE_NAME)) + return ffPrintLM(&instance.config.lm); + if(ffStrEqualsIgnCase(line, FF_LOCALE_MODULE_NAME)) + return ffPrintLocale(&instance.config.locale); + if(ffStrEqualsIgnCase(line, FF_LOCALIP_MODULE_NAME)) + return ffPrintLocalIp(&instance.config.localIP); + break; + case 'M': + if(ffStrEqualsIgnCase(line, FF_MEDIA_MODULE_NAME)) + return ffPrintMedia(&instance.config.media); + if(ffStrEqualsIgnCase(line, FF_MEMORY_MODULE_NAME)) + return ffPrintMemory(&instance.config.memory); + if(ffStrEqualsIgnCase(line, FF_MONITOR_MODULE_NAME)) + return ffPrintMonitor(&instance.config.nativeResolution); + break; + case 'O': + if(ffStrEqualsIgnCase(line, FF_OPENCL_MODULE_NAME)) + return ffPrintOpenCL(&instance.config.openCL); + if(ffStrEqualsIgnCase(line, FF_OPENGL_MODULE_NAME)) + return ffPrintOpenGL(&instance.config.openGL); + if(ffStrEqualsIgnCase(line, FF_OS_MODULE_NAME)) + return ffPrintOS(&instance.config.os); + break; + case 'P': + if(ffStrEqualsIgnCase(line, FF_PACKAGES_MODULE_NAME)) + return ffPrintPackages(&instance.config.packages); + if(ffStrEqualsIgnCase(line, FF_PLAYER_MODULE_NAME)) + return ffPrintPlayer(&instance.config.player); + if(ffStrEqualsIgnCase(line, FF_POWERADAPTER_MODULE_NAME)) + return ffPrintPowerAdapter(&instance.config.powerAdapter); + if(ffStrEqualsIgnCase(line, FF_PROCESSES_MODULE_NAME)) + return ffPrintProcesses(&instance.config.processes); + if(ffStrEqualsIgnCase(line, FF_PUBLICIP_MODULE_NAME)) + return ffPrintPublicIp(&instance.config.publicIP); + break; + case 'S': + if(ffStrEqualsIgnCase(line, FF_SEPARATOR_MODULE_NAME)) + return ffPrintSeparator(&instance.config.separator); + if(ffStrEqualsIgnCase(line, FF_SHELL_MODULE_NAME)) + return ffPrintShell(&instance.config.shell); + if(ffStrEqualsIgnCase(line, FF_SOUND_MODULE_NAME)) + return ffPrintSound(&instance.config.sound); + if(ffStrEqualsIgnCase(line, FF_SWAP_MODULE_NAME)) + return ffPrintSwap(&instance.config.swap); + break; + case 'T': + if(ffStrEqualsIgnCase(line, FF_TERMINAL_MODULE_NAME)) + return ffPrintTerminal(&instance.config.terminal); + if(ffStrEqualsIgnCase(line, FF_TERMINALFONT_MODULE_NAME)) + return ffPrintTerminalFont(&instance.config.terminalFont); + if(ffStrEqualsIgnCase(line, FF_TERMINALSIZE_MODULE_NAME)) + return ffPrintTerminalSize(&instance.config.terminalSize); + if(ffStrEqualsIgnCase(line, FF_TITLE_MODULE_NAME)) + return ffPrintTitle(&instance.config.title); + if(ffStrEqualsIgnCase(line, FF_THEME_MODULE_NAME)) + return ffPrintTheme(&instance.config.theme); + break; + case 'U': + if(ffStrEqualsIgnCase(line, FF_UPTIME_MODULE_NAME)) + return ffPrintUptime(&instance.config.uptime); + if(ffStrEqualsIgnCase(line, FF_USERS_MODULE_NAME)) + return ffPrintUsers(&instance.config.users); + break; + case 'V': + if(ffStrEqualsIgnCase(line, FF_VULKAN_MODULE_NAME)) + return ffPrintVulkan(&instance.config.vulkan); + break; + case 'W': + if(ffStrEqualsIgnCase(line, FF_WALLPAPER_MODULE_NAME)) + return ffPrintWallpaper(&instance.config.wallpaper); + if(ffStrEqualsIgnCase(line, FF_WEATHER_MODULE_NAME)) + return ffPrintWeather(&instance.config.weather); + if(ffStrEqualsIgnCase(line, FF_WIFI_MODULE_NAME)) + return ffPrintWifi(&instance.config.wifi); + if(ffStrEqualsIgnCase(line, FF_WM_MODULE_NAME)) + return ffPrintWM(&instance.config.wm); + if(ffStrEqualsIgnCase(line, FF_WMTHEME_MODULE_NAME)) + return ffPrintWMTheme(&instance.config.wmTheme); + break; + } + ffPrintErrorString(line, 0, NULL, NULL, ""); } int main(int argc, const char** argv) { - FFinstance instance; - ffInitInstance(&instance); + ffInitInstance(); //Data stores things only needed for the configuration of fastfetch FFdata data; - ffValuestoreInit(&data.customValues, sizeof(CustomValue)); - ffStrbufInitA(&data.structure, 256); + ffStrbufInit(&data.structure); + ffListInit(&data.customValues, sizeof(FFCustomValue)); data.loadUserConfig = true; if(!getenv("NO_CONFIG")) - parseConfigFiles(&instance, &data); - parseArguments(&instance, &data, argc, argv); + parseConfigFiles(&data); + parseArguments(&data, argc, argv); + + if (instance.state.configDoc) + { + const char* error = NULL; + + if ( + (error = ffParseLogoJsonConfig()) || + (error = ffParseGeneralJsonConfig()) || + (error = ffParseDisplayJsonConfig()) || + (error = ffParseLibraryJsonConfig()) || + false + ) { + fputs(error, stderr); + exit(477); + } + } - //If we don't have a custom structure, use the default one - if(data.structure.length == 0) - ffStrbufAppendS(&data.structure, FASTFETCH_DATATEXT_STRUCTURE); + if(data.structure.length > 0 || !instance.state.configDoc) + { + //If we don't have a custom structure, use the default one + if(data.structure.length == 0) + ffStrbufAppendS(&data.structure, FASTFETCH_DATATEXT_STRUCTURE); - if(ffStrbufContainIgnCaseS(&data.structure, "CPUUsage")) - ffPrepareCPUUsage(); + if(ffStrbufContainIgnCaseS(&data.structure, FF_CPUUSAGE_MODULE_NAME)) + ffPrepareCPUUsage(); - if(instance.config.multithreading) - { - if(ffStrbufContainIgnCaseS(&data.structure, "PublicIp")) - ffPreparePublicIp(&instance); + if(instance.config.multithreading) + { + if(ffStrbufContainIgnCaseS(&data.structure, FF_PUBLICIP_MODULE_NAME)) + ffPreparePublicIp(&instance.config.publicIP); - if(ffStrbufContainIgnCaseS(&data.structure, "Weather")) - ffPrepareWeather(&instance); + if(ffStrbufContainIgnCaseS(&data.structure, FF_WEATHER_MODULE_NAME)) + ffPrepareWeather(&instance.config.weather); + } } - ffStart(&instance); + ffStart(); - #if defined(_WIN32) && defined(FF_ENABLE_BUFFER) - fflush(stdout); + #if defined(_WIN32) + if (!instance.config.noBuffer) fflush(stdout); #endif - //Parse the structure and call the modules - uint32_t startIndex = 0; - while (startIndex < data.structure.length) + if (data.structure.length == 0 && instance.state.configDoc) + { + ffPrintJsonConfig(); + } + else { - uint32_t colonIndex = ffStrbufNextIndexC(&data.structure, startIndex, ':'); - data.structure.chars[colonIndex] = '\0'; + //Parse the structure and call the modules + uint32_t startIndex = 0; + while (startIndex < data.structure.length) + { + uint32_t colonIndex = ffStrbufNextIndexC(&data.structure, startIndex, ':'); + data.structure.chars[colonIndex] = '\0'; - uint64_t ms = 0; - if(__builtin_expect(instance.config.stat, false)) - ms = ffTimeGetTick(); + uint64_t ms = 0; + if(__builtin_expect(instance.config.stat, false)) + ms = ffTimeGetTick(); - parseStructureCommand(&instance, &data, data.structure.chars + startIndex); + parseStructureCommand(data.structure.chars + startIndex, &data.customValues); - if(__builtin_expect(instance.config.stat, false)) - { - char str[32]; - int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ffTimeGetTick() - ms); - if(instance.config.pipe) - puts(str); - else - printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load - } + if(__builtin_expect(instance.config.stat, false)) + { + char str[32]; + int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ffTimeGetTick() - ms); + if(instance.config.pipe) + puts(str); + else + printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load + } - #if defined(_WIN32) && defined(FF_ENABLE_BUFFER) - fflush(stdout); - #endif + #if defined(_WIN32) + if (!instance.config.noBuffer) fflush(stdout); + #endif - startIndex = colonIndex + 1; + startIndex = colonIndex + 1; + } } - ffFinish(&instance); + ffFinish(); ffStrbufDestroy(&data.structure); - ffValuestoreDestroy(&data.customValues); + FF_LIST_FOR_EACH(FFCustomValue, customValue, data.customValues) + { + ffStrbufDestroy(&customValue->key); + ffStrbufDestroy(&customValue->value); + } + ffListDestroy(&data.customValues); - ffDestroyInstance(&instance); + ffDestroyInstance(); } diff --git a/src/fastfetch.h b/src/fastfetch.h index 8c1114ceff..3e77c204b5 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -7,63 +7,15 @@ #include #include +#include #include "util/FFstrbuf.h" #include "util/FFlist.h" #include "util/platform/FFPlatform.h" +#include "util/unused.h" -static inline void ffUnused(int dummy, ...) { (void) dummy; } -#define FF_UNUSED(...) ffUnused(0, __VA_ARGS__); -#define FF_MAYBE_UNUSED __attribute__ ((__unused__)) - -#define FASTFETCH_LOGO_MAX_COLORS 9 //two digits would make parsing much more complicated (index 1 - 9) - -typedef enum FFLogoType -{ - FF_LOGO_TYPE_AUTO, //if something is given, first try builtin, then file. Otherwise detect logo - FF_LOGO_TYPE_BUILTIN, //builtin ascii art - FF_LOGO_TYPE_FILE, //text file, printed with color code replacement - FF_LOGO_TYPE_FILE_RAW, //text file, printed as is - FF_LOGO_TYPE_DATA, //text data, printed with color code replacement - FF_LOGO_TYPE_DATA_RAW, //text data, printed as is - FF_LOGO_TYPE_IMAGE_SIXEL, //image file, printed as sixel codes. - FF_LOGO_TYPE_IMAGE_KITTY, //image file, printed as kitty graphics protocol - FF_LOGO_TYPE_IMAGE_ITERM, //image file, printed as iterm graphics protocol - FF_LOGO_TYPE_IMAGE_CHAFA, //image file, printed as ascii art using libchafa - FF_LOGO_TYPE_IMAGE_RAW, //image file, printed as raw binary string - FF_LOGO_TYPE_NONE, //--logo none -} FFLogoType; - -typedef enum FFSoundType -{ - FF_SOUND_TYPE_MAIN, - FF_SOUND_TYPE_ACTIVE, - FF_SOUND_TYPE_ALL, -} FFSoundType; - -typedef enum FFDisplayCompactType -{ - FF_DISPLAY_COMPACT_TYPE_NONE = 0, - FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT = 1 << 0, - FF_DISPLAY_COMPACT_TYPE_SCALED_BIT = 1 << 1, -} FFDisplayCompactType; - -typedef enum FFLocalIpCompactType -{ - FF_LOCALIP_COMPACT_TYPE_NONE, - FF_LOCALIP_COMPACT_TYPE_MULTILINE, - FF_LOCALIP_COMPACT_TYPE_ONELINE, -} FFLocalIpCompactType; - -typedef enum FFDiskType -{ - FF_DISK_TYPE_NONE = 0, - FF_DISK_TYPE_REGULAR_BIT = 1 << 0, - FF_DISK_TYPE_HIDDEN_BIT = 1 << 1, - FF_DISK_TYPE_EXTERNAL_BIT = 1 << 2, - FF_DISK_TYPE_SUBVOLUME_BIT = 1 << 3, - FF_DISK_TYPE_UNKNOWN_BIT = 1 << 4, -} FFDiskType; +#include "modules/options.h" +#include "logo/option.h" typedef enum FFBinaryPrefixType { @@ -72,59 +24,24 @@ typedef enum FFBinaryPrefixType FF_BINARY_PREFIX_TYPE_JEDEC, // 1024 Bytes = 1 kB, 1024 K = 1 MB, ... } FFBinaryPrefixType; -typedef enum FFGLType +typedef enum FFTemperatureUnit { - FF_GL_TYPE_AUTO, - FF_GL_TYPE_EGL, - FF_GL_TYPE_GLX, - FF_GL_TYPE_OSMESA -} FFGLType; - -typedef struct FFModuleArgs -{ - FFstrbuf key; - FFstrbuf outputFormat; - FFstrbuf errorFormat; -} FFModuleArgs; - -typedef enum FFLocalIpType -{ - FF_LOCALIP_TYPE_NONE, - FF_LOCALIP_TYPE_LOOP_BIT = 1 << 0, - FF_LOCALIP_TYPE_IPV4_BIT = 1 << 1, - FF_LOCALIP_TYPE_IPV6_BIT = 1 << 2, - FF_LOCALIP_TYPE_MAC_BIT = 1 << 3, - - FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10, -} FFLocalIpType; + FF_TEMPERATURE_UNIT_CELSIUS, + FF_TEMPERATURE_UNIT_FAHRENHEIT, + FF_TEMPERATURE_UNIT_KELVIN, +} FFTemperatureUnit; typedef struct FFconfig { - struct - { - FFstrbuf source; - FFLogoType type; - FFstrbuf colors[FASTFETCH_LOGO_MAX_COLORS]; - uint32_t width; - uint32_t height; - uint32_t paddingTop; - uint32_t paddingLeft; - uint32_t paddingRight; - bool printRemaining; - bool preserveAspectRadio; - - bool chafaFgOnly; - FFstrbuf chafaSymbols; - uint32_t chafaCanvasMode; - uint32_t chafaColorSpace; - uint32_t chafaDitherMode; - } logo; + FFLogoOptions logo; //If one of those is empty, ffLogoPrint will set them FFstrbuf colorKeys; FFstrbuf colorTitle; - FFstrbuf separator; + bool brightColor; + + FFstrbuf keyValueSeparator; bool showErrors; bool recache; @@ -133,58 +50,77 @@ typedef struct FFconfig bool hideCursor; bool escapeBedrock; FFBinaryPrefixType binaryPrefixType; - FFGLType glType; + uint8_t sizeNdigits; + uint8_t sizeMaxPrefix; + FFTemperatureUnit temperatureUnit; bool pipe; //disables logo and all escape sequences bool multithreading; bool stat; + bool noBuffer; + int32_t processingTimeout; - FFModuleArgs os; - FFModuleArgs host; - FFModuleArgs bios; - FFModuleArgs board; - FFModuleArgs brightness; - FFModuleArgs chassis; - FFModuleArgs kernel; - FFModuleArgs uptime; - FFModuleArgs processes; - FFModuleArgs packages; - FFModuleArgs shell; - FFModuleArgs display; - FFModuleArgs de; - FFModuleArgs wallpaper; - FFModuleArgs wifi; - FFModuleArgs wm; - FFModuleArgs wmTheme; - FFModuleArgs theme; - FFModuleArgs icons; - FFModuleArgs font; - FFModuleArgs cursor; - FFModuleArgs terminal; - FFModuleArgs terminalFont; - FFModuleArgs cpu; - FFModuleArgs cpuUsage; - FFModuleArgs gpu; - FFModuleArgs memory; - FFModuleArgs swap; - FFModuleArgs disk; - FFModuleArgs battery; - FFModuleArgs powerAdapter; - FFModuleArgs locale; - FFModuleArgs localIP; - FFModuleArgs publicIP; - FFModuleArgs weather; - FFModuleArgs player; - FFModuleArgs media; - FFModuleArgs dateTime; - FFModuleArgs date; - FFModuleArgs time; - FFModuleArgs vulkan; - FFModuleArgs openGL; - FFModuleArgs openCL; - FFModuleArgs users; - FFModuleArgs bluetooth; - FFModuleArgs sound; - FFModuleArgs gamepad; + // Module options that cannot be put in module option structure + #if defined(__linux__) || defined(__FreeBSD__) + FFstrbuf playerName; + FFstrbuf osFile; + bool dsForceDrm; + #elif defined(_WIN32) + int32_t wmiTimeout; + #endif + + FFTitleOptions title; + FFOSOptions os; + FFHostOptions host; + FFBiosOptions bios; + FFBoardOptions board; + FFBrightnessOptions brightness; + FFChassisOptions chassis; + FFCommandOptions command; + FFKernelOptions kernel; + FFUptimeOptions uptime; + FFProcessesOptions processes; + FFPackagesOptions packages; + FFShellOptions shell; + FFDisplayOptions display; + FFDEOptions de; + FFWallpaperOptions wallpaper; + FFWifiOptions wifi; + FFWMOptions wm; + FFWMThemeOptions wmTheme; + FFThemeOptions theme; + FFIconsOptions icons; + FFFontOptions font; + FFCursorOptions cursor; + FFTerminalOptions terminal; + FFTerminalFontOptions terminalFont; + FFTerminalSizeOptions terminalSize; + FFCPUOptions cpu; + FFCPUUsageOptions cpuUsage; + FFCustomOptions custom; + FFGPUOptions gpu; + FFMemoryOptions memory; + FFSwapOptions swap; + FFDiskOptions disk; + FFBatteryOptions battery; + FFPowerAdapterOptions powerAdapter; + FFLMOptions lm; + FFLocaleOptions locale; + FFLocalIpOptions localIP; + FFPublicIpOptions publicIP; + FFWeatherOptions weather; + FFPlayerOptions player; + FFMediaOptions media; + FFMonitorOptions nativeResolution; + FFDateTimeOptions dateTime; + FFVulkanOptions vulkan; + FFOpenGLOptions openGL; + FFOpenCLOptions openCL; + FFUsersOptions users; + FFBluetoothOptions bluetooth; + FFSeparatorOptions separator; + FFSoundOptions sound; + FFGamepadOptions gamepad; + FFColorsOptions colors; FFstrbuf libPCI; FFstrbuf libVulkan; @@ -206,58 +142,14 @@ typedef struct FFconfig FFstrbuf libGLX; FFstrbuf libOSMesa; FFstrbuf libOpenCL; - FFstrbuf libcJSON; FFstrbuf libfreetype; FFstrbuf libPulse; - FFstrbuf libwlanapi; FFstrbuf libnm; - - bool cpuTemp; - bool gpuTemp; - bool gpuForceVulkan; - bool batteryTemp; - - bool gpuHideIntegrated; - bool gpuHideDiscrete; - - bool titleFQDN; - - bool shellVersion; - bool terminalVersion; - - FFstrbuf diskFolders; - FFDiskType diskShowTypes; - - FFDisplayCompactType displayCompactType; - bool displayDetectName; - bool displayPreciseRefreshRate; - - bool bluetoothShowDisconnected; - - FFstrbuf batteryDir; - - FFstrbuf separatorString; - - FFstrbuf localIpNamePrefix; - FFLocalIpType localIpShowType; - - FFstrbuf publicIpUrl; - uint32_t publicIpTimeout; - - FFstrbuf weatherOutputFormat; - uint32_t weatherTimeout; - - FFSoundType soundType; - - FFstrbuf osFile; - - FFstrbuf playerName; + FFstrbuf libDdcutil; uint32_t percentType; - FFstrbuf commandShell; - FFlist commandKeys; - FFlist commandTexts; + bool jsonConfig; } FFconfig; typedef struct FFstate @@ -267,6 +159,7 @@ typedef struct FFstate uint32_t keysHeight; FFPlatform platform; + yyjson_doc* configDoc; } FFstate; typedef struct FFinstance @@ -274,16 +167,17 @@ typedef struct FFinstance FFconfig config; FFstate state; } FFinstance; +extern FFinstance instance; // Defined in `common/init.c` ////////////////////// // Init functions // ////////////////////// //common/init.c -void ffInitInstance(FFinstance* instance); -void ffStart(FFinstance* instance); -void ffFinish(FFinstance* instance); -void ffDestroyInstance(FFinstance* instance); +void ffInitInstance(); +void ffStart(); +void ffFinish(); +void ffDestroyInstance(); void ffListFeatures(); @@ -291,79 +185,12 @@ void ffListFeatures(); // Logo functions // //////////////////// -void ffLogoPrint(FFinstance* instance); -void ffLogoPrintRemaining(FFinstance* instance); -void ffLogoPrintLine(FFinstance* instance); +void ffLogoPrint(); +void ffLogoPrintRemaining(); +void ffLogoPrintLine(); -void ffLogoBuiltinPrint(FFinstance* instance); +void ffLogoBuiltinPrint(); void ffLogoBuiltinList(); void ffLogoBuiltinListAutocompletion(); -////////////////////// -// Module functions // -////////////////////// - -//Common - -void ffPrintDateTimeFormat(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs); -void ffPrepareCPUUsage(); -void ffPreparePublicIp(FFinstance* instance); -void ffPrepareWeather(FFinstance* instance); - -//Printing - -void ffPrintCustom(FFinstance* instance, const char* key, const char* value); -void ffPrintBreak(FFinstance* instance); -void ffPrintTitle(FFinstance* instance); -void ffPrintSeparator(FFinstance* instance); -void ffPrintOS(FFinstance* instance); -void ffPrintHost(FFinstance* instance); -void ffPrintBios(FFinstance* instance); -void ffPrintBoard(FFinstance* instance); -void ffPrintChassis(FFinstance* instance); -void ffPrintKernel(FFinstance* instance); -void ffPrintUptime(FFinstance* instance); -void ffPrintProcesses(FFinstance* instance); -void ffPrintPackages(FFinstance* instance); -void ffPrintShell(FFinstance* instance); -void ffPrintDisplay(FFinstance* instance); -void ffPrintBrightness(FFinstance* instance); -void ffPrintDesktopEnvironment(FFinstance* instance); -void ffPrintWM(FFinstance* instance); -void ffPrintWMTheme(FFinstance* instance); -void ffPrintTheme(FFinstance* instance); -void ffPrintIcons(FFinstance* instance); -void ffPrintWallpaper(FFinstance* instance); -void ffPrintFont(FFinstance* instance); -void ffPrintCursor(FFinstance* instance); -void ffPrintTerminal(FFinstance* instance); -void ffPrintTerminalFont(FFinstance* instance); -void ffPrintCPU(FFinstance* instance); -void ffPrintCPUUsage(FFinstance* instance); -void ffPrintGPU(FFinstance* instance); -void ffPrintMemory(FFinstance* instance); -void ffPrintSwap(FFinstance* instance); -void ffPrintDisk(FFinstance* instance); -void ffPrintBattery(FFinstance* instance); -void ffPrintPowerAdapter(FFinstance* instance); -void ffPrintLocale(FFinstance* instance); -void ffPrintPlayer(FFinstance* instance); -void ffPrintMedia(FFinstance* instance); -void ffPrintDateTime(FFinstance* instance); -void ffPrintDate(FFinstance* instance); -void ffPrintTime(FFinstance* instance); -void ffPrintLocalIp(FFinstance* instance); -void ffPrintPublicIp(FFinstance* instance); -void ffPrintWeather(FFinstance* instance); -void ffPrintWifi(FFinstance* instance); -void ffPrintColors(FFinstance* instance); -void ffPrintVulkan(FFinstance* instance); -void ffPrintOpenGL(FFinstance* instance); -void ffPrintOpenCL(FFinstance* instance); -void ffPrintUsers(FFinstance* instance); -void ffPrintCommand(FFinstance* instance); -void ffPrintBluetooth(FFinstance* instance); -void ffPrintSound(FFinstance* instance); -void ffPrintGamepad(FFinstance* instance); - #endif diff --git a/src/fastfetch_config.h.in b/src/fastfetch_config.h.in index 0fcf3f2d1d..f913973899 100644 --- a/src/fastfetch_config.h.in +++ b/src/fastfetch_config.h.in @@ -1,3 +1,5 @@ +#pragma once + #ifndef FASTFETCH_INDLUDED_fastfetch_config_h_in #define FASTFETCH_INDLUDED_fastfetch_config_h_in @@ -19,13 +21,4 @@ #define FASTFETCH_TARGET_DIR_INSTALL_SYSCONF "@CMAKE_INSTALL_SYSCONFDIR@" -#define FASTFETCH_DATATEXT_STRUCTURE "@DATATEXT_STRUCTURE@" -#define FASTFETCH_DATATEXT_CONFIG_SYSTEM "@DATATEXT_CONFIG_SYSTEM@" -#define FASTFETCH_DATATEXT_CONFIG_USER "@DATATEXT_CONFIG_USER@" //Requires FASTFETCH_PROJECT_VERSION and FASTFETCH_DATATEXT_STRUCTURE to be set -#define FASTFETCH_DATATEXT_MODULES "@DATATEXT_MODULES@" -#define FASTFETCH_DATATEXT_HELP "@DATATEXT_HELP@" -#define FASTFETCH_DATATEXT_HELP_COLOR "@DATATEXT_HELP_COLOR@" -#define FASTFETCH_DATATEXT_HELP_FORMAT "@DATATEXT_HELP_FORMAT@" -#define FASTFETCH_DATATEXT_HELP_CONFIG "@DATATEXT_HELP_CONFIG@" - #endif // FASTFETCH_INDLUDED_fastfetch_config_h_in diff --git a/src/fastfetch_datatext.h.in b/src/fastfetch_datatext.h.in new file mode 100644 index 0000000000..f8a6994272 --- /dev/null +++ b/src/fastfetch_datatext.h.in @@ -0,0 +1,16 @@ +#pragma once + +#ifndef FASTFETCH_INDLUDED_fastfetch_datatext_h_in +#define FASTFETCH_INDLUDED_fastfetch_datatext_h_in + +#define FASTFETCH_DATATEXT_STRUCTURE "@DATATEXT_STRUCTURE@" +#define FASTFETCH_DATATEXT_CONFIG_SYSTEM "@DATATEXT_CONFIG_SYSTEM@" +#define FASTFETCH_DATATEXT_CONFIG_USER "@DATATEXT_CONFIG_USER@" //Requires FASTFETCH_PROJECT_VERSION and FASTFETCH_DATATEXT_STRUCTURE to be set +#define FASTFETCH_DATATEXT_CONFIG_USER_JSONC "@DATATEXT_CONFIG_USER_JSONC@" +#define FASTFETCH_DATATEXT_MODULES "@DATATEXT_MODULES@" +#define FASTFETCH_DATATEXT_HELP "@DATATEXT_HELP@" +#define FASTFETCH_DATATEXT_HELP_COLOR "@DATATEXT_HELP_COLOR@" +#define FASTFETCH_DATATEXT_HELP_FORMAT "@DATATEXT_HELP_FORMAT@" +#define FASTFETCH_DATATEXT_HELP_CONFIG "@DATATEXT_HELP_CONFIG@" + +#endif diff --git a/src/flashfetch.c b/src/flashfetch.c index 8737c8fcfc..3417548f59 100644 --- a/src/flashfetch.c +++ b/src/flashfetch.c @@ -1,75 +1,71 @@ #include "fastfetch.h" -int main(int argc, char** argv) -{ - //Disable compiler warnings - FF_UNUSED(argc, argv); +#include "modules/modules.h" - FFinstance instance; - ffInitInstance(&instance); //This also applys default configuration to instance.config +int main(void) +{ + ffInitInstance(); //This also applys default configuration to instance.config //Modify instance.config here // ffPrepareCPUUsage(); - // ffPreparePublicIp(&instance); - // ffPrepareWeather(&instance); + // ffPreparePublicIp(&instance.config.publicIP); + // ffPrepareWeather(&instance.config.weather); //Does things like starting detection threads, disabling line wrap, etc - ffStart(&instance); + ffStart(); //Printing - ffPrintTitle(&instance); - ffPrintSeparator(&instance); - ffPrintOS(&instance); - ffPrintHost(&instance); - //ffPrintBios(&instance); - //ffPrintBoard(&instance); - //ffPrintChassis(&instance); - ffPrintKernel(&instance); - ffPrintUptime(&instance); - //ffPrintProcesses(&instance); - ffPrintPackages(&instance); - ffPrintShell(&instance); - ffPrintDisplay(&instance); - // ffPrintBrightness(&instance); - ffPrintDesktopEnvironment(&instance); - ffPrintWM(&instance); - ffPrintWMTheme(&instance); - ffPrintTheme(&instance); - ffPrintIcons(&instance); - ffPrintFont(&instance); - ffPrintCursor(&instance); - ffPrintTerminal(&instance); - ffPrintTerminalFont(&instance); - ffPrintCPU(&instance); - ffPrintGPU(&instance); - ffPrintMemory(&instance); - //ffPrintSwap(&instance); - ffPrintDisk(&instance); - ffPrintBattery(&instance); - ffPrintPowerAdapter(&instance); - //ffPrintPlayer(&instance); - //ffPrintMedia(&instance); - //ffPrintLocalIp(&instance); - //ffPrintPublicIp(&instance); - //ffPrintWifi(&instance); - //ffPrintCPUUsage(&instance); - ffPrintLocale(&instance); - //ffPrintDateTime(&instance); - //ffPrintDate(&instance); - //ffPrintTime(&instance); - //ffPrintVulkan(&instance); - //ffPrintOpenGL(&instance); - //ffPrintOpenCL(&instance); - //ffPrintUsers(&instance); - //ffPrintWeather(&instance); - //ffPrintBluetooth(&instance); - //ffPrintSound(&instance); - //ffPrintGamepad(&instance); - ffPrintBreak(&instance); - ffPrintColors(&instance); + ffPrintTitle(&instance.config.title); + ffPrintSeparator(&instance.config.separator); + ffPrintOS(&instance.config.os); + ffPrintHost(&instance.config.host); + //ffPrintBios(&instance.config.bios); + //ffPrintBoard(&instance.config.board); + //ffPrintChassis(&instance.config.chassis); + ffPrintKernel(&instance.config.kernel); + //ffPrintProcesses(&instance.config.processes); + ffPrintUptime(&instance.config.uptime); + ffPrintPackages(&instance.config.packages); + ffPrintShell(&instance.config.shell); + ffPrintDisplay(&instance.config.display); + // ffPrintBrightness(&instance.config.brightness); + ffPrintDE(&instance.config.de); + ffPrintWM(&instance.config.wm); + ffPrintWMTheme(&instance.config.wmTheme); + ffPrintTheme(&instance.config.theme); + ffPrintIcons(&instance.config.icons); + ffPrintFont(&instance.config.font); + ffPrintCursor(&instance.config.cursor); + ffPrintTerminal(&instance.config.terminal); + ffPrintTerminalFont(&instance.config.terminalFont); + ffPrintCPU(&instance.config.cpu); + ffPrintGPU(&instance.config.gpu); + ffPrintMemory(&instance.config.memory); + ffPrintSwap(&instance.config.swap); + ffPrintDisk(&instance.config.disk); + ffPrintBattery(&instance.config.battery); + ffPrintPowerAdapter(&instance.config.powerAdapter); + //ffPrintPlayer(&instance.config.player); + //ffPrintMedia(&instance.config.media); + //ffPrintLocalIp(&instance.config.localIp); + //ffPrintPublicIp(&instance.config.publicIp); + //ffPrintWifi(&instance.config.wifi); + //ffPrintCPUUsage(&instance.config.cpuUsage); + ffPrintLocale(&instance.config.locale); + //ffPrintDateTime(&instance.config.dateTime); + //ffPrintVulkan(&instance.config.vulkan); + //ffPrintOpenGL(&instance.config.openGL); + //ffPrintOpenCL(&instance.config.openCL); + //ffPrintUsers(&instance.config.users); + //ffPrintWeather(&instance.config.weather); + //ffPrintBluetooth(&instance.config.bluetooth); + //ffPrintSound(&instance.config.sound); + //ffPrintGamepad(&instance.config.gamepad); + ffPrintBreak(); + ffPrintColors(&instance.config.colors); - ffFinish(&instance); - ffDestroyInstance(&instance); + ffFinish(); + ffDestroyInstance(); return 0; } diff --git a/src/logo/ascii/aix.txt b/src/logo/ascii/aix.txt new file mode 100644 index 0000000000..42b3f43ac7 --- /dev/null +++ b/src/logo/ascii/aix.txt @@ -0,0 +1,20 @@ + `:+ssssossossss+-` + .oys///oyhddddhyo///sy+. + /yo:+hNNNNNNNNNNNNNNNNh+:oy/ + :h/:yNNNNNNNNNNNNNNNNNNNNNNy-+h: + `ys.yNNNNNNNNNNNNNNNNNNNNNNNNNNy.ys + `h+-mNNNNNNNNNNNNNNNNNNNNNNNNNNNNm-oh + h+-NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN.oy +/d`mNNNNNNN/::mNNNd::m+:/dNNNo::dNNNd`m: +h//NNNNNNN: . .NNNh mNo od. -dNNNNN:+y +N.sNNNNNN+ -N/ -NNh mNNd. sNNNNNNNo-m +N.sNNNNNs +oo /Nh mNNs` ` /mNNNNNNo-m +h//NNNNh ossss` +h md- .hm/ `sNNNNN:+y +:d`mNNN+/yNNNNNd//y//h//oNNNNy//sNNNd`m- + yo-NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNm.ss + `h+-mNNNNNNNNNNNNNNNNNNNNNNNNNNNNm-oy + sy.yNNNNNNNNNNNNNNNNNNNNNNNNNNs.yo + :h+-yNNNNNNNNNNNNNNNNNNNNNNs-oh- + :ys:/yNNNNNNNNNNNNNNNmy/:sy: + .+ys///osyhhhhys+///sy+. + -/osssossossso/- \ No newline at end of file diff --git a/src/logo/ascii/almalinux.txt b/src/logo/ascii/almalinux.txt new file mode 100644 index 0000000000..6a1000fa82 --- /dev/null +++ b/src/logo/ascii/almalinux.txt @@ -0,0 +1,20 @@ +$1 'c:. +$1 lkkkx, .. $2.. ,cc, +$1 okkkk:ckkx' $2.lxkkx.okkkkd +$1 .:llcokkx' $2:kkkxkko:xkkd, +$1 .xkkkkdood: $2;kx, .lkxlll; +$1 xkkx. $2xk' xkkkkk: +$1 'xkx. $2xd .....,. +$3 .. $1:xkl' $2:c ..''.. +$3 .dkx' $1.:ldl:'. $2' $4':lollldkkxo; +$3 .''lkkko' $4ckkkx. +$3'xkkkd:kkd. .. $5;' $4:kkxo. +$3,xkkkd;kk' ,d; $5ld. $4':dkd::cc, +$3 .,,.;xkko'.';lxo. $5dx, $4:kkk'xkkkkc +$3 'dkkkkkxo:. $5;kx $4.kkk:;xkkd. +$3 ..... $5.;dk:. $5lkk. $4:;, + $5:kkkkkkkdoxkkx + ,c,,;;;:xkkd. + ;kkkkl... + ;kkkkl + ,od; \ No newline at end of file diff --git a/src/logo/ascii/alpine.txt b/src/logo/ascii/alpine.txt new file mode 100644 index 0000000000..3379ff4ee8 --- /dev/null +++ b/src/logo/ascii/alpine.txt @@ -0,0 +1,20 @@ + .hddddddddddddddddddddddh. + :dddddddddddddddddddddddddd: + /dddddddddddddddddddddddddddd/ + +dddddddddddddddddddddddddddddd+ + `sdddddddddddddddddddddddddddddddds` + `ydddddddddddd++hdddddddddddddddddddy` +.hddddddddddd+` `+ddddh:-sdddddddddddh. +hdddddddddd+` `+y: .sddddddddddh +ddddddddh+` `//` `.` -sddddddddd +ddddddh+` `/hddh/` `:s- -sddddddd +ddddh+` `/+/dddddh/` `+s- -sddddd +ddd+` `/o` :dddddddh/` `oy- .yddd +hdddyo+ohddyosdddddddddho+oydddy++ohdddh +.hddddddddddddddddddddddddddddddddddddh. + `yddddddddddddddddddddddddddddddddddy` + `sdddddddddddddddddddddddddddddddds` + +dddddddddddddddddddddddddddddd+ + /dddddddddddddddddddddddddddd/ + :dddddddddddddddddddddddddd: + .hddddddddddddddddddddddh. \ No newline at end of file diff --git a/src/logo/ascii/alpine2_small.txt b/src/logo/ascii/alpine2_small.txt new file mode 100644 index 0000000000..8f231cc2b3 --- /dev/null +++ b/src/logo/ascii/alpine2_small.txt @@ -0,0 +1,6 @@ +${c1} /\\ /\\ + /${c2}/ ${c1}\\ \\ + /${c2}// ${c1}\\ \\ +/${c2}// ${c1}\\ \\ +${c2}// ${c1}\\ \\ + \\ diff --git a/src/logo/ascii/alpine_small.txt b/src/logo/ascii/alpine_small.txt new file mode 100644 index 0000000000..a0cb082a26 --- /dev/null +++ b/src/logo/ascii/alpine_small.txt @@ -0,0 +1,6 @@ + /\ /\ + // \ \ + // \ \ +/// \ \ +// \ \ + \ \ No newline at end of file diff --git a/src/logo/ascii/alter.txt b/src/logo/ascii/alter.txt new file mode 100644 index 0000000000..990221c90f --- /dev/null +++ b/src/logo/ascii/alter.txt @@ -0,0 +1,20 @@ + %, + ^WWWw + 'wwwwww + !wwwwwwww + #`wwwwwwwww + @wwwwwwwwwwww + wwwwwwwwwwwwwww + wwwwwwwwwwwwwwwww + wwwwwwwwwwwwwwwwwww + wwwwwwwwwwwwwwwwwwww, + w~1i.wwwwwwwwwwwwwwwww, + 3~:~1lli.wwwwwwwwwwwwwwww. + :~~:~?ttttzwwwwwwwwwwwwwwww + #<~:~~~~?llllltO-.wwwwwwwwwww + #~:~~:~:~~?ltlltlttO-.wwwwwwwww + @~:~~:~:~:~~(zttlltltlOda.wwwwwww + @~:~~: ~:~~:~:(zltlltlO a,wwwwww + 8~~:~~:~~~~:~~~~_1ltltu ,www + 5~~:~~:~~:~~:~~:~~~_1ltq N,, + g~:~~:~~~:~~:~~:~:~~~~1q N, diff --git a/src/logo/ascii/amazon.txt b/src/logo/ascii/amazon.txt new file mode 100644 index 0000000000..e995cfdff9 --- /dev/null +++ b/src/logo/ascii/amazon.txt @@ -0,0 +1,19 @@ + `-/oydNNdyo:.` + `.:+shmMMMMMMMMMMMMMMmhs+:.` + -+hNNMMMMMMMMMMMMMMMMMMMMMMNNho- +.`` -/+shmNNMMMMMMNNmhs+/- ``. +dNmhs+:. `.:/oo/:.` .:+shmNd +dMMMMMMMNdhs+:.. ..:+shdNMMMMMMMd +dMMMMMMMMMMMMMMNds odNMMMMMMMMMMMMMMd +dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd +dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd +dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd +dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd +dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd +dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd +dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd +dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd +dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd +.:+ydNMMMMMMMMMMMh yMMMMMMMMMMMNdy+:. + `.:+shNMMMMMh yMMMMMNhs+:`` + `-+shy shs+:` diff --git a/src/logo/ascii/amogos.txt b/src/logo/ascii/amogos.txt new file mode 100644 index 0000000000..4b19191337 --- /dev/null +++ b/src/logo/ascii/amogos.txt @@ -0,0 +1,19 @@ +${c1} ___________ + / \ + / ${c2}______${c1} \ + / ${c2}/ \${c1} \ + | ${c2}( )${c1} \ + / ${c2}\______/${c1} | + | | + / \ + | | + | | + / | + | | + | _______ | + ____/ / \ | + / | | | + | / ____/ | + \_________/ / | + \ __/ + \_______/ diff --git a/src/logo/ascii/anarchy.txt b/src/logo/ascii/anarchy.txt new file mode 100644 index 0000000000..76b74cd35d --- /dev/null +++ b/src/logo/ascii/anarchy.txt @@ -0,0 +1,28 @@ + ${c2}..${c1} + ${c2}..${c1} + ${c2}:..${c1} + ${c2}:+++.${c1} + .:::++${c2}++++${c1}+::. + .:+######${c2}++++${c1}######+:. + .+#########${c2}+++++${c1}##########:. + .+##########${c2}+++++++${c1}##${c2}+${c1}#########+. + +###########${c2}+++++++++${c1}############: + +##########${c2}++++++${c1}#${c2}++++${c1}#${c2}+${c1}###########+ + +###########${c2}+++++${c1}###${c2}++++${c1}#${c2}+${c1}###########+ + :##########${c2}+${c1}#${c2}++++${c1}####${c2}++++${c1}#${c2}+${c1}############: + ###########${c2}+++++${c1}#####${c2}+++++${c1}#${c2}+${c1}###${c2}++${c1}######+ +.##########${c2}++++++${c1}#####${c2}++++++++++++${c1}#######. +.##########${c2}+++++++++++++++++++${c1}###########. + #####${c2}++++++++++++++${c1}###${c2}++++++++${c1}#########+ + :###${c2}++++++++++${c1}#########${c2}+++++++${c1}#########: + +######${c2}+++++${c1}##########${c2}++++++++${c1}#######+ + +####${c2}+++++${c1}###########${c2}+++++++++${c1}#####+ + :##${c2}++++++${c1}############${c2}++++++++++${c1}##: + .${c2}++++++${c1}#############${c2}++++++++++${c1}+. + :${c2}++++${c1}###############${c2}+++++++${c1}:: + .${c2}++. .:+${c1}##############${c2}+++++++${c1}.. + ${c2}.:.${c1} ..::++++++::..:${c2}++++${c1}+. + ${c2}.${c1} ${c2}.:+++${c1}. + ${c2}.:${c1}: + ${c2}..${c1} + ${c2}..${c1} diff --git a/src/logo/ascii/android.txt b/src/logo/ascii/android.txt new file mode 100644 index 0000000000..dba9163b14 --- /dev/null +++ b/src/logo/ascii/android.txt @@ -0,0 +1,18 @@ + -o o- + +hydNNNNdyh+ + +mMMMMMMMMMMMMm+ + `dMM$2m:$1NMMMMMMN$2:m$1MMd` + hMMMMMMMMMMMMMMMMMMh + .. yyyyyyyyyyyyyyyyyyyy .. +.mMMm`MMMMMMMMMMMMMMMMMMMM`mMMm. +:MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM: +:MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM: +:MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM: +:MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM: +-MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM- + +yy+ MMMMMMMMMMMMMMMMMMMM +yy+ + mMMMMMMMMMMMMMMMMMMm + `/++MMMMh++hMMMM++/` + MMMMo oMMMM + MMMMo oMMMM + oNMm- -mMNs \ No newline at end of file diff --git a/src/logo/ascii/android_small.txt b/src/logo/ascii/android_small.txt new file mode 100644 index 0000000000..0d7df96afa --- /dev/null +++ b/src/logo/ascii/android_small.txt @@ -0,0 +1,6 @@ + ;, ,; + ';,.-----.,;' + ,' ', + / O O \ +| | +'-----------------' \ No newline at end of file diff --git a/src/logo/ascii/antergos.txt b/src/logo/ascii/antergos.txt new file mode 100644 index 0000000000..023af9bd89 --- /dev/null +++ b/src/logo/ascii/antergos.txt @@ -0,0 +1,19 @@ +${c2} `.-/::/-`` + .-/osssssssso/. + :osyysssssssyyys+- + `.+yyyysssssssssyyyyy+. + `/syyyyyssssssssssyyyyys-` + `/yhyyyyysss${c1}++${c2}ssosyyyyhhy/` + .ohhhyyyys${c1}o++/+o${c2}so${c1}+${c2}syy${c1}+${c2}shhhho. + .shhhhys${c1}oo++//+${c2}sss${c1}+++${c2}yyy${c1}+s${c2}hhhhs. + -yhhhhs${c1}+++++++o${c2}ssso${c1}+++${c2}yyy${c1}s+o${c2}hhddy: + -yddhhy${c1}o+++++o${c2}syyss${c1}++++${c2}yyy${c1}yooy${c2}hdddy- + .yddddhs${c1}o++o${c2}syyyyys${c1}+++++${c2}yyhh${c1}sos${c2}hddddy` +`odddddhyosyhyyyyyy${c1}++++++${c2}yhhhyosddddddo +.dmdddddhhhhhhhyyyo${c1}+++++${c2}shhhhhohddddmmh. +ddmmdddddhhhhhhhso${c1}++++++${c2}yhhhhhhdddddmmdy +dmmmdddddddhhhyso${c1}++++++${c2}shhhhhddddddmmmmh +-dmmmdddddddhhys${c1}o++++o${c2}shhhhdddddddmmmmd- +.smmmmddddddddhhhhhhhhhdddddddddmmmms. + `+ydmmmdddddddddddddddddddmmmmdy/. + `.:+ooyyddddddddddddyyso+:.` diff --git a/src/logo/ascii/antix.txt b/src/logo/ascii/antix.txt new file mode 100644 index 0000000000..57a97dafa0 --- /dev/null +++ b/src/logo/ascii/antix.txt @@ -0,0 +1,12 @@ + \ + , - ~ ^ ~ - \ / + , ' \ ' , / + , \ '/ + , \ / , + ,___, \/ , + / | _ _ _|_ o /\ , +|, | / |/ | | | / \ , + \,_/\_/ | |_/|_/|_/_/ \, + , / ,\ + , / , ' \ + ' - , _ _ _ , ' diff --git a/src/logo/ascii/aoscos.txt b/src/logo/ascii/aoscos.txt new file mode 100644 index 0000000000..2886c092dd --- /dev/null +++ b/src/logo/ascii/aoscos.txt @@ -0,0 +1,20 @@ + .:+syhhhhys+:. + .ohNMMMMMMMMMMMMMMNho. + `+mMMMMMMMMMMmdmNMMMMMMMMm+` + +NMMMMMMMMMMMM/ `./smMMMMMN+ + .mMMMMMMMMMMMMMMo -yMMMMMm. + :NMMMMMMMMMMMMMMMs .hMMMMN: + .NMMMMhmMMMMMMMMMMm+/- oMMMMN. + dMMMMs ./ymMMMMMMMMMMNy. sMMMMd +-MMMMN` oMMMMMMMMMMMN: `NMMMM- +/MMMMh NMMMMMMMMMMMMm hMMMM/ +/MMMMh NMMMMMMMMMMMMm hMMMM/ +-MMMMN` :MMMMMMMMMMMMy. `NMMMM- + dMMMMs .yNMMMMMMMMMMMNy/. sMMMMd + .NMMMMo -/+sMMMMMMMMMMMmMMMMN. + :NMMMMh. .MMMMMMMMMMMMMMMN: + .mMMMMMy- NMMMMMMMMMMMMMm. + +NMMMMMms/.` mMMMMMMMMMMMN+ + `+mMMMMMMMMNmddMMMMMMMMMMm+` + .ohNMMMMMMMMMMMMMMNho. + .:+syhhhhys+:. diff --git a/src/logo/ascii/aoscosretro.txt b/src/logo/ascii/aoscosretro.txt new file mode 100644 index 0000000000..1ae7f87488 --- /dev/null +++ b/src/logo/ascii/aoscosretro.txt @@ -0,0 +1,18 @@ +${c2} ......... + ................... + .....................${c1}################${c2} + .............. ....${c1}################${c2} +.............. ...${c1}################${c2} +............. ..${c1}****************${c2} +............ . .${c1}****************${c2} +........... ... ${c1}................${c2} +.......... ..... ${c1}...............${c2} +......... ....... ... + .${c3}...... ${c2}. + ${c3}..... .....${c2}.... ${c4}........... + ${c3}.... ......${c2}. ${c4}........... + ${c3}... ....... ${c4}........... + ${c3}................ ${c4}*********** + ${c3}................ ${c4}########### + ${c3}**************** + ${c3}################ diff --git a/src/logo/ascii/aoscosretro_small.txt b/src/logo/ascii/aoscosretro_small.txt new file mode 100644 index 0000000000..9a67980622 --- /dev/null +++ b/src/logo/ascii/aoscosretro_small.txt @@ -0,0 +1,9 @@ +${c2} _____ ${c1}_____${c2} + -' '-${c1}| |${c2} + / ___ ${c1}| |${c2} +| / _ \\${c1}|_____|${c2} +' / /_\\ \\ + \\ / _____ \\${c4}___ + ${c3}|${c2}/_/ ${c3}| ${c4}| | + ${c3}| | ${c4}|___| + ${c3}|_____| diff --git a/src/logo/ascii/aperture.txt b/src/logo/ascii/aperture.txt new file mode 100644 index 0000000000..a3ffb5889e --- /dev/null +++ b/src/logo/ascii/aperture.txt @@ -0,0 +1,20 @@ + .,-:;//;:=, + . :H@@@MM@M#H/.,+%;, + ,/X+ +M@@M@MM%=,-%HMMM@X/, + -+@MM; SM@@MH+-,;XMMMM@MMMM@+- + ;@M@@M- XM@X;. -+XXXXXHHH@M@M#@/. + ,%MM@@MH ,@%= .---=-=:=,. + =@#@@@MX., -%HXSS%%%:; + =-./@M@MS .;@MMMM@MM: + X@/ -SMM/ . +MM@@@MS +,@M@H: :@: . =X#@@@@- +,@@@MMX, . /H- ;@M@M= +.H@@@@M@+, %MM+..%#S. + /MMMM@MMH/. XM@MH; =; + /%+%SXHH@S= , .H@@@@MX, + .=--------. -%H.,@@@@@MX, + .%MM@@@HHHXXSSS%+- .:SMMX =M@@MM%. + =XMMM@MM@MM#H;,-+HMM@M+ /MMMX= + =%@M@M#@S-.=S@MM@@@M; %M%= + ,:+S+-,/H#MMMMMMM@= =, + =++%%%%+/:-. diff --git a/src/logo/ascii/apricity.txt b/src/logo/ascii/apricity.txt new file mode 100644 index 0000000000..1f3166583b --- /dev/null +++ b/src/logo/ascii/apricity.txt @@ -0,0 +1,18 @@ + ./o- + ``...`` `:. -/: + `-+ymNMMMMMNmho-` :sdNNm/ + `+dMMMMMMMMMMMMMMMmo` sh:.:::- + /mMMMMMMMMMMMMMMMMMMMm/`sNd/ + oMMMMMMMMMMMMMMMMMMMMMMMs -` +:MMMMMMMMMMMMMMMMMMMMMMMMM/ +NMMMMMMMMMMMMMMMMMMMMMMMMMd +MMMMMMMmdmMMMMMMMMMMMMMMMMd +MMMMMMy` .mMMMMMMMMMMMmho:` +MMMMMMNo/sMMMMMMMNdy+-.`-/ +MMMMMMMMMMMMNdy+:.`.:ohmm: +MMMMMMMmhs+-.`.:+ymNMMMy. +MMMMMM/`.-/ohmNMMMMMMy- +MMMMMMNmNNMMMMMMMMmo. +MMMMMMMMMMMMMMMms:` +MMMMMMMMMMNds/. +dhhyys+/-` diff --git a/src/logo/ascii/arch.txt b/src/logo/ascii/arch.txt new file mode 100644 index 0000000000..b3d2347558 --- /dev/null +++ b/src/logo/ascii/arch.txt @@ -0,0 +1,19 @@ + -` + .o+` + `ooo/ + `+oooo: + `+oooooo: + -+oooooo+: + `/:-:++oooo+: + `/++++/+++++++: + `/++++++++++++++: + `/+++o$2oooooooo$1oooo/` + ./$2ooosssso++osssssso$1+` +$2 .oossssso-````/ossssss+` + -osssssso. :ssssssso. + :osssssss/ osssso+++. + /ossssssss/ +ssssooo/- + `/ossssso+/:- -:/+osssso+- + `+sso+:-` `.-/+oso: +`++:. `-/+/ +.` `/ diff --git a/src/logo/ascii/arch2.txt b/src/logo/ascii/arch2.txt new file mode 100644 index 0000000000..5da1b55406 --- /dev/null +++ b/src/logo/ascii/arch2.txt @@ -0,0 +1,19 @@ + ▄ + ▟█▙ + ▟███▙ + ▟█████▙ + ▟███████▙ + ▂▔▀▜██████▙ + ▟██▅▂▝▜█████▙ + ▟█████████████▙ + ▟███████████████▙ + ▟█████████████████▙ + ▟███████████████████▙ +$2 ▟█████████▛▀▀▜████████▙ + ▟████████▛ ▜███████▙ + ▟█████████ ████████▙ + ▟██████████ █████▆▅▄▃▂ + ▟██████████▛ ▜█████████▙ + ▟██████▀▀▀ ▀▀██████▙ + ▟███▀▘ ▝▀███▙ +▟▛▀ ▀▜▙ diff --git a/src/logo/ascii/arch_small.txt b/src/logo/ascii/arch_small.txt new file mode 100644 index 0000000000..3688e24713 --- /dev/null +++ b/src/logo/ascii/arch_small.txt @@ -0,0 +1,7 @@ + /\ + / \ + / \ + / \ + / ,, \ + / | | \ +/_-'' ''-_\ \ No newline at end of file diff --git a/src/logo/ascii/archbox.txt b/src/logo/ascii/archbox.txt new file mode 100644 index 0000000000..682a183aef --- /dev/null +++ b/src/logo/ascii/archbox.txt @@ -0,0 +1,19 @@ + ...:+oh/:::.. + ..-/oshhhhhh` `::::-. + .:/ohhhhhhhhhhhh` `-::::. + .+shhhhhhhhhhhhhhhhh` `.::-. + /`-:+shhhhhhhhhhhhhh` .-/+shh + / .:/ohhhhhhhhh` .:/ohhhhhhhh + / `-:+shhh` ..:+shhhhhhhhhhhh + / .:ohhhhhhhhhhhhhhhhhhh + / `hhhhhhhhhhhhhhhhhhhh + / `hhhhhhhhhhhhhhhhhhhh + / `hhhhhhhhhhhhhhhhhhhh + / `hhhhhhhhhhhhhhhhhhhh + / .+o+ `hhhhhhhhhhhhhhhhhhhh + / -hhhhh `hhhhhhhhhhhhhhhhhhhh + / ohhhhho `hhhhhhhhhhhhhhhhhhhh + /:::+`hhhhoos` `hhhhhhhhhhhhhhhhhs+` + `--/:` /: `hhhhhhhhhhhho/- + -/:. `hhhhhhs+:-` + ::::/ho/-` diff --git a/src/logo/ascii/archcraft.txt b/src/logo/ascii/archcraft.txt new file mode 100644 index 0000000000..a57f7b7bfd --- /dev/null +++ b/src/logo/ascii/archcraft.txt @@ -0,0 +1,20 @@ +${c1}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⢰⡆${c1}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄ +${c2}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⢠⣿⣿⡄${c2}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄ +${c3}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⢀⣾⣿⣿⣿⡀${c3}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄ +${c4}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⣼⣿⣿⣿⣿⣷⡀${c4}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄ +${c5}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⣼⣿⣿⣿⣿⣿⣿⣷${c5}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄ +${c6}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⢼⣿⣿⣿⣿⣿⣿⣿⣿⣧${c6}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄ +${c1}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⣰⣤⣈⠻⢿⣿⣿⣿⣿⣿⣿⣧${c1}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄ +${c2}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⣰⣿⣿⣿⣿⣮⣿⣿⣿⣿⣿⣿⣿⣧${c2}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄ +${c3}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧${c3}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄ +${c4}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧${c4}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄ +${c5}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧${c5}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄ +${c6}⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⣼⣿⣿⣿⣿⣿⡿⣿⣿⡟${c6}⠄⠄${c1}⠸⣿⣿⡿⣿⣿⣿⣿⣿⣷⡀${c6}⠄⠄⠄⠄⠄⠄⠄⠄ +${c1}⠄⠄⠄⠄⠄⠄⠄⠄${c1}⣼⣿⣿⣿⣿⣿⡏${c1}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠈⣿⣿⣿⣿⣿⣷⡀${c1}⠄⠄⠄⠄⠄⠄⠄ +${c2}⠄⠄⠄⠄⠄⠄${c1}⢀⣼⣿⣿⣿⣿⣿⣿⡗${c2}⠄⠄⠄${c1}⢀⣠⣤⣀⠄⠄⠄${c1}⠸⣿⣿⣿⣿⣿⣿⣷⡀${c2}⠄⠄⠄⠄⠄⠄ +${c3}⠄⠄⠄⠄⠄${c1}⢀⣾⣿⣿⣿⣿⣿⡏⠁${c3}⠄⠄⠄${c1}⢠⣿⣿⣿⣿⡇${c3}⠄⠄⠄⠄${c1}⢙⣿⣿⣻⠿⣿⣷⡀${c3}⠄⠄⠄⠄⠄ +${c4}⠄⠄⠄⠄${c1}⢀⣾⣿⣿⣿⣿⣿⣿⣷⣤⡀${c4}⠄⠄⠄${c1}⠻⣿⣿⡿⠃${c4}⠄⠄⠄${c1}⢀⣼⣿⣿⣿⣿⣦⣌⠙⠄${c4}⠄⠄⠄⠄ +${c5}⠄⠄⠄${c1}⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏${c5}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⢿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀${c5}⠄⠄⠄ +${c6}⠄⠄${c1}⢠⣿⣿⣿⣿⣿⣿⣿⡿⠟⠋⠁${c6}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠙⠻⣿⣿⣿⣿⣿⣿⣿⣿⡄${c6}⠄⠄ +${c1}⠄${c1}⣠⣿⣿⣿⣿⠿⠛⠋⠁${c1}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠉⠙⠻⢿⣿⣿⣿⣿⣆${c1}⠄ +${c1}⡰⠟⠛⠉⠁${c2}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠉⠙⠛⠿⢆ diff --git a/src/logo/ascii/archcraft2.txt b/src/logo/ascii/archcraft2.txt new file mode 100644 index 0000000000..75e553bf67 --- /dev/null +++ b/src/logo/ascii/archcraft2.txt @@ -0,0 +1,20 @@ + -o\ + :ooo: + .ooooo. + ooooooo. + +oooooooo. + -oooooooooo. + --:-+oooooooo. + yooo+=+sooooooo. + yoooooosooooooooo. + y+ooooooooooooooooo. + yoooooooooooooooooooo` + yoooooo+oo= :oo++ooooo` + :oooooo. +ooooo- + -ooooooo. .::. +ooosoo= + -oooooo` .oooo` +os-=o= + =ooooooo=: `oo+ :=ooo=--`. + +ooooooooos. .=sooooooo+- + .+osossos+-` `-+osososs+. + :sss+=-:` `:-=+ssss: +:=-:` `-=+: diff --git a/src/logo/ascii/archlabs.txt b/src/logo/ascii/archlabs.txt new file mode 100644 index 0000000000..49af8b7096 --- /dev/null +++ b/src/logo/ascii/archlabs.txt @@ -0,0 +1,21 @@ + 'c' + 'kKk, + .dKKKx. + .oKXKXKd. + .l0XXXXKKo. + c0KXXXXKX0l. + :0XKKOxxOKX0l. + :OXKOc. .c0XX0l. + :OK0o. $2...$1'dKKX0l. + :OX0c $2;xOx'$1'dKXX0l. + :0KKo.$2.o0XXKd'.$1lKXX0l. + c0XKd.$2.oKXXXXKd..$1oKKX0l. + .c0XKk;$2.l0K0OO0XKd..$1oKXXKo. + .l0XXXk:$2,dKx,.'l0XKo.$1.kXXXKo. + .o0XXXX0d,$2:x; .oKKx'$1.dXKXXKd. + .oKXXXXKK0c.$2;. :00c'$1cOXXXXXKd. + .dKXXXXXXXXk,$2. cKx'$1'xKXXXXXXKx' + 'xKXXXXK0kdl:. $2.ok; $1.cdk0KKXXXKx' + 'xKK0koc,.. $2'c, $1 ..,cok0KKk, + ,xko:'. $2.. $1 .':okx; + .,'. .',. diff --git a/src/logo/ascii/archstrike.txt b/src/logo/ascii/archstrike.txt new file mode 100644 index 0000000000..a65d510112 --- /dev/null +++ b/src/logo/ascii/archstrike.txt @@ -0,0 +1,17 @@ +${c1} * + **. + **** + ****** + ******* + ** ******* + **** ******* + ${c1}****${c2}_____${c1}***${c2}/${c1}* + ***${c2}/${c1}*******${c2}//${c1}*** + **${c2}/${c1}********${c2}///${c1}*${c2}/${c1}** + **${c2}/${c1}*******${c2}////${c1}***${c2}/${c1}** + **${c2}/${c1}****${c2}//////.,${c1}****${c2}/${c1}** + ***${c2}/${c1}*****${c2}/////////${c1}**${c2}/${c1}*** + ****${c2}/${c1}**** ${c2}/////${c1}***${c2}/${c1}**** + ******${c2}/${c1}*** ${c2}//// ${c1}**${c2}/${c1}****** + ********${c2}/${c1}* ${c2}/// ${c1}*${c2}/${c1}******** + ,****** ${c2}// ______ / ${c1}******, diff --git a/src/logo/ascii/arco.txt b/src/logo/ascii/arco.txt new file mode 100644 index 0000000000..d24c3ca380 --- /dev/null +++ b/src/logo/ascii/arco.txt @@ -0,0 +1,20 @@ + /- + ooo: + yoooo/ + yooooooo + yooooooooo + yooooooooooo + .yooooooooooooo + .oooooooooooooooo + .oooooooarcoooooooo + .ooooooooo-oooooooooo + .ooooooooo- oooooooooo + :ooooooooo. :ooooooooo + :ooooooooo. :ooooooooo + :oooarcooo .oooarcooo + :ooooooooy .ooooooooo + $1:ooooooooo $2/ooooooooooooooooooo + $1:ooooooooo $2.-ooooooooooooooooo. + $1ooooooooo- $2-ooooooooooooo. + $1ooooooooo- $2.-oooooooooo. +$1ooooooooo. $2-ooooooooo \ No newline at end of file diff --git a/src/logo/ascii/arco_small.txt b/src/logo/ascii/arco_small.txt new file mode 100644 index 0000000000..cafcc54413 --- /dev/null +++ b/src/logo/ascii/arco_small.txt @@ -0,0 +1,11 @@ +${c1} A + ooo + ooooo + ooooooo + ooooooooo + ooooo ooooo + ooooo ooooo + ooooo ooooo + ooooo ${c2}${c1} + ooooo ${c2}${c1} +ooooo ${c2} diff --git a/src/logo/ascii/arselinux.txt b/src/logo/ascii/arselinux.txt new file mode 100644 index 0000000000..6e673bc813 --- /dev/null +++ b/src/logo/ascii/arselinux.txt @@ -0,0 +1,15 @@ + ⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⣶⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⣴⣶⠀⠀⠀⠀⠀ +⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣄⠀⠀⠀⠀⣼⠟⠁⠀⠀⢀⣀⠀ +⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡀⠀⢀⣤⡀⠀⠀⠀⠉⢻⣷⡄⠀⠀⠁⠀⢀⣤⣾⡿⠟⠀ +⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣷⣿⠏⠀⠀⠀⠀⠀⠀⠹⣿⡄⠀⠀⠀⠙⠉⠁⠀⠀⠀ +⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⡄⠀⠀⠀⠀⠀⠀⠀⢹⣿⠀⠀⠀⠀⠠⣶⣶⣶⡶ +⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀ +⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⢠⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀ +⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠂⠀⠀⠀⠀⠀⢀⣾⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠇⠀⠀⠀⠀⠀⣠⣾⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⣿⣇⣀⣀⣀⣠⣴⣾⣿⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⢸⣿⠀⠀⠀⠀⠀⣤⣤⣴⣶⣾⠿⠟⣿⡏⠙⠛⠛⠛⠋⠉⢀⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⣿⡄⠀⠀⠀⠀⠈⠉⠉⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⢸⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⠇⠀⠀⠀⠀⠀⠀⠘⠿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ diff --git a/src/logo/ascii/artix.txt b/src/logo/ascii/artix.txt new file mode 100644 index 0000000000..a1e26a804e --- /dev/null +++ b/src/logo/ascii/artix.txt @@ -0,0 +1,20 @@ + ' + 'o' + 'ooo' + 'ooxoo' + 'ooxxxoo' + 'oookkxxoo' + 'oiioxkkxxoo' + ':;:iiiioxxxoo' + `'.;::ioxxoo' + '-. `':;jiooo' + 'oooio-.. `'i:io' + 'ooooxxxxoio:,. `'-;' + 'ooooxxxxxkkxoooIi:-. `' + 'ooooxxxxxkkkkxoiiiiiji' + 'ooooxxxxxkxxoiiii:'` .i' + 'ooooxxxxxoi:::'` .;ioxo' + 'ooooxooi::'` .:iiixkxxo' + 'ooooi:'` `'';ioxxo' + 'i:'` '':io' +'` `' \ No newline at end of file diff --git a/src/logo/ascii/artix2_small.txt b/src/logo/ascii/artix2_small.txt new file mode 100644 index 0000000000..14e70835aa --- /dev/null +++ b/src/logo/ascii/artix2_small.txt @@ -0,0 +1,13 @@ + ' + 'A' + 'ooo' + 'ookxo' + `ookxxo' + '. `ooko' + 'ooo`. `oo' + 'ooxxxoo`. `' + 'ookxxxkooo.` . + 'ookxxkoo'` .'oo' + 'ooxoo'` .:ooxxo' + 'io'` `'oo' +'` `' diff --git a/src/logo/ascii/artix_small.txt b/src/logo/ascii/artix_small.txt new file mode 100644 index 0000000000..7e016d82c3 --- /dev/null +++ b/src/logo/ascii/artix_small.txt @@ -0,0 +1,7 @@ + /\ + / \ + /`'.,\ + / ', + / ,`\ + / ,.'`. \ +/.,'` `'.\ \ No newline at end of file diff --git a/src/logo/ascii/arya.txt b/src/logo/ascii/arya.txt new file mode 100644 index 0000000000..7d603e20d8 --- /dev/null +++ b/src/logo/ascii/arya.txt @@ -0,0 +1,15 @@ +${c1} `oyyy/${c2}-yyyyyy+ +${c1} -syyyy/${c2}-yyyyyy+ +${c1} .syyyyy/${c2}-yyyyyy+ +${c1} :yyyyyy/${c2}-yyyyyy+ +${c1} `/ :yyyyyy/${c2}-yyyyyy+ +${c1} .+s :yyyyyy/${c2}-yyyyyy+ +${c1} .oys :yyyyyy/${c2}-yyyyyy+ +${c1} -oyys :yyyyyy/${c2}-yyyyyy+ +${c1} :syyys :yyyyyy/${c2}-yyyyyy+ +${c1} /syyyys :yyyyyy/${c2}-yyyyyy+ +${c1} +yyyyyys :yyyyyy/${c2}-yyyyyy+ +${c1} .oyyyyyyo. :yyyyyy/${c2}-yyyyyy+ --------- +${c1} .syyyyyy+` :yyyyyy/${c2}-yyyyy+-+syyyyyyyy +${c1} -syyyyyy/ :yyyyyy/${c2}-yyys:.syyyyyyyyyy +${c1}:syyyyyy/ :yyyyyy/${c2}-yyo.:syyyyyyyyyyy diff --git a/src/logo/ascii/asahi.txt b/src/logo/ascii/asahi.txt new file mode 100644 index 0000000000..005f056138 --- /dev/null +++ b/src/logo/ascii/asahi.txt @@ -0,0 +1,18 @@ +$1 ## $2** + $1*####$2****. + $1###$2, + $3...,$1/#$3,,,.. + $3/*,,,,,,,,$1*$3,........$4,, + $3,((((((//*,,,,,,,,$4,...... + $3(((((((((((((($5%..$4.......... + $3,((((((((((((((($5@@($4............ + $3((((((((((((((((($5@@@@/$4............ + $3,(((((((((((((((((($5@@@@@&*$4........... + $3(((((((((((((((((((($5@@@@@@@&$4,........... +$3((((((((((((((((((((($5@@@$6&%&$5@@@%$4,.......... + $3/((((((((((((((((((($5@@@$6&%%&$5@@@@($4........ + $3,(((((((((((((((($5@@@$6&&$5@@&/&@@@/$4.. + $3/(((((((((((($5@@@@@@/$4.../&& + $3.((((((((($5@@@@($4.... + $3/((((($5@@#$4... + $3.(($4&, \ No newline at end of file diff --git a/src/logo/ascii/aster.txt b/src/logo/ascii/aster.txt new file mode 100644 index 0000000000..52d893d1d6 --- /dev/null +++ b/src/logo/ascii/aster.txt @@ -0,0 +1,18 @@ + ...''... + .;oOXWMWNXXXNMMN0d:. + .oXMWOo;.. ..:oO; + ;KMWx, co, + 'KMNl dMMW. + oMMx xMMMMk + xMM: dMMMMMM; + cMMl dMMMMMMMW + NMK xMMMx::dXMx +,MMl xMMN' .o. +cMM; dMMW' +;MMc oMMW, + WMK dMMW, ccccccc. + lMMl oMMM; ooooooo. + OMMc ... + xMMx + ;XMN: + ,. diff --git a/src/logo/ascii/asteroidos.txt b/src/logo/ascii/asteroidos.txt new file mode 100644 index 0000000000..124bf92a2f --- /dev/null +++ b/src/logo/ascii/asteroidos.txt @@ -0,0 +1,17 @@ +${c1} *** +${c1} ***** +${c1} ********** +${c1} *************** +${c1} *///****////****////. +${c2} (/////// /////// ///////( +${c2} /(((((//* //, //((((((. +${c2} ((((((((((( ((( (((((((( +${c2} *((((((((((((((((((((((( (((((((( +${c3} (((((#(((((((#((((( ((#((((( +${c3} (#(#(#####(#(#, ####(#(# +${c3} ######### ######## +${c3} /######## ######## +${c4} #######%####### +${c4} (#%%%%%%%# +${c4} %%%%% +${c4} %%% diff --git a/src/logo/ascii/astos.txt b/src/logo/ascii/astos.txt new file mode 100644 index 0000000000..3e06aefd72 --- /dev/null +++ b/src/logo/ascii/astos.txt @@ -0,0 +1,23 @@ + oQA#$%UMn + H 9 + G # + 6 % + ?#M#%KW3" + // \\\ + // \\\ + // \\\ + // \\\ + n%@$DK&ML .0O3#@&M_ + P # 8 W + H U G # + B N O @ + C&&#%HNAR 'WS3QMHB" + // \\\ \\\ + // \\\ \\\ + // \\\ \\\ + // \\\ \\\ +uURF$##Bv nKWB$%ABc aM@3R@D@b +8 M @ O # % +% & G U @ @ +& @ # % % # +!HGN@MNCf t&S9#%HQr ?@G#6S@QP diff --git a/src/logo/ascii/astra_linux.txt b/src/logo/ascii/astra_linux.txt new file mode 100644 index 0000000000..97b7bc6863 --- /dev/null +++ b/src/logo/ascii/astra_linux.txt @@ -0,0 +1,22 @@ + AA + AaaA + Aa${c2}/\\${c1}aA +${c1} Aa${c2}/${c1}aa${c2}\\${c1}aA +${c1} Aa${c2}/${c1}aAAa${c2}\\${c1}aA +${c1} aA${c2}/${c1}aaAAaa${c2}\\${c1}Aa +${c1} aA${c2}/${c1}aaAAAAaa${c2}\\${c1}Aa +${c1} aaaaaaAAAAa${c2}/${c1}aaAAAAAAaa${c2}\\${c1}aAAAAaaaaa +${c1}aAAa${c2}-----${c1}aaaaaAAAAAAAAAAaaaaa${c2}-----${c1}aAAa +${c1} aAA${c2}\ ${c1}aAAAAAAAAAAAAAAAAAAAAAAa${c2} /${c1}AAa +${c1} aAa${c2}\\${c1}aAAA${c2}\\${c1}AAAA${c2}\\${c1}AAAA${c2}\\${c1}AAA${c2}\\${c1}AAa${c2}/${c1}aAa +${c1} aAa${c2}\\${c1}aA${c2}\\\\${c1}AAA${c2}\\\\${c1}AAA${c2}\\\\${c1}AA${c2}\\\\/${c1}aAa +${c1} aAA${c2}\\${c1}aA${c2}\\\\${c1}AAA${c2}\\\\${c1}AAA${c2}\\\\${c1}Aa${c2}/${c1}AAa +${c1} aA${c2}\\${c1}aA${c2}\\\\${c1}AAA${c2}\\\\${c1}AAA${c2}\\\\/${c1}Aa +${c1} aA${c2}/${c1}AA${c2}\\\\\\${c1}AA${c2}\\\\\\${c1}AA${c2}\\\\\\${c1}Aa +${c1} aA${c2}/\\${c1}AAa${c2}\\\\\\${c1}Aa${c2}\\\\\\${c1}Aa${c2}\\\\\\${c1}Aa +${c1} aA${c2}/\\\\${c1}AAa${c2}\\\\/\\${c1}a${c2}\\\\\\${c1}Aa${c2}\\\\${c1}Aa +${c1} aA${c2}/${c1}a${c2}\\\\\\${c1}Aa${c2}\\/${c1}AA${c2}\\\\\\\\\\${c1}Aa${c2}\\\\${c1}Aa +${c1} aA${c2}/${c1}aA${c2}\\\\/${c1}aAa aAa${c2}\\\\\\${c1}Aa${c2}\\${c1}Aa +${c1} aA${c2}/\\${c1}A${c2}\\/${c1}Aa aA${c2}\\\\${c1}A${c2}\\\\${c1}Aa +${c1} A${c2}|/${c1}aaAa aAaa${c2}\\|${c1}A +${c1} aAaa aaAa diff --git a/src/logo/ascii/athena.txt b/src/logo/ascii/athena.txt new file mode 100644 index 0000000000..1cbd3145b9 --- /dev/null +++ b/src/logo/ascii/athena.txt @@ -0,0 +1,24 @@ +${c1} . .. +${c1} :####: ####. +${c1} .################ +${c1} :################## +${c1}.###################. +${c1}######## ####### +${c1}####### ${c2}####${c1} ##### +${c1}:#######. #### +${c1} ######### ${c2}#${c1} ## # +${c1} ####### ${c2}##${c1} #### +${c1}######## ${c2}####${c1} ####### +${c1}######## ${c2}#####${c1} ######## +${c1}######## ${c2}#######${c1} ####### +${c1} ####### ${c2}########${c1} ####### +${c1} ######## ${c2}#########${c1} ###### +${c1} ######## ${c2}#########${c1} ##### +${c1} ####### ${c2}#########${c1} #### +${c1} ####### ${c2}#########${c1} ## +${c1} ####### ${c2}########${c1} ## +${c1} ###### ${c2}########${c1} # +${c1} ### ${c2}#######${c1} +${c1} ${c2}######${c1} +${c1} ${c2}####${c1} +${c1} ${c2}##${c1} diff --git a/src/logo/ascii/bedrock.txt b/src/logo/ascii/bedrock.txt new file mode 100644 index 0000000000..6bbd44a1eb --- /dev/null +++ b/src/logo/ascii/bedrock.txt @@ -0,0 +1,17 @@ +-------------------------------------- +-------------------------------------- +-------------------------------------- +---$2\\\\\\\\\\\\$1----------------------- +----$2\\\ \\\$1---------------------- +-----$2\\\ \\\$1--------------------- +------$2\\\ \\\\\\\\\\\\\\\\\$1------ +-------$2\\\ \\\$1----- +--------$2\\\ \\\$1---- +---------$2\\\ ______ \\\$1--- +----------$2\\\ ///$1--- +-----------$2\\\ ///$1---- +------------$2\\\ ///$1----- +-------------$2\\\////////////////$1------ +-------------------------------------- +-------------------------------------- +-------------------------------------- \ No newline at end of file diff --git a/src/logo/ascii/biglinux.txt b/src/logo/ascii/biglinux.txt new file mode 100644 index 0000000000..3570e85885 --- /dev/null +++ b/src/logo/ascii/biglinux.txt @@ -0,0 +1,19 @@ + ... + :OWMMMNd. + :NMMMMMMMMWc + okkl. kMMMMMW0xdOWMl + : xMMMMMW. kMMMMNc lW. + :x NMMMMMO ,MMMM0. 'l + Xx "lkk" kMMMX .okx, +${c2}.MX .cc;. .xXKx. KMMM: .OMMMMMl +:MM' 'KMMMMWK: 0MMMMk xMMM. lWMMMMMMM' +cMMN:;xMMMMk::MMO oMMMMX .XMM. .KMMMWOOMMMd +'MMMMMMMMN, NMMx OMMMMl .kM0OMMMMk. ;MMd + xMMMMMMd .MMMW :NMMMd .ckKKx' KMc + dWMNd. oMMMN lkNMX, oM. + ;. ;MMMMx "MM:. cO +${c3} .X. oMMMMW. l. + dMk:..;xWMMMMW, + kMMMMMMMMMMX. + :XMMMMMMK: + ':MM:" Made in Brazil diff --git a/src/logo/ascii/bitrig.txt b/src/logo/ascii/bitrig.txt new file mode 100644 index 0000000000..c360216ff4 --- /dev/null +++ b/src/logo/ascii/bitrig.txt @@ -0,0 +1,17 @@ + `hMMMMN+ + -MMo-dMd` + oMN- oMN` + yMd /NM: + .mMmyyhMMs + :NMMMhsmMh + +MNhNNoyMm- + hMd.-hMNMN: + mMmsssmMMMo + .MMdyyhNMMMd + oMN.`/dMddMN` + yMm/hNm+./MM/ +.dMMMmo.``.NMo +:NMMMNmmmmmMMh +/MN/-------oNN: +hMd. .dMh +sm/ /ms diff --git a/src/logo/ascii/blackarch.txt b/src/logo/ascii/blackarch.txt new file mode 100644 index 0000000000..d8dd4afc47 --- /dev/null +++ b/src/logo/ascii/blackarch.txt @@ -0,0 +1,21 @@ +${c3} 00 + 11 + ====${c1} + .${c3}//${c1} + `o${c3}//${c1}: + `+o${c3}//${c1}o: + `+oo${c3}//${c1}oo: + -+oo${c3}//${c1}oo+: + `/:-:+${c3}//${c1}ooo+: + `/+++++${c3}//${c1}+++++: + `/++++++${c3}//${c1}++++++: + `/+++o${c2}ooo${c3}//${c2}ooo${c1}oooo/` +${c2} ${c1}./${c2}ooosssso${c3}//${c2}osssssso${c1}+` +${c2} .oossssso-`${c3}//${c1}`/ossssss+` + -osssssso. ${c3}//${c1} :ssssssso. + :osssssss/ ${c3}//${c1} osssso+++. + /ossssssss/ ${c3}//${c1} +ssssooo/- + `/ossssso+/:- ${c3}//${c1} -:/+osssso+- + `+sso+:-` ${c3}//${c1} `.-/+oso: + `++:. ${c3}//${c1} `-/+/ + .` ${c3}/${c1} `/ diff --git a/src/logo/ascii/blackpanther.txt b/src/logo/ascii/blackpanther.txt new file mode 100644 index 0000000000..e14329fb6e --- /dev/null +++ b/src/logo/ascii/blackpanther.txt @@ -0,0 +1,23 @@ +${c3} ........ + .,»╔╗╗╬▄▄╫█▀▓▄▄╬╗╗g≈,. + ,j╗╬╣▓▓███████▌;»╙▀▀▀▀█▄▄╗j, + .≈╗╬▓██▀▀▀▀▀╠╙░░»»;:`${c2}``>${c1}▄ ${c3}▐ ▓╫╗⌂, + .j╬▓█▀▒░░░░░░░░░»»»;:```` ╙▀█▌╬░, + ;╗▓█▄▄███████▀░░»»»»;```` ╓▄▄█▄▄φ ██▌Ñ>. + .j╣█████▀▀░░░░░░░░»»╓▄▄¿``▄███████/▄████▓╬U. + .j╣▓██▀ÜÑ╦╦░░░░░░▐█@▄████⌐▐███████████████▓╬H. + «╫▓█▀░ÑÑ╩╦░░░░░░░░▀██████M"▀███████████████▓╫░ + :]╣█▌ÑÑÑÑ▄▄██▀░░░░»»██████████████████████████Ñ~ + »╫▓█╫ÑÑ▄███▀░░░░░»»▐██████████████████████████▌░ + `j╣█▌Ñ╬████░░░░░░░»»▐████████████████████████▌▐█U` + `/╫█▌▄███▌░░░░░░░»»»;▀██████████████▀████████w▐█░` + ;╟█▌███▌░░░░░░░▄▄»»;:`▀▀████████▀Ü▄████████▌ ▐▌>` + `]▓████░░░░░░░░██⌂;:````╓▄▄µp╓▄▄██████████▀ ,█M` + "╠╣██▌░░░░░░░»██▌;```` ╙▀██████████████M █▀" + "╟╣█░░░░░░░░»███⌂``` ▐▀████████▀░ █▌░` + "╩█▄░░░░░░»»▀███ `` └└` ,█▀"` + `░▀█▄░░░»»»»████@ .▄█Ü` + `╙▀█▄@»»»;`▀███▌¿ ,▄▀Ñ"` + `"╨▀█▄▄▄░`▐█████▄, ,▄▄▀▀░` + `"╙╩▀▀▀▀████████▓▌▌▌▀▀▀╨"`` + ``""░╚╨╝╝╝╝╨╨░""`` diff --git a/src/logo/ascii/blag.txt b/src/logo/ascii/blag.txt new file mode 100644 index 0000000000..1275cf657e --- /dev/null +++ b/src/logo/ascii/blag.txt @@ -0,0 +1,17 @@ + d + ,MK: + xMMMX: + .NMMMMMX; + lMMMMMMMM0clodkO0KXWW: + KMMMMMMMMMMMMMMMMMMX' + .;d0NMMMMMMMMMMMMMMMMMMK. + .;dONMMMMMMMMMMMMMMMMMMMMMMx +'dKMMMMMMMMMMMMMMMMMMMMMMMMl + .:xKWMMMMMMMMMMMMMMMMMMM0. + .:xNMMMMMMMMMMMMMMMMMK. + lMMMMMMMMMMMMMMMMMMK. + ,MMMMMMMMWkOXWMMMMMM0 + .NMMMMMNd. `':ldko + OMMMK: + oWk, + ;: diff --git a/src/logo/ascii/blankon.txt b/src/logo/ascii/blankon.txt new file mode 100644 index 0000000000..43bbd78653 --- /dev/null +++ b/src/logo/ascii/blankon.txt @@ -0,0 +1,17 @@ +${c2} `./ohdNMMMMNmho+.` ${c1} .+oo:` +${c2} -smMMMMMMMMMMMMMMMMmy-` ${c1}`yyyyy+ +${c2} `:dMMMMMMMMMMMMMMMMMMMMMMd/` ${c1}`yyyyys +${c2} .hMMMMMMMNmhso/++symNMMMMMMMh- ${c1}`yyyyys +${c2} -mMMMMMMms-` -omMMMMMMN-${c1}.yyyyys +${c2}.mMMMMMMy. .yMMMMMMm:${c1}yyyyys +${c2}sMMMMMMy `sMMMMMMh${c1}yyyyys +${c2}NMMMMMN: .NMMMMMN${c1}yyyyys +${c2}MMMMMMm. NMMMMMN${c1}yyyyys +${c2}hMMMMMM+ /MMMMMMN${c1}yyyyys +${c2}:NMMMMMN: :mMMMMMM+${c1}yyyyys +${c2} oMMMMMMNs- .sNMMMMMMs.${c1}yyyyys +${c2} +MMMMMMMNho:.` `.:ohNMMMMMMNo ${c1}`yyyyys +${c2} -hMMMMMMMMNNNmmNNNMMMMMMMMh- ${c1}`yyyyys +${c2} :yNMMMMMMMMMMMMMMMMMMNy:` ${c1}`yyyyys +${c2} .:sdNMMMMMMMMMMNds/. ${c1}`yyyyyo +${c2} `.:/++++/:.` ${c1}:oys+. diff --git a/src/logo/ascii/bluelight.txt b/src/logo/ascii/bluelight.txt new file mode 100644 index 0000000000..05eba637cb --- /dev/null +++ b/src/logo/ascii/bluelight.txt @@ -0,0 +1,19 @@ + oMMNMMMMMMMMMMMMMMMMMMMMMM + oMMMMMMMMMMMMMMMMMMMMMMMMM + oMMMMMMMMMMMMMMMMMMMMMMMMM + oMMMMMMMMMMMMMMMMMMMMMMMMM + -+++++++++++++++++++++++mM${c2} + ```````````````````````..${c1}dM${c2} + ```````````````````````....${c1}dM${c2} + ```````````````````````......${c1}dM${c2} + ```````````````````````........${c1}dM${c2} + ```````````````````````..........${c1}dM${c2} + ```````````````````````............${c1}dM${c2} +.::::::::::::::::::::::-..............${c1}dM${c2} + `-+yyyyyyyyyyyyyyyyyyyo............${c1}+mMM${c2} + -+yyyyyyyyyyyyyyyyo..........${c1}+mMMMM${c2} + ./syyyyyyyyyyyyo........${c1}+mMMMMMM${c2} + ./oyyyyyyyyyo......${c1}+mMMMMMMMM${c2} + omdyyyyyyo....${c1}+mMMMMMMMMMM${c2} + ${c1}oMMM${c2}mdhyyo..${c1}+mMMMMMMMMMMMM + oNNNNNNm${c2}dso${c1}mMMMMMMMMMMMMMM diff --git a/src/logo/ascii/bodhi.txt b/src/logo/ascii/bodhi.txt new file mode 100644 index 0000000000..6b49f9b3ef --- /dev/null +++ b/src/logo/ascii/bodhi.txt @@ -0,0 +1,18 @@ +${c1}| ${c2},,mmKKKKKKKKWm,, + ${c1}' ${c2},aKKP${c1}LL**********|L*${c2}TKp, + ${c1}t ${c2}aKP${c1}L**``` ```**L${c2}*Kp + IX${c1}EL${c3}L,wwww, ${c1}``*||${c2}Kp + ,#P${c1}L|${c3}KKKpPP@IPPTKmw, ${c1}`*||${c2}K + ,K${c1}LL*${c3}{KKKKKKPPb$KPhpKKPKp ${c1}`||${c2}K + #${c1}PL ${c3}!KKKKKKPhKPPP$KKEhKKKKp ${c1}`||${c2}K +!H${c1}L* ${c3}1KKKKKKKphKbPKKKKKK$KKp ${c1}`|I${c2}W +$$$${c1}bL ${c3}KKKKKKKKBQKhKbKKKKKKKK ${c1}|I${c2}N +$$$${c1}bL ${c3}!KKKKKKKKKKNKKKKKKKPP` ${c1}|I${c2}b +TH${c1}L* ${c3}TKKKKKK##KKKN@KKKK^ ${c1}|I${c2}M + K@${c1}L ${c3}*KKKKKKKKKKKEKE5 ${c1}||${c2}K + `NL${c1}L ${c3}`KKKKKKKKKK"```|L ${c1}||${c2}#P + `K@${c1}LL ${c3}`"**"` ${c1}'. :||${c2}#P + Yp${c1}LL ${c1}' |L${c2}$M` + `Tp${c1}pLL, ,|||${c2}p'L + "Kpp${c1}LL++,., ,,|||$$$${c2}#K* ${c1}'. + ${c2}`"MKWpppppppp#KM"` ${c1}`h, diff --git a/src/logo/ascii/bonsai.txt b/src/logo/ascii/bonsai.txt new file mode 100644 index 0000000000..4dbc8d5eac --- /dev/null +++ b/src/logo/ascii/bonsai.txt @@ -0,0 +1,16 @@ +${c2} ,####, + ${c2}#######, ${c2},#####, + ${c2}#####',# ${c2}'###### + ${c2}''###'${c3}';,,,'${c2}###' + ${c3} ,; '''' + ${c3} ;;; ${c2},#####, + ${c3} ;;;' ,,;${c2};;### + ${c3} ';;;;''${c2}'####' + ${c3} ;;; + ${c3} ,.;;';'',,, + ${c3} ' ' +${c1} # + # O + ##, ,##,',##, ,## ,#, , + # # # # #''# #,, # # # + '#' '##' # # ,,# '##;, # diff --git a/src/logo/ascii/bsd.txt b/src/logo/ascii/bsd.txt new file mode 100644 index 0000000000..adf0b8579f --- /dev/null +++ b/src/logo/ascii/bsd.txt @@ -0,0 +1,19 @@ +$1 , , + /( )` + \ \___ / | + /- _ `-/ ' + ($2/\/ \ $1\ /\ + $2/ / | ` $1\ + $3O O $2) $1/ | + $2`-^--'$1`< ' + (_.) _ ) / + `.___/` / + `-----' / +$4<----. __ / __ \ +$4<----|====$1O)))$4==$1) \) /$4====| +<----' $1`--' `.__,' \ + | | + \ / /\ + $5______$1( (_ / \______/ + $5,' ,-----' | + `--{__________) diff --git a/src/logo/ascii/bunsenlabs.txt b/src/logo/ascii/bunsenlabs.txt new file mode 100644 index 0000000000..218c417f89 --- /dev/null +++ b/src/logo/ascii/bunsenlabs.txt @@ -0,0 +1,20 @@ + `++ + -yMMs + `yMMMMN` + -NMMMMMMm. + :MMMMMMMMMN- + .NMMMMMMMMMMM/ + yMMMMMMMMMMMMM/ +`MMMMMMNMMMMMMMN. +-MMMMN+ /mMMMMMMy +-MMMm` `dMMMMMM +`MMN. .NMMMMM. + hMy yMMMMM` + -Mo +MMMMN + /o +MMMMs + +MMMN` + hMMM: + `NMM/ + +MN: + mh. + -/ diff --git a/src/logo/ascii/cachyos.txt b/src/logo/ascii/cachyos.txt new file mode 100644 index 0000000000..10c1e424dc --- /dev/null +++ b/src/logo/ascii/cachyos.txt @@ -0,0 +1,22 @@ + $3.$1-------------------------: + .$2+=$1========================. + :$2++$1===$2++===$1===============- :$2++$1- + :$2*++$1====$2+++++==$1===========- .==: + -$2*+++$1=====$2+***++=$1=========: + =$2*++++=$1=======------------: + =$2*+++++=$1====- $3...$1 + .$2+*+++++$1=-===: .$2=+++=$1: + :$2++++$1=====-==: -***$2**$1+ + :$2++=$1=======-=. .=+**+$3.$1 +.$2+$1==========-. $3.$1 + :$2+++++++$1====- $3.$1--==-$3.$1 + :$2++$1==========. $3:$2+++++++$1$3: + $1.-===========. =*****+*+ + $1.-===========: .+*****+: + $1-=======$2++++$1:::::::::::::::::::::::::-: $3.$1---: + :======$2++++$1====$2+++******************=. + $1:=====$2+++$1==========$2++++++++++++++*- + $1.====$2++$1==============$2++++++++++*- + $1.===$2+$1==================$2+++++++: + $1.-=======================$2+++: + $3.......................... \ No newline at end of file diff --git a/src/logo/ascii/cachyos_small.txt b/src/logo/ascii/cachyos_small.txt new file mode 100644 index 0000000000..f3ea5d87ce --- /dev/null +++ b/src/logo/ascii/cachyos_small.txt @@ -0,0 +1,8 @@ + /''''''''''''/ + /''''''''''''/ + /''''''/ +/''''''/ +\......\ + \......\ + \.............../ + \............./ diff --git a/src/logo/ascii/calculate.txt b/src/logo/ascii/calculate.txt new file mode 100644 index 0000000000..86f4974d70 --- /dev/null +++ b/src/logo/ascii/calculate.txt @@ -0,0 +1,20 @@ + ...... + ,,+++++++,. + .,,,....,,,${c2}+**+,,.${c1} + ............,${c2}++++,,,${c1} + ............... + ......,,,........ + .....+*#####+,,,*+. + .....,*###############,..,,,,,,.. + ......,*#################*..,,,,,..,,,.. + .,,....*####################+***+,,,,...,++, + .,,..,..*#####################*, + ,+,.+*..*#######################. + ,+,,+*+..,########################* +.,++++++. ..+##**###################+ +..... ..+##***#################*. + .,.*#*****##############*. + ..,,*********#####****+. + ${c2}.,++*****+++${c1}*****************${c2}+++++,.${c1} + ${c2},++++++**+++++${c1}***********${c2}+++++++++,${c1} + ${c2}.,,,,++++,.. .,,,,,.....,+++,.,,${c1} diff --git a/src/logo/ascii/calinixos.txt b/src/logo/ascii/calinixos.txt new file mode 100644 index 0000000000..85475c52bb --- /dev/null +++ b/src/logo/ascii/calinixos.txt @@ -0,0 +1,25 @@ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⠤⠔⠒⠒⠋⠉⠉⠉⠉⠓⠒⠒⠦⠤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠤⠒⠉⣁⣠⣤⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣤⣄⣈⠙⠲⢤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠴⠋⢁⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⡈⠑⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⣠⠞⢁⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⢀⠞⠁⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⠋⠉⠁⠀⠀⠀⠀⠈⠉⠙⠛⠿⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⠈⢢⡀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⡰⠃⣠⣾⣿⣿⣿⣿⣿⣿⡿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠻⢿⡿⠁⠀⠀⠀⠀⠀⠀⠙⣄⠀⠀⠀⠀ +⠀⠀⠀⡼⠁⣴⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢆⠀⠀⠀ +⠀⠀⡼⠀⣼⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣆⠀⠀ +⠀⣰⠁⣸⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠉⠻⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡄⠀ +⢀⡇⢠⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⢿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢳⠀ +⢸⠀⣸⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡄ +⣼⠀⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣿⣿⣿⣿⣷⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇ +⡇⠀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢛⣿⣿⣿⣿⣿⣿⣿⡦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇ +⢻⠀⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣶⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇ +⢸⡀⢹⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠃ +⠀⣇⠘⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⣿⣿⡿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⠀ +⠀⠸⡄⢹⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⣠⣶⣿⣿⣿⣿⣿⣿⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠃⠀ +⠀⠀⢳⡀⢻⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠈⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠏⠀⠀ +⠀⠀⠀⠳⡀⠻⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣷⣄⡀⠀⠀⠀⠀⢠⠏⠀⠀⠀ +⠀⠀⠀⠀⠙⣄⠙⢿⣿⣿⣿⣿⣿⣿⣷⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣾⣿⣿⣿⣿⣿⣦⡀⠀⡰⠃⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠈⠢⡈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣤⣄⣀⡀⠀⠀⠀⠀⢀⣀⣠⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⣠⠞⠁⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠈⠢⡈⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⣡⠞⠁⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠓⢤⡈⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⣁⠴⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⠢⢄⣉⠙⠛⠿⠿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠛⠋⣉⡤⠖⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠓⠒⠢⠤⠤⠤⠤⠤⠤⠤⠤⠖⠒⠋⠉⠀ diff --git a/src/logo/ascii/calinixos_small.txt b/src/logo/ascii/calinixos_small.txt new file mode 100644 index 0000000000..801e45fd77 --- /dev/null +++ b/src/logo/ascii/calinixos_small.txt @@ -0,0 +1,15 @@ +⠀⠀⠀⠀⠀⠀⠀⠀⣀⠤⠐⣂⣈⣩⣭⣭⣍⣀⣐⠀⠄⡀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⡀⠔⣨⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣅⠢⡀⠀⠀⠀⠀⠀ +⠀⠀⠀⠠⢊⣴⣾⣿⣿⣿⣿⠿⠟⠛⠛⠛⠛⠻⠿⣿⣿⣿⣿⠃⠀⠠⡀⠀⠀⠀ +⠀⠀⡐⢡⣾⣿⣿⣿⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠁⠀⠀⠀⠈⢆⠀⠀ +⠀⡘⢰⣿⣿⣿⡟⠁⠀⠀⢀⣀⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢂⠀ +⢠⢠⣿⣿⣿⡟⠀⠀⠀⠀⠀⠙⠿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡀ +⡄⢸⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣿⣦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁ +⡇⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣹⣿⣿⣿⣷⠄⠀⠀⠀⠀⠀⠀⠀⠀ +⠃⢸⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⡿⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⡀ +⠘⡘⣿⣿⣿⣧⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⠿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠁ +⠀⠡⠸⣿⣿⣿⣧⡀⠀⠀⠀⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⢀⠆⠀ +⠀⠀⠡⡘⢿⣿⣿⣿⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣿⣷⣦⡀⢀⠊⠀⠀ +⠀⠀⠀⠈⠊⡻⢿⣿⣿⣿⣿⣶⣤⣤⣤⣤⣤⣤⣶⣿⣿⣿⣿⡿⢟⠕⠁⠀⠀⠀ +⠀⠀⠀⠀⠀⠈⠢⢙⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⡩⠐⠁⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠈⠐⠂⠭⠉⠙⣛⣛⠋⠉⠭⠐⠂⠁⠀⠀⠀⠀ diff --git a/src/logo/ascii/carbs.txt b/src/logo/ascii/carbs.txt new file mode 100644 index 0000000000..71fdface7d --- /dev/null +++ b/src/logo/ascii/carbs.txt @@ -0,0 +1,18 @@ + .......... + ..,;:ccccccc:;'.. + ..,clllc:;;;;;:cllc,. + .,cllc,... ..';;'. + .;lol;.. .. + .,lol;. + .coo:. + .'lol,. + .,lol,. + .,lol,. + 'col;. + .:ooc'. + .'col:. + .'cllc'.. .''. + ..:lolc,'.......',cll,. + ..;cllllccccclllc;'. + ...',;;;;;;,,... + ..... diff --git a/src/logo/ascii/cbl_mariner.txt b/src/logo/ascii/cbl_mariner.txt new file mode 100644 index 0000000000..26e8fdcdbb --- /dev/null +++ b/src/logo/ascii/cbl_mariner.txt @@ -0,0 +1,18 @@ + . + :- . + :==. .=: + :===: -==: + :-===: .====: + :-====- -=====: + -====== :=======: + -======. .=========: + -======: -==========. + -======- -===========. + :======- :===========. + :=======. .-==========. + :=======: -==========. + :=======- :==========. + :=======- .-========- +:--------. :========- + ..:::--=========- + ..::---================-=- diff --git a/src/logo/ascii/celos.txt b/src/logo/ascii/celos.txt new file mode 100644 index 0000000000..b5b7661559 --- /dev/null +++ b/src/logo/ascii/celos.txt @@ -0,0 +1,15 @@ + `-:/++++/:-` + -/syyyyyyyyyyyyy+- + :ssssyyyyyyyyyyyyyyyy/ + .osy$2mmmmmmmmmmmmmmmNNNNNmmhy+ + $1.sssshhhhhhhddddddddddddddds- + $1`osssssssyyyyyyyyyyyyyyyyyyhy` + $1:ssssssyyyyyyyyyyyyyyyyyyyyhh/ +$2sMMMMMMMMMMMMMMMMMMMMMMMh$1yyyyyyhho + :sssssssyyyyyyyyyyyyyyyyyyyhh/ + `ssssssssyyyyyyyyyyyyyyyyyyhy. + -sssssyddddddddddddddddddddy + -ssss$2hmmmmmmmmmmmmmmmmmmmyssss- + $1`/ssssyyyyyyyyyyyyyyyy+` + $1`:osyyyyyyyyyyyyys/` + $1`.:/+ooooo+:-` \ No newline at end of file diff --git a/src/logo/ascii/center.txt b/src/logo/ascii/center.txt new file mode 100644 index 0000000000..1b9b3199a6 --- /dev/null +++ b/src/logo/ascii/center.txt @@ -0,0 +1,13 @@ + . + o, + . d, . + ';' ..d;.. .cl' + .:; 'oldO,.oo. + ..,:,xKXxoo;'. + ,;;;;;ldxkONMMMXxkxc;;;;;. + .....':oddXWMNOxlcl:...... + .:dlxk0c;:. . + :d:.,xcld,.,:. + ;l, .l; ';' + .o; + l, diff --git a/src/logo/ascii/centos.txt b/src/logo/ascii/centos.txt new file mode 100644 index 0000000000..be42a9de56 --- /dev/null +++ b/src/logo/ascii/centos.txt @@ -0,0 +1,19 @@ + .. + .PLTJ. + <><><><> + $2KKSSV' 4KKK $1LJ$4 KKKL.'VSSKK + $2KKV' 4KKKKK $1LJ$4 KKKKAL 'VKK + $2V' ' 'VKKKK $1LJ$4 KKKKV' ' 'V + $2.4MA.' 'VKK $1LJ$4 KKV' '.4Mb. + $4. $2KKKKKA.' 'V $1LJ$4 V' '.4KKKKK $3. + $4.4D $2KKKKKKKA.'' $1LJ$4 ''.4KKKKKKK $3FA. +$4 + '$4VD $3KKKKKKKK'.. $2LJ $1..'KKKKKKKK $3FV + $4' $3VKKKKK'. .4 $2LJ $1K. .'KKKKKV $3' + $3'VK'. .4KK $2LJ $1KKA. .'KV' + $3A. . .4KKKK $2LJ $1KKKKA. . .4 + $3KKA. 'KKKKK $2LJ $1KKKKK' .4KK + $3KKSSA. VKKK $2LJ $1KKKV .4SSKK + $2<><><><> + $2'MKKM' + $2'' \ No newline at end of file diff --git a/src/logo/ascii/centos_small.txt b/src/logo/ascii/centos_small.txt new file mode 100644 index 0000000000..52d8027a72 --- /dev/null +++ b/src/logo/ascii/centos_small.txt @@ -0,0 +1,7 @@ + $2____$1^$4____ + $2|\ $1|$4 /| + $2| \ $1|$4 / | +$4<---- $3----> + $3| / $2|$1 \ | + $3|/__$2|$1__\| + $2v \ No newline at end of file diff --git a/src/logo/ascii/chakra.txt b/src/logo/ascii/chakra.txt new file mode 100644 index 0000000000..284117e3ac --- /dev/null +++ b/src/logo/ascii/chakra.txt @@ -0,0 +1,18 @@ + _ _ _ "kkkkkkkk. + ,kkkkkkkk., 'kkkkkkkkk, + ,kkkkkkkkkkkk., 'kkkkkkkkk. + ,kkkkkkkkkkkkkkkk,'kkkkkkkk, + ,kkkkkkkkkkkkkkkkkkk'kkkkkkk. + "''"''',;::,,"''kkk''kkkkk; __ + ,kkkkkkkkkk, "k''kkkkk' ,kkkk + ,kkkkkkk' ., ' .: 'kkkk',kkkkkk + ,kkkkkkkk'.k' , ,kkkk;kkkkkkkkk + ,kkkkkkkk';kk 'k "'k',kkkkkkkkkkkk +.kkkkkkkkk.kkkk.'kkkkkkkkkkkkkkkkkk' +;kkkkkkkk''kkkkkk;'kkkkkkkkkkkkk'' +'kkkkkkk; 'kkkkkkkk.,""''"''"" + ''kkkk; 'kkkkkkkkkk., + ';' 'kkkkkkkkkkkk., + ';kkkkkkkkkk' + ';kkkkkk' + "''" diff --git a/src/logo/ascii/chaletos.txt b/src/logo/ascii/chaletos.txt new file mode 100644 index 0000000000..d1e405c7f2 --- /dev/null +++ b/src/logo/ascii/chaletos.txt @@ -0,0 +1,20 @@ + `.//+osso+/:`` + `/sdNNmhyssssydmNNdo:` + :hNmy+-` .-+hNNs- + /mMh/` `+:` `+dMd: + .hMd- -sNNMNo. /yyy /mMs` + -NM+ `/dMd/--omNh::dMM `yMd` + .NN+ .sNNs:/dMNy:/hNmo/s yMd` + hMs `/hNd+-smMMMMMMd+:omNy- `dMo +:NM. .omMy:/hNMMMMMMMMMMNy:/hMd+` :Md` +/Md` `sm+.omMMMMMMMMMMMMMMMMd/-sm+ .MN: +/Md` MMMMMMMMMMMMMMMMMMMN .MN: +:NN. MMMMMMm....--NMMMMMN -Mm. +`dMo MMMMMMd mMMMMMN hMs + -MN: MMMMMMd mMMMMMN oMm` + :NM: MMMMMMd mMMMMMN +Mm- + -mMy. mmmmmmh dmmmmmh -hMh. + oNNs- :yMm/ + .+mMdo:` `:smMd/` + -ohNNmhsoo++osshmNNh+. + `./+syyhhyys+:`` diff --git a/src/logo/ascii/chapeau.txt b/src/logo/ascii/chapeau.txt new file mode 100644 index 0000000000..0fa328cfcb --- /dev/null +++ b/src/logo/ascii/chapeau.txt @@ -0,0 +1,18 @@ + .-/-. + ////////. + ////////${c2}y+${c1}//. + ////////${c2}mMN${c1}/////. + ////////${c2}mMN+${c1}////////. + ////////////////////////. + /////////+${c2}shhddhyo${c1}+////////. + ////////${c2}ymMNmdhhdmNNdo${c1}///////. +///////+${c2}mMms${c1}////////${c2}hNMh${c1}///////. +///////${c2}NMm+${c1}//////////${c2}sMMh${c1}/////// +//////${c2}oMMNmmmmmmmmmmmmMMm${c1}/////// +//////${c2}+MMmssssssssssssss+${c1}/////// +`//////${c2}yMMy${c1}//////////////////// + `//////${c2}smMNhso++oydNm${c1}//////// + `///////${c2}ohmNMMMNNdy+${c1}/////// + `//////////${c2}++${c1}////////// + `////////////////. + -////////- diff --git a/src/logo/ascii/chonkysealos.txt b/src/logo/ascii/chonkysealos.txt new file mode 100644 index 0000000000..5d9096bce6 --- /dev/null +++ b/src/logo/ascii/chonkysealos.txt @@ -0,0 +1,21 @@ + .-/-. + .:-=++****++=-:. + .:=+*##%%%%%%%%%%##*+=:. + :=*#%%%%%%%%%%%%%%%%%%%%#*=: + :=*#%%%%%%%%%%%%%%%%%%%%%%%%#*=. + -+#%%%%%%%%%%%%%%%%%%%%%%%%%%%%#+- + =+#%%%%@@@@@@@%%%%%%%@@@@@@@%%%%%#+= + =+#@%%%%*+=-==*%%%%%%%#+====*%%%%%@#+= +:+*%%%%@* +@%%%@# -@%%%%%*+: +=+#%%%%%%#+====*###%%##*=--=+*%%%%%%%#+= ++*%%%%%%%@@##%%%%*=::=#%%%##%@%%%%%%%%*+ ++*%%%%%%%@**@%%%%%@==@%%%%%@+#%%%%%%%%*+ +=+#%%%%%%@#*@%%%%%%**%%%%%@%+%%%%%%%%#+= +:+*%%%%%%%@#*####**###*####*%@%%%%%%%*+: + =+#@%%%%%%@%%%%%%%@@%%%%%%%%%%%%%%@#+= + =+#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#+= + -+#%%%%%%%%%%%%%%%%%%%%%%%%%%%%*+- + .=*#%%%%%%%%%%%%%%%%%%%%%%%%#*=. + :=*##%%%%%%%%%%%%%%%%%%##*=: + .:=+*##%%%%%%%%%%##*+=:. + .:-=++****++=-:. diff --git a/src/logo/ascii/chrom.txt b/src/logo/ascii/chrom.txt new file mode 100644 index 0000000000..951bf1906f --- /dev/null +++ b/src/logo/ascii/chrom.txt @@ -0,0 +1,18 @@ +${c2} .,:loool:,. + .,coooooooooooooc,. + .,lllllllllllllllllllll,. + ;ccccccccccccccccccccccccc; +${c1} '${c2}ccccccccccccccccccccccccccccc. +${c1} ,oo${c2}c::::::::okO${c5}000${c3}0OOkkkkkkkkkkk: +${c1}.ooool${c2};;;;:x${c5}K0${c4}kxxxxxk${c5}0X${c3}K0000000000. +${c1}:oooool${c2};,;O${c5}K${c4}ddddddddddd${c5}KX${c3}000000000d +${c1}lllllool${c2};l${c5}N${c4}dllllllllllld${c5}N${c3}K000000000 +${c1}lllllllll${c2}o${c5}M${c4}dccccccccccco${c5}W${c3}K000000000 +${c1};cllllllllX${c5}X${c4}c:::::::::c${c5}0X${c3}000000000d +${c1}.ccccllllllO${c5}Nk${c4}c;,,,;cx${c5}KK${c3}0000000000. +${c1} .cccccclllllxOO${c5}OOO${c1}Okx${c3}O0000000000; +${c1} .:ccccccccllllllllo${c3}O0000000OOO, +${c1} ,:ccccccccclllcd${c3}0000OOOOOOl. +${c1} '::ccccccccc${c3}dOOOOOOOkx:. +${c1} ..,::cccc${c3}xOOOkkko;. +${c1} ..,:${c3}dOkxl:. diff --git a/src/logo/ascii/cleanjaro.txt b/src/logo/ascii/cleanjaro.txt new file mode 100644 index 0000000000..8c2dbe94ff --- /dev/null +++ b/src/logo/ascii/cleanjaro.txt @@ -0,0 +1,12 @@ +███████▌ ████████████████ +███████▌ ████████████████ +███████▌ ████████████████ +███████▌ +███████▌ +███████▌ +███████▌ +███████▌ +█████████████████████████ +█████████████████████████ +█████████████████████████ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ diff --git a/src/logo/ascii/cleanjaro_small.txt b/src/logo/ascii/cleanjaro_small.txt new file mode 100644 index 0000000000..9de37e3a76 --- /dev/null +++ b/src/logo/ascii/cleanjaro_small.txt @@ -0,0 +1,7 @@ +█████ ██████████ +█████ ██████████ +█████ +█████ +█████ +████████████████ +████████████████ diff --git a/src/logo/ascii/clear_linux.txt b/src/logo/ascii/clear_linux.txt new file mode 100644 index 0000000000..7d427ed3d4 --- /dev/null +++ b/src/logo/ascii/clear_linux.txt @@ -0,0 +1,20 @@ + BBB + BBBBBBBBB + BBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBBBBBB + BBBBBBBBBBB BBB + BBBBBBBB${c2}YYYYY +${c1} BBBBBBBB${c2}YYYYYY +${c1} BBBBBBBB${c2}YYYYYYY +${c1} BBBBBBBBB${c2}YYYYY${c3}W +${c4} GG${c1}BBBBBBBY${c2}YYYY${c3}WWW +${c4} GGG${c1}BBBBBBB${c2}YY${c3}WWWWWWWW +${c4} GGGGGG${c1}BBBBBB${c3}WWWWWWWW +${c4} GGGGGGGG${c1}BBBB${c3}WWWWWWWW +${c4}GGGGGGGGGGG${c1}BBB${c3}WWWWWWW +${c4}GGGGGGGGGGGGG${c1}B${c3}WWWWWW +${c4}GGGGGGGG${c3}WWWWWWWWWWW +${c4}GG${c3}WWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWW + WWWWWWWWWW + WWW diff --git a/src/logo/ascii/clearos.txt b/src/logo/ascii/clearos.txt new file mode 100644 index 0000000000..7b5252da1a --- /dev/null +++ b/src/logo/ascii/clearos.txt @@ -0,0 +1,20 @@ + `.--::::::--.` + .-:////////////////:-. + `-////////////////////////-` + -////////////////////////////- + `//////////////-..-//////////////` + ./////////////: ://///////////. + `//////:..-////: :////-..-//////` + ://////` -///:.``.:///-` ://///: +`///////:. -////////-` `:///////` +.//:--////:. -////-` `:////--://. +./: .////:. --` `:////- :/. +`//-` .////:. `:////- `-//` + :///-` .////:. `:////- `-///: + `/////-` -///: :///- `-/////` + `//////- `///: :///` .//////` + `:////: `///: :///` -////:` + .://: `///: :///` -//:. + .:: `///: :///` -:. + `///: :///` + `... ...` diff --git a/src/logo/ascii/clover.txt b/src/logo/ascii/clover.txt new file mode 100644 index 0000000000..bf64adb49a --- /dev/null +++ b/src/logo/ascii/clover.txt @@ -0,0 +1,20 @@ + `omo``omo` + `oNMMMNNMMMNo` + `oNMMMMMMMMMMMMNo` + oNMMMMMMMMMMMMMMMMNo + `sNMMMMMMMMMMMMMMNs` + `omo` `sNMMMMMMMMMMNs` `omo` + `oNMMMNo` `sNMMMMMMNs` `oNMMMNo` + `oNMMMMMMMNo` `oNMMNs` `oNMMMMMMMNo` +oNMMMMMMMMMMMNo` `sy` `oNMMMMMMMMMMMNo +`sNMMMMMMMMMMMMNo.${c2}oNNs${c1}.oNMMMMMMMMMMMMNs` +`oNMMMMMMMMMMMMNs.${c2}oNNs${c1}.oNMMMMMMMMMMMMNo` +oNMMMMMMMMMMMNs` `sy` `oNMMMMMMMMMMMNo + `oNMMMMMMMNs` `oNMMNo` `oNMMMMMMMNs` + `oNMMMNs` `sNMMMMMMNs` `oNMMMNs` + `oNs` `sNMMMMMMMMMMNs` `oNs` + `sNMMMMMMMMMMMMMMNs` + +NMMMMMMMMMMMMMMMMNo + `oNMMMMMMMMMMMMNo` + `oNMMMNNMMMNs` + `omo``oNs` diff --git a/src/logo/ascii/cobalt.txt b/src/logo/ascii/cobalt.txt new file mode 100644 index 0000000000..6780a3880b --- /dev/null +++ b/src/logo/ascii/cobalt.txt @@ -0,0 +1,16 @@ +${c1} /// +${c1} ,////////////// +${c1} /////////////////////////////// +${c1} ///////////////${c5}***********${c1}////// + ////${c5}***********************${c1}///// + /////${c5}***********************${c1}//// + //////${c5},,,,,,,,,,,,,,,,,,,,,,${c1}/// + //////${c5},,,,,,,,,,,,,,,,,,,,,,,,,${c1}///// + /////${c5},,,,,,,,,,,,,,,,,,,,,,,,,,,,${c1}///// +${c4} *****${c3},,,,,,,,,,,,,,,,,,,,,,,,,,,,,${c4}***** + ******${c3},,,,,,,,,,,,,,,,,,,,,,,,,,,,${c4}***** + *******${c3},,,,,,,,,,,,,,,,,,,,,,,,,${c4}****** + *******${c3}......................${c4}******* + ******${c3}....${c4}*********************** + **************************** + ***** diff --git a/src/logo/ascii/condres.txt b/src/logo/ascii/condres.txt new file mode 100644 index 0000000000..c14c19eee3 --- /dev/null +++ b/src/logo/ascii/condres.txt @@ -0,0 +1,17 @@ +${c1}syyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy+${c3}.+. +${c1}`oyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy+${c3}:++. +${c2}/o${c1}+oyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy/${c3}oo++. +${c2}/y+${c1}syyyyyyyyyyyyyyyyyyyyyyyyyyyyy${c3}+ooo++. +${c2}/hy+${c1}oyyyhhhhhhhhhhhhhhyyyyyyyyy${c3}+oo+++++. +${c2}/hhh+${c1}shhhhhdddddhhhhhhhyyyyyyy${c3}+oo++++++. +${c2}/hhdd+${c1}oddddddddddddhhhhhyyyys${c3}+oo+++++++. +${c2}/hhddd+${c1}odmmmdddddddhhhhyyyy${c3}+ooo++++++++. +${c2}/hhdddmo${c1}odmmmdddddhhhhhyyy${c3}+oooo++++++++. +${c2}/hdddmmms${c1}/dmdddddhhhhyyys${c3}+oooo+++++++++. +${c2}/hddddmmmy${c1}/hdddhhhhyyyyo${c3}+oooo++++++++++: +${c2}/hhdddmmmmy${c1}:yhhhhyyyyy+${c3}+oooo+++++++++++: +${c2}/hhddddddddy${c1}-syyyyyys+${c3}ooooo++++++++++++: +${c2}/hhhddddddddy${c1}-+yyyy+${c3}/ooooo+++++++++++++: +${c2}/hhhhhdddddhhy${c1}./yo:${c3}+oooooo+++++++++++++/ +${c2}/hhhhhhhhhhhhhy${c1}:-.${c3}+sooooo+++++++++++///: +${c2}:sssssssssssso++${c1}${c3}`:/:--------.```````` diff --git a/src/logo/ascii/container_linux.txt b/src/logo/ascii/container_linux.txt new file mode 100644 index 0000000000..e1f81b9d13 --- /dev/null +++ b/src/logo/ascii/container_linux.txt @@ -0,0 +1,20 @@ + ..... + .';:cccccccc:;'. + ':ccccclc${c3}lllllllll${c1}cc:. + .;cccccccc${c3}lllllllllllllll${c1}c, + ;clllccccc${c3}llllllllllllllllll${c1}c, + .cllclccccc${c3}lllll${c2}lll${c3}llllllllllll${c1}c: + ccclclcccc${c3}cllll${c2}kWMMNKk${c3}llllllllll${c1}c: + :ccclclcccc${c3}llll${c2}oWMMMMMMWO${c3}lllllllll${c1}c, +.ccllllllccc${c3}clll${c2}OMMMMMMMMM0${c3}lllllllll${c1}c +.lllllclcccc${c3}llll${c2}KMMMMMMMMMMo${c3}llllllll${c1}c. +.lllllllcccc${c3}clll${c2}KMMMMMMMMN0${c3}lllllllll${c1}c. +.cclllllcccc${c3}lllld${c2}xkkxxdo${c3}llllllllllc${c1}lc + :cccllllllcccc${c3}lllccllllcclccc${c1}cccccc; + .ccclllllllcccccccc${c3}lll${c1}ccccclccccccc + .cllllllllllclcccclccclccllllcllc + :cllllllllccclcllllllllllllcc; + .cccccccccccccclcccccccccc:. + .;cccclccccccllllllccc,. + .';ccccclllccc:;.. + ..... diff --git a/src/logo/ascii/crux.txt b/src/logo/ascii/crux.txt new file mode 100644 index 0000000000..142bcbc50e --- /dev/null +++ b/src/logo/ascii/crux.txt @@ -0,0 +1,18 @@ + $1odddd + oddxkkkxxdoo + ddcoddxxxdoool + xdclodod olol + xoc xdd olol + xdc $2k00$1Okdlol + xxd$2kOKKKOkd$1ldd + xdco$2xOkdlo$1dldd + ddc:cl$2lll$1oooodo + odxxdd$3xkO000kx$1ooxdo + oxddx$30NMMMMMMWW0o$1dkkxo + oooxd$30WMMMMMMMMMW0o$1dxkx +docldkXW$3MMMMMMMWWN$1Odolco +xx$2dx$1kxxOKN$3WMMWN$10xdoxo::c +$2xOkkO$10oo$3odOW$2WW$1XkdodOxc:l +$2dkkkxkkk$3OKX$2NNNX0Oxx$1xc:cd + $2odxxdx$3xllo$2dddooxx$1dc:ldo + $2lodd$1dolccc$2ccox$1xoloo diff --git a/src/logo/ascii/crux_small.txt b/src/logo/ascii/crux_small.txt new file mode 100644 index 0000000000..d332133db0 --- /dev/null +++ b/src/logo/ascii/crux_small.txt @@ -0,0 +1,7 @@ + ___ + (${c3}.· ${c1}| + (${c2}<> ${c1}| + / ${c3}__ ${c1}\\ + ( ${c3}/ \\ ${c1}/| +${c2}_${c1}/\\ ${c3}__)${c1}/${c2}_${c1}) +${c2}\/${c1}-____${c2}\/ diff --git a/src/logo/ascii/crystal.txt b/src/logo/ascii/crystal.txt new file mode 100644 index 0000000000..85cfd25239 --- /dev/null +++ b/src/logo/ascii/crystal.txt @@ -0,0 +1,20 @@ + mysssym + mysssym + mysssym + mysssym + mysssyd + mysssyd N + mysssyd mysym + mysssyd dysssym + mysssyd dysssym +mysssyd dysssym +mysssyd dysssym + mysssyd dysssym + mysssyd dysssym + mysym dysssym + N dysssym + dysssym + dysssym + dysssym + dysssym + dysssym \ No newline at end of file diff --git a/src/logo/ascii/cucumber.txt b/src/logo/ascii/cucumber.txt new file mode 100644 index 0000000000..24bd1a834b --- /dev/null +++ b/src/logo/ascii/cucumber.txt @@ -0,0 +1,20 @@ + `.-://++++++//:-.` + `:/+//${c2}::--------${c1}:://+/:` + -++/:${c2}----..........----${c1}:/++- + .++:${c2}---...........-......---${c1}:++. + /+:${c2}---....-::/:/--//:::-....---${c1}:+/ + `++:${c2}--.....:---::/--/::---:.....--${c1}:++` + /+:${c2}--.....--.--::::-/::--.--.....--${c1}:+/ +-o:${c2}--.......-:::://--/:::::-.......--${c1}:o- +/+:${c2}--...-:-::---:::..:::---:--:-...--${c1}:+/ +o/:${c2}-...-:.:.-/:::......::/:.--.:-...-${c1}:/o +o/${c2}--...::-:/::/:-......-::::::-/-...-${c1}:/o +/+:${c2}--..-/:/:::--:::..:::--::////-..--${c1}:+/ +-o:${c2}--...----::/:::/--/:::::-----...--${c1}:o- + /+:${c2}--....://:::.:/--/:.::://:....--${c1}:+/ + `++:${c2}--...-:::.--.:..:.--.:/:-...--${c1}:++` + /+:${c2}---....----:-..-:----....---${c1}:+/ + .++:${c2}---..................---${c1}:++. + -/+/:${c2}----..........----${c1}:/+/- + `:/+//${c2}::--------:::${c1}/+/:` + `.-://++++++//:-.` diff --git a/src/logo/ascii/cutefishos.txt b/src/logo/ascii/cutefishos.txt new file mode 100644 index 0000000000..3cf5a3e4ea --- /dev/null +++ b/src/logo/ascii/cutefishos.txt @@ -0,0 +1,9 @@ + ___ww___ +_ _wwMMM@M^^^^MMMMww_ +M0w_ _wMMM~~ ~~MMm_ + ~MMy _ww0M~ ~MMy + ~MMMM~ o "MM +${c3} jw0M~~MMMw_ _wMM' +wMM~ ~~MMmw__ __w0M~ +~ ~~MM0MmwwwwwwwwwMMM~ + ~~~~^^~~~ diff --git a/src/logo/ascii/cuteos.txt b/src/logo/ascii/cuteos.txt new file mode 100644 index 0000000000..482791c9d5 --- /dev/null +++ b/src/logo/ascii/cuteos.txt @@ -0,0 +1,14 @@ + ${c3}1ua${c2} + ${c3}MMM1ua${c2} + ${c1}MM${c2}EE ${c3} MMMMM1uazE${c2} +${c1}MM ${c2}EEEE ${c3}M1MM1uazzEn ${c2}EEEE MME + EEEEE ${c3}MMM uazEno ${c2}EEEE + EEEEE${c1}MMMMMMEno~; ${c2}EE E${c2} + EE ${c1}MMMMMMMM~;;E ${c2}MMMMM M ${c2} + E ${c1}MMMMMMMMM ${c2} E E ${c2} + ${c1}MMMMMMMMMMM + ${c1}MMMMMMMMM ${c2}EE ${c1} + MM1MMMM ${c2}EEE ${c1} + MMMMM + MMM + M diff --git a/src/logo/ascii/cyberos.txt b/src/logo/ascii/cyberos.txt new file mode 100644 index 0000000000..ebdb1c6f7b --- /dev/null +++ b/src/logo/ascii/cyberos.txt @@ -0,0 +1,15 @@ +${c3} !M$EEEEEEEEEEEP + .MMMMM000000Nr. + ${c3}&MMMMMM${c2}MMMMMMMMMMMMM9 + ${c3}~MMM${c1}MMMM${c2}MMMMMMMMMMMMC + ${c1}" ${c3}M${c1}MMMMMMM${c2}MMMMMMMMMMs + ${c1}iM${c2}MMM&&${c1}MMMMMMMM${c2}MMMMMMMM\\ + ${c1}BMMM${c2}MMMMM${c1}MMMMMMM${c2}MMMMMM${c3}" + ${c1}9MMMMM${c2}MMMMMMM${c1}MMMM${c2}MMMM${c3}MMMf- + ${c2}sMMMMMMMM${c1}MM${c2}M${c3}MMMMMMMMM3_ + ${c2}+ffffffff${c1}P${c3}MMMMMMMMMMMM0 + ${c2}CMMMMMMMMMMM + }MMMMMMMMM + ~MMMMMMM + "RMMMM + .PMB diff --git a/src/logo/ascii/dahlia.txt b/src/logo/ascii/dahlia.txt new file mode 100644 index 0000000000..d3d0588035 --- /dev/null +++ b/src/logo/ascii/dahlia.txt @@ -0,0 +1,17 @@ + .#. + *%@@@%* + .,,,,,(&@@@@@@@&/,,,,,. + ,#@@@@@@@@@@@@@@@@@@@@@#. + ,#@@@@@@@&#///#&@@@@@@@#. + ,/%&@@@@@%/, .,(%@@@@@&#/. + *#&@@@@@@#,. .*#@@@@@@&#, + .&@@@@@@@@@( .(@@@@@@@@@&&. +#@@@@@@@@@@( )@@@@@@@@@@@# + °@@@@@@@@@@( .(@@@@@@@@@@@° + *%@@@@@@@(. ,#@@@@@@@%* + ,(&@@@@@@%*. ./%@@@@@@%(, + ,#@@@@@@@&(***(&@@@@@@@#. + ,#@@@@@@@@@@@@@@@@@@@@@#. + ,*****#&@@@@@@@&(*****, + ,/%@@@%/. + ,#, diff --git a/src/logo/ascii/darkos.txt b/src/logo/ascii/darkos.txt new file mode 100644 index 0000000000..8ff29fab77 --- /dev/null +++ b/src/logo/ascii/darkos.txt @@ -0,0 +1,20 @@ +${c3}⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c1}⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣶⠋⡆⢹⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c5}⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡆⢀⣤⢛⠛⣠⣿⠀⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c6}⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣶⣿⠟⣡⠊⣠⣾⣿⠃⣠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c2}⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣯⣿⠀⠊⣤⣿⣿⣿⠃⣴⣧⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c1}⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣶⣿⣿⡟⣠⣶⣿⣿⣿⢋⣤⠿⠛⠉⢁⣭⣽⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c4} ⠀⠀⠀⠀⠀⠀ ⠀⣠⠖⡭⢉⣿⣯⣿⣯⣿⣿⣿⣟⣧⠛⢉⣤⣶⣾⣿⣿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c5}⠀⠀⠀⠀⠀⠀⠀⠀⣴⣫⠓⢱⣯⣿⢿⠋⠛⢛⠟⠯⠶⢟⣿⣯⣿⣿⣿⣿⣿⣿⣦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c2}⠀⠀⠀⠀⠀⠀⢀⡮⢁⣴⣿⣿⣿⠖⣠⠐⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠛⠛⠛⢿⣶⣄⠀⠀⠀⠀⠀⠀⠀ +${c3}⠀⠀⠀⠀⢀⣤⣷⣿⣿⠿⢛⣭⠒⠉⠀⠀⠀⣀⣀⣄⣤⣤⣴⣶⣶⣶⣿⣿⣿⣿⣿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀ +${c1}⠀⢀⣶⠏⠟⠝⠉⢀⣤⣿⣿⣶⣾⣿⣿⣿⣿⣿⣿⣟⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c6}⢴⣯⣤⣶⣿⣿⣿⣿⣿⡿⣿⣯⠉⠉⠉⠉⠀⠀⠀⠈⣿⡀⣟⣿⣿⢿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c5}⠀⠀⠀⠉⠛⣿⣧⠀⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠃⣿⣿⣯⣿⣦⡀⠀⠉⠻⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c3}⠀⠀⠀⠀⠀⠀⠉⢿⣮⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⠀⣯⠉⠉⠛⢿⣿⣷⣄⠀⠈⢻⣆⠀⠀⠀⠀⠀⠀⠀⠀ +${c2}⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠢⠀⠀⠀⠀⠀⠀⠀⢀⢡⠃⣾⣿⣿⣦⠀⠀⠀⠙⢿⣿⣤⠀⠙⣄⠀⠀⠀⠀⠀⠀⠀ +${c6}⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢋⡟⢠⣿⣿⣿⠋⢿⣄⠀⠀⠀⠈⡄⠙⣶⣈⡄⠀⠀⠀⠀⠀⠀ +${c1}⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠚⢲⣿⠀⣾⣿⣿⠁⠀⠀⠉⢷⡀⠀⠀⣇⠀⠀⠈⠻⡀⠀⠀⠀⠀⠀ +${c4}⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢢⣀⣿⡏⠀⣿⡿⠀⠀⠀⠀⠀⠀⠙⣦⠀⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c3}⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠿⣧⣾⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣮⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +${c5}⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠛⠀⠀⠀⠀⠀⠀ diff --git a/src/logo/ascii/debian.txt b/src/logo/ascii/debian.txt new file mode 100644 index 0000000000..6c88f55c8f --- /dev/null +++ b/src/logo/ascii/debian.txt @@ -0,0 +1,17 @@ + $2_,met$$$$$$$$$$gg. + ,g$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$P. + ,g$$$$P" """Y$$$$.". + ,$$$$P' `$$$$$$. +',$$$$P ,ggs. `$$$$b: +`d$$$$' ,$P"' $1.$2 $$$$$$ + $$$$P d$' $1,$2 $$$$$$P + $$$$: $$. $1-$2 ,d$$$$' + $$$$; Y$b._ _,d$P' + Y$$$$. $1`.$2`"Y$$$$$$$$P"' + `$$$$b $1"-.__ + $2`Y$$$$ + `Y$$$$. + `$$$$b. + `Y$$$$b. + `"Y$$b._ + `""" \ No newline at end of file diff --git a/src/logo/ascii/debian_small.txt b/src/logo/ascii/debian_small.txt new file mode 100644 index 0000000000..7db04d84bc --- /dev/null +++ b/src/logo/ascii/debian_small.txt @@ -0,0 +1,6 @@ + _____ + / __ \ +| / | +| \___- +-_ + --_ \ No newline at end of file diff --git a/src/logo/ascii/deepin.txt b/src/logo/ascii/deepin.txt new file mode 100644 index 0000000000..d79eaa42f5 --- /dev/null +++ b/src/logo/ascii/deepin.txt @@ -0,0 +1,18 @@ +$1 ............ + .';;;;;. .,;,. + .,;;;;;;;. ';;;;;;;. + .;::::::::' .,::;;,''''',. + ,'.:::::::: .;;'. '; + ;' 'cccccc, ,' :: '.. .: + ,, :ccccc. ;: .c, '' :. ,; +.l. cllll' ., .lc :; .l' l. +.c :lllc ;cl: .l' .ll. :' +.l 'looc. . ,o: 'oo' c, +.o. .:ool::coc' .ooo' o. + :: ..... .;dddo ;c + l:... .';lddddo. ,o + lxxxxxdoolllodxxxxxxxxxc :l + ,dxxxxxxxxxxxxxxxxxxl. 'o, + ,dkkkkkkkkkkkkko;. .;o; + .;okkkkkdl;. .,cl:. + .,:cccccccc:,. \ No newline at end of file diff --git a/src/logo/ascii/desaos.txt b/src/logo/ascii/desaos.txt new file mode 100644 index 0000000000..8259b116e3 --- /dev/null +++ b/src/logo/ascii/desaos.txt @@ -0,0 +1,16 @@ +███████████████████████ +███████████████████████ +███████████████████████ +███████████████████████ +████████ ███████ +████████ ███████ +████████ ███████ +████████ ███████ +████████ ███████ +████████ ███████ +████████ ███████ +██████████████████████████████ +██████████████████████████████ +████████████████████████ +████████████████████████ +████████████████████████ diff --git a/src/logo/ascii/devuan.txt b/src/logo/ascii/devuan.txt new file mode 100644 index 0000000000..2ecd8d7494 --- /dev/null +++ b/src/logo/ascii/devuan.txt @@ -0,0 +1,15 @@ + ..,,;;;::;,.. + `':ddd;:,. + `'dPPd:,. + `:b$$$$b`. + 'P$$$$$d` + .$$$$$$$$$` + ;$$$$$$$$$P + .:P$$$$$$$$$$$$` + .,:b$$$$$$$$$$$$$;' + .,:dP$$$$$$$$$$$$$$$$b:' + .,:;db$$$$$$$$$$$$$$$$$$$$Pd'` + ,db$$$$$$$$$$$$$$$$$$$$$$$$$$$$b:'` +:$$$$$$$$$$$$$$$$$$$$$$$$b:'` + `$$$$$$$$$bd:''` + `'''` diff --git a/src/logo/ascii/devuan_small.txt b/src/logo/ascii/devuan_small.txt new file mode 100644 index 0000000000..c56ceae8bd --- /dev/null +++ b/src/logo/ascii/devuan_small.txt @@ -0,0 +1,7 @@ + ..:::. + ..-==- + .+#: + =@@ + :+%@#: +.:=+#@@%*: +#@@@#=: diff --git a/src/logo/ascii/dietpi.txt b/src/logo/ascii/dietpi.txt new file mode 100644 index 0000000000..7e2b10d9bd --- /dev/null +++ b/src/logo/ascii/dietpi.txt @@ -0,0 +1,19 @@ + :=+******+- -+******+=: + =#-::-::::-=#:-#=-::::-::-#= + :%-::--==-::-%%-::-==--::-%: + +#-:::::=+++${c2}@@${c1}+++=-::::-#= + :#+-::::=%${c2}@@@@@${c1}=::::-+#: + =@%##%${c2}@@@@@@@@${c1}%##%@= +${c2} .#@@@@@@@@@@@@@@@@@@@@#. + %@@@@@@@@@@@@@@@@@@@@@@% + -@@@@@@@@@@@@@@@@@@@@@@@@: +.#@@@@@@@@@@%%%%%@@@@@@@@@@@#. +#@@@${c1}+-=*#%${c2}%%%%%%%%%${c1}%%#+--#${c2}@@@# +%@@%${c1}*. .:${c2}=*%%%%*${c1}=: .#${c2}@@@% +:%@@@${c1}#+=-:${c2}:-*%%%%+::${c1}:-=+%${c2}@@@%: + :@@@@%@%%%%@${c1}#${c2}#${c1}#${c2}%@%%%%@%@@@@. + +@@@@@@@@@${c1}%${c2}=*+${c1}%${c2}@%@@@@@@@@+ + #@@@@@@@@@@@@@@@@@@@@@@# + -#@@@@@@@@@@@@@@@@@@#- + -*%@@@@@@@@@@%*- + .+%@@@@%+. diff --git a/src/logo/ascii/dracos.txt b/src/logo/ascii/dracos.txt new file mode 100644 index 0000000000..e8d59dd023 --- /dev/null +++ b/src/logo/ascii/dracos.txt @@ -0,0 +1,13 @@ + `-:/- + -os: + -os/` + :sy+-` + `/yyyy+. + `+yyyyo- + `/yyyys: +`:osssoooo++- +yyyyyy/` + ./yyyyyyo yo`:syyyy+. + -oyyy+ +- :yyyyyo- + `:sy: `. `/yyyyys: + ./o/.` .oyyso+oo:` + :+oo+//::::///:-.` `.` diff --git a/src/logo/ascii/dragonfly.txt b/src/logo/ascii/dragonfly.txt new file mode 100644 index 0000000000..7ccc14bc3a --- /dev/null +++ b/src/logo/ascii/dragonfly.txt @@ -0,0 +1,15 @@ +${c2},--, ${c1}| ${c2},--, +${c2}| `-, ${c1},^, ${c2},-' | +${c2} `, `-, ${c3}(/ \) ${c2},-' ,' +${c2} `-, `-,${c1}/ \${c2},-' ,-' +${c2} `------${c1}( )${c2}------' +${c2} ,----------${c1}( )${c2}----------, +${c2} | _,-${c1}( )${c2}-,_ | +${c2} `-,__,-' ${c1}\ /${c2} `-,__,-' +${c1} | | + | | + | | + | | + | | + | | + `|' diff --git a/src/logo/ascii/dragonfly_old.txt b/src/logo/ascii/dragonfly_old.txt new file mode 100644 index 0000000000..66609ffb53 --- /dev/null +++ b/src/logo/ascii/dragonfly_old.txt @@ -0,0 +1,17 @@ + .-. + ${c3} ()${c1}I${c3}() + ${c1} "==.__:-:__.==" + "==.__/~|~\__.==" + "==._( Y )_.==" + ${c2}.-'~~""~=--...,__${c1}\/|\/${c2}__,...--=~""~~'-. +( ..=${c1}\\=${c1}/${c2}=.. ) + `'-. ,.-"`;${c1}/=\\${c2};"-.,_ .-'` + `~"-=-~` .-~` ${c1}|=|${c2} `~-. `~-=-"~` + .-~` /${c1}|=|${c2}\ `~-. + .~` / ${c1}|=|${c2} \ `~. + .-~` .' ${c1}|=|${c2} `. `~-. + (` _,.-="` ${c1} |=|${c2} `"=-.,_ `) + `~"~"` ${c1} |=|${c2} `"~"~` + ${c1} /=\\ + \\=/ + ^ diff --git a/src/logo/ascii/dragonfly_small.txt b/src/logo/ascii/dragonfly_small.txt new file mode 100644 index 0000000000..a20c040c88 --- /dev/null +++ b/src/logo/ascii/dragonfly_small.txt @@ -0,0 +1,7 @@ +${c2} ,${c1}_${c2}, +('-_${c1}|${c2}_-') + >--${c1}|${c2}--< +(_-'${c1}|${c2}'-_) + ${c1}| + | + | diff --git a/src/logo/ascii/drauger.txt b/src/logo/ascii/drauger.txt new file mode 100644 index 0000000000..72ae4ffe5a --- /dev/null +++ b/src/logo/ascii/drauger.txt @@ -0,0 +1,16 @@ + -``- + `:+``+:` + `/++``++/. + .++/. ./++. + :++/` `/++: + `/++: :++/` + ./+/- -/+/. + -++/. ./++- + :++:` `:++: + `/++- -++/` + ./++. ./+/. + -++/` `/++- + :++:` `:++: + `/++- -++/` +.:-.`..............................`.-:. +`.-/++++++++++++++++++++++++++++++++/-.` diff --git a/src/logo/ascii/droidian.txt b/src/logo/ascii/droidian.txt new file mode 100644 index 0000000000..bc1eace631 --- /dev/null +++ b/src/logo/ascii/droidian.txt @@ -0,0 +1,15 @@ +${c2} _,met$$$$$$$$$$gg. + ,g$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$P. + ,$$$$P' `$$$$$$. +',$$$$P ,ggs. `$$$$b: +`d$$$$' ,$$P"' ${c1}.${c2} $$$$$$ + $$$$P d$$' ${c1},${c2} $$$$P + $$$$: $$$$. ${c1}-${c2} ,d$$$$' + $$$$; Y$$b._ _,d$$P' + Y$$$$. ${c1}`.${c2}`"Y$$$$$$$$P"' +${c2} `$$$$b ${c1}"-.__ +${c2} `Y$$$$ + `Y$$$$. + `$$$$b. + `Y$$$$b. + `"Y$$b._ diff --git a/src/logo/ascii/elementary.txt b/src/logo/ascii/elementary.txt new file mode 100644 index 0000000000..e347f52ee6 --- /dev/null +++ b/src/logo/ascii/elementary.txt @@ -0,0 +1,17 @@ + eeeeeeeeeeeeeeeee + eeeeeeeeeeeeeeeeeeeeeee + eeeee eeeeeeeeeeee eeeee + eeee eeeee eee eeee + eeee eeee eee eeee +eee eee eee eee +eee eee eee eee +ee eee eeee eeee +ee eee eeeee eeeeee +ee eee eeeee eeeee ee +eee eeee eeeeee eeeee eee +eee eeeeeeeeee eeeeee eee + eeeeeeeeeeeeeeeeeeeeeeee eeeee + eeeeeeee eeeeeeeeeeee eeee + eeeee eeeee + eeeeeee eeeeeee + eeeeeeeeeeeeeeeee diff --git a/src/logo/ascii/elementary_small.txt b/src/logo/ascii/elementary_small.txt new file mode 100644 index 0000000000..1610313300 --- /dev/null +++ b/src/logo/ascii/elementary_small.txt @@ -0,0 +1,6 @@ + _______ + / ____ \\ +/ | / /\\ +|__\\ / / | +\\ /__/ / + \\_______/ diff --git a/src/logo/ascii/elive.txt b/src/logo/ascii/elive.txt new file mode 100644 index 0000000000..4727cd8638 --- /dev/null +++ b/src/logo/ascii/elive.txt @@ -0,0 +1,17 @@ + *@${c2},,&(%%%..%*. + ${c1}(@${c2}&%/##############((/${c1}*, + ${c2}@${c1}@&${c2}#########${c1}*..../${c2}########%${c1}*.. + ${c2}@${c1}&${c2}#%%%%%. ${c3},.${c1},${c2}%%%%%%. + /%${c2}(%%%%. ${c1}(${c2}%%%%#. + /${c1}*${c2}%%##,. .,%%###, + ,####. ,${c1}*${c2}#%${c1}#${c3}/,(/ ${c2}/${c1}#${c2}###, +((###/ ,,##########${c1}(${c3}/(# ${c2}%####, +%#(((${c1}. .${c1}./${c2}((((((((((((((${c1}(${c2}#/${c3}*.. ${c3}*.${c2}(((${c1}/ +${c2}%#///${c1}. ${c3}***${c2}.*///////////// +${c3}#${c2}#////* ${c3}***${c2}.*/////. + ${c3}(${c2}(***** ${c3}*** + ${c2},*****.. + ..${c1}*${c2}*****.. *${c1}%${c2}/****. + .,,*******,${c3},,../##(${c2}%&${c1}&${c2}#******${c1},${c2}. + ,*${c1},${c2},,,,,,,,,,,,,,,,,,,${c1},${c2}.. + *//${c1}/,,${c2},,,,,,,${c1},..${c2} diff --git a/src/logo/ascii/encryptos.txt b/src/logo/ascii/encryptos.txt new file mode 100644 index 0000000000..4f86a291c5 --- /dev/null +++ b/src/logo/ascii/encryptos.txt @@ -0,0 +1,13 @@ + ******* + *** **. + ** ** + ** ** + + ***************** +,,,,,,,,,,,,,,,,*** +,,,,,,, ,,,,,,, +,,,,,,, ,,,,,,, +,,,,,,, ,,,,,,, +,,,,,,, ,,,,,,, +,,,,,,,,,,,,,,,,,,, + ,,,,,,,,,,,,. diff --git a/src/logo/ascii/endeavour.txt b/src/logo/ascii/endeavour.txt new file mode 100644 index 0000000000..2bdf27dd91 --- /dev/null +++ b/src/logo/ascii/endeavour.txt @@ -0,0 +1,15 @@ + $2./$1o$3. + $2./$1sssso$3- + $2`:$1osssssss+$3- + $2`:+$1sssssssssso$3/. + $2`-/o$1ssssssssssssso$3/. + $2`-/+$1sssssssssssssssso$3+:` + $2`-:/+$1sssssssssssssssssso$3+/. + $2`.://o$1sssssssssssssssssssso$3++- + $2.://+$1ssssssssssssssssssssssso$3++: + $2.:///o$1ssssssssssssssssssssssssso$3++: + $2`:////$1ssssssssssssssssssssssssssso$3+++. +$2`-////+$1ssssssssssssssssssssssssssso$3++++- + $2`..-+$1oosssssssssssssssssssssssso$3+++++/` + $3./++++++++++++++++++++++++++++++/:. + `:::::::::::::::::::::::::------`` \ No newline at end of file diff --git a/src/logo/ascii/endless.txt b/src/logo/ascii/endless.txt new file mode 100644 index 0000000000..7dcf052ec3 --- /dev/null +++ b/src/logo/ascii/endless.txt @@ -0,0 +1,20 @@ + `:+yhmNMMMMNmhy+:` + -odMMNhso//////oshNMMdo- + /dMMh+. .+hMMd/ + /mMNo` `oNMm: + `yMMo` `oMMy` + `dMN- -NMd` + hMN. .NMh +/MM/ -os` /MM/ +dMm `smNmmhs/- `:sNMd+ `` mMd +MMy oMd--:+yMMMMMNo.:ohmMMMNy` yMM +MMy -NNyyhmMNh+oNMMMMMy:. dMo yMM +dMm `/++/-``/yNNh+/sdNMNddMm- mMd +/MM/ `dNy: `-::- /MM/ + hMN. .NMh + `dMN- -NMd` + `yMMo` `oMMy` + /mMNo` `oNMm/ + /dMMh+. .+hMMd/ + -odMMNhso//////oshNMMdo- + `:+yhmNMMMMNmhy+:` diff --git a/src/logo/ascii/enso.txt b/src/logo/ascii/enso.txt new file mode 100644 index 0000000000..5177215b09 --- /dev/null +++ b/src/logo/ascii/enso.txt @@ -0,0 +1,19 @@ + .:--==--:. + :=*#############*+-. + .+##################*##*: + .*##########+==-==++*####*##- + =########=: .-+**#***. + *#######- ++*#**. + +######+ -*+#** + :######* .*+**= + *######: --#*# + ####### +++#. + #######. ++=*. + *######+ .-+*+ + :#######- -:*+: + =#######*. :.*+- + +########*- :*=- + =###########+=: =+=: + .+#############. .-==: + .=###########= ..:--:. + .-+######+ diff --git a/src/logo/ascii/eurolinux.txt b/src/logo/ascii/eurolinux.txt new file mode 100644 index 0000000000..b379eba1c3 --- /dev/null +++ b/src/logo/ascii/eurolinux.txt @@ -0,0 +1,18 @@ + __ + -wwwWWWWWWWWWwww- + -WWWWWWWWWWWWWWWWWWw- + \WWWWWWWWWWWWWWWWWWW- + _Ww `WWWWWWWWWWWWWWWWWWWw + -W${c2}E${c1}Www -WWWWWWWWW- +_WW${c2}U${c1}WWWW- _WWWWWWWW +_WW${c2}R${c1}WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW- +wWW${c2}O${c1}WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWW${c2}L${c1}WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWw +WWW${c2}I${c1}WWWWWWWWWWWWWWWWWWWWWWWWWWWWww- +wWW${c2}N${c1}WWWWw + WW${c2}U${c1}WWWWWWw + wW${c2}X${c1}WWWWWWWWww + wWWWWWWWWWWWWWWWw + wWWWWWWWWWWWWWWWw + WWWWWWWWWWWWWw + wWWWWWWWw diff --git a/src/logo/ascii/evolutionos.txt b/src/logo/ascii/evolutionos.txt new file mode 100644 index 0000000000..7a6622d4a9 --- /dev/null +++ b/src/logo/ascii/evolutionos.txt @@ -0,0 +1,18 @@ + dddddddddddddddddddddddd +.dddd''''''''''''''''''''''dddd. +dd: dddddddddddddddddddd; dd: +dd: ldl:'''''''''''''''' dd: +dd: ldl: dd: +dd: ldl: dd: +dd: ldl: dd: +dd: ldl: dd: +dd: ldl: ddddddd; ddddd; dd: +dd: ldl: ''''''' ''''' dd: +dd: ldl: dd: +dd: ldl: dd: +dd: ldl: dd: +dd: ldl: dd: +dd: ldl: ddddddddddddddd; dd: +dddd:.''' ''''''''''''''' dddd: + dddddddddddddddddddddddddd;;' + ''''''''''''''''''''''''' diff --git a/src/logo/ascii/exherbo.txt b/src/logo/ascii/exherbo.txt new file mode 100644 index 0000000000..0d7ed1bd42 --- /dev/null +++ b/src/logo/ascii/exherbo.txt @@ -0,0 +1,22 @@ +$2 , +OXo. +NXdX0: .cok0KXNNXXK0ko:. +KX '0XdKMMK;.xMMMk, .0MMMMMXx; ... +'NO..xWkMMx kMMM cMMMMMX,NMWOxOXd. + cNMk NK .oXM. OMMMMO. 0MMNo kW. + lMc o: ., .oKNk; ;NMMWlxW' + ;Mc .. .,,' .0M$1g;$2WMN'dWMMMMMMO + XX ,WMMMMW. cM$1cfli$2WMKlo. .kMk +.Mo .WM$1GD$2MW. XM$1WO0$2MMk oMl +,M: ,XMMWx::,''oOK0x; NM. +'Ml ,kNKOxxxxxkkO0XXKOd:. oMk + NK .0Nxc$3:::::::::::::::$2fkKNk, .MW + ,Mo .NXc$3::$2qXWXb$3::::::::::$2oo$3::$2lNK. .MW + ;Wo oMd$3:::$2oNMNP$3::::::::$2oWMMMx$3:$2c0M; lMO + 'NO;W0c$3:::::::::::::::$2dMMMMO$3::$2lMk .WM' + xWONXdc$3::::::::::::::$2oOOo$3::$2lXN. ,WMd + 'KWWNXXK0Okxxo,$3:::::::$2,lkKNo xMMO + :XMNxl,';:lodxkOO000Oxc. .oWMMo + 'dXMMXkl;,. .,o0MMNo' + ':d0XWMMMMWNNNNMMMNOl' + ':okKXWNKkl' diff --git a/src/logo/ascii/exodia_predator.txt b/src/logo/ascii/exodia_predator.txt new file mode 100644 index 0000000000..67456ce2a7 --- /dev/null +++ b/src/logo/ascii/exodia_predator.txt @@ -0,0 +1,24 @@ +- : ++: :+ +++. .++ ++++ : . +++ ++++= .+ + =+++ +++++- ++ += -++++ +++++++- -++ ++- -++++++ +++++++++: .+++ +++. :++++++++ +++++++++++: ++++ ++++ :++++++++++ ++++++++++++==++++ ++++=++++++=+++++ ++++++.:++++++++++ ++++++++++:.+++++ ++++++. .+++++++++ +++++++++. .+++++ ++++++: ++++++++ ++++++++ :+++++ +++++++- =+++++++ +++++++= -++++++ + :+++++= =+++++++ +++++++= =+++++: + :+++= =+++++++ +++++++= =+++: + -+= =+++++++ +++++++= ++- + : =++++++- -++++++= : + =++++- -++++= + =++= =++= + =++ ++= + =+. .+= + =- -= + : : diff --git a/src/logo/ascii/fedora.txt b/src/logo/ascii/fedora.txt new file mode 100644 index 0000000000..f0cfe76a01 --- /dev/null +++ b/src/logo/ascii/fedora.txt @@ -0,0 +1,19 @@ + .',;::::;,'. + .';:cccccccccccc:;,. + .;cccccccccccccccccccccc;. + .:cccccccccccccccccccccccccc:. + .;ccccccccccccc;$2.:dddl:.$1;ccccccc;. + .:ccccccccccccc;$2OWMKOOXMWd$1;ccccccc:. +.:ccccccccccccc;$2KMMc$1;cc;$2xMMc$1;ccccccc:. +,cccccccccccccc;$2MMM.$1;cc;$2;WW:$1;cccccccc, +:cccccccccccccc;$2MMM.$1;cccccccccccccccc: +:ccccccc;$2oxOOOo$1;$2MMM000k.$1;cccccccccccc: +cccccc;$20MMKxdd:$1;$2MMMkddc.$1;cccccccccccc; +ccccc;$2XMO'$1;cccc;$2MMM.$1;cccccccccccccccc' +ccccc;$2MMo$1;ccccc;$2MMW.$1;ccccccccccccccc; +ccccc;$20MNc.$1ccc$2.xMMd$1;ccccccccccccccc; +cccccc;$2dNMWXXXWM0:$1;cccccccccccccc:, +cccccccc;$2.:odl:.$1;cccccccccccccc:,. +ccccccccccccccccccccccccccccc:'. +:ccccccccccccccccccccccc:;,.. + ':cccccccccccccccc::;,. \ No newline at end of file diff --git a/src/logo/ascii/fedora_old.txt b/src/logo/ascii/fedora_old.txt new file mode 100644 index 0000000000..b943ce9a26 --- /dev/null +++ b/src/logo/ascii/fedora_old.txt @@ -0,0 +1,17 @@ + /:-------------:\ + :-------------------:: + :-----------$2/shhOHbmp$1---:\ + /-----------$2omMMMNNNMMD$1 ---: + :-----------$2sMMMMNMNMP$1. ---: + :-----------$2:MMMdP$1------- ---\ +,------------$2:MMMd$1-------- ---: +:------------$2:MMMd$1------- .---: +:---- $2oNMMMMMMMMMNho$1 .----: +:-- .$2+shhhMMMmhhy++$1 .------/ +:- -------$2:MMMd$1--------------: +:- --------$2/MMMd$1-------------; +:- ------$2/hMMMy$1------------: +:--$2 :dMNdhhdNMMNo$1------------; +:---$2:sdNMMMMNds:$1------------: +:------$2:://:$1-------------:: +:---------------------:// \ No newline at end of file diff --git a/src/logo/ascii/fedora_small.txt b/src/logo/ascii/fedora_small.txt new file mode 100644 index 0000000000..0220cc5301 --- /dev/null +++ b/src/logo/ascii/fedora_small.txt @@ -0,0 +1,9 @@ + ,'''''. + | ,. | + | | '_' + ,....| |.. +.' ,_;| ..' +| | | | +| ',_,' | + '. ,' + ''''' \ No newline at end of file diff --git a/src/logo/ascii/femboyos.txt b/src/logo/ascii/femboyos.txt new file mode 100644 index 0000000000..20f0306edc --- /dev/null +++ b/src/logo/ascii/femboyos.txt @@ -0,0 +1,20 @@ +MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM +MMMMWKkxkKWMMMMMMMMMMMMMMMMMMMMWKkxkKWMM +MMMMXo. .;xKWMMMMMMMMMMMMMMMMMMXo. .oXMM +MMWXx,..'..oXMMMMMMMMMMMMMMMMWKx, .lXMM +MMNo. .cOc.,xKWMMMMMMMMMMMMWXx;.....cXMM +MMXl..;kKl. .oXMMMMMMMMMMWKx;..,ok:.'o0W +WKx,.cKWNk;..lXMMMMMMMMWKx;..,o0NXl. .oN +No. .lXMMWKc.,dKWMMMMMMNo..;d0NWMNx,..lX +Nk:,:kNMMMNk:,ckNMMMMMMNxcxXWMMMMMN0ockN +MWNNNWMMMMMWNNNWMMMMMMMMWWWMMMMMMMMMWWWM +MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM +MMMMMMMNXKXNWMMMMMMMMMMMWNKOKWMMMMMMMMMM +MMMMMMWKdccxXMMMMMMMMMMW0o'.oXMMMMMMMMMM +MMMMMMMNO:.'o0NKkkkkkOXXo. .lXMMMMMMMMMM +MMMMMMMMNx,..;o;. .:o,..;kNMMMMMMMMMM +MMMMMMMMMNO: ... .cKWMMMMMMMMMMM +MMMMMMMMMMNx,. .;dk:. .;kNMMMMMMMMMMMM +MMMMMMMMMMMN0ocxXWNkl:,:xXWMMMMMMMMMMMMM +MMMMMMMMMMMMMWNWMMMWWNNNWMMMMMMMMMMMMMMM +MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM diff --git a/src/logo/ascii/feren.txt b/src/logo/ascii/feren.txt new file mode 100644 index 0000000000..186dd7df87 --- /dev/null +++ b/src/logo/ascii/feren.txt @@ -0,0 +1,16 @@ + `----------` + :+ooooooooo+. +-o+oooooooooo+- +..`/+++++++++++/...````````````````` + .++++++++++++++++++++++++++/////- + ++++++++++++++++++++++++++++++++//:` + -++++++++++++++++++++++++++++++/-` + ++++++++++++++++++++++++++++:. + -++++++++++++++++++++++++/. + +++++++++++++++++++++/-` + -++++++++++++++++++//-` + .:+++++++++++++//////- + .:++++++++//////////- + `-++++++---:::://///. + `.:///+++. ` + `......... diff --git a/src/logo/ascii/finnix.txt b/src/logo/ascii/finnix.txt new file mode 100644 index 0000000000..9f18eac78e --- /dev/null +++ b/src/logo/ascii/finnix.txt @@ -0,0 +1,17 @@ + ,,:;;;;:,, + ,;*%S########S%*;, + ;?#################S?: + :%######################?: + +##########################; + +############################; + :#############.**,#############, + *###########+ +###########+ + ?########## ${c3}Finnix${c1} ##########* + *###########, ,###########+ + :#############%..%#############, + *############################+ + *##########################+ + ;S######################%: + ,+%##################%; + :+?S##########S?+: + ,:;++++;:, diff --git a/src/logo/ascii/floflis.txt b/src/logo/ascii/floflis.txt new file mode 100644 index 0000000000..7d50205188 --- /dev/null +++ b/src/logo/ascii/floflis.txt @@ -0,0 +1,19 @@ + ,▄▄▄▌▓▓███▓▓▌▄▄▄, + ,▄▒▓███████████████████▓▄▄ + ▄▓███████████████████████████▌ + ▓███████████████████████████████ + , ╙▓████████████████████████████▀ ▄ + ╓█▓▄ ╙▀▓████████████████████▀▀` ,▄██▓ + ╓█████▌▄, '▀▀▀▀▓▓▓▓▓▓▀▀Å╙` ▄▄▓█████▌ + ██████████▓▌▄ , ▄▓███████████▄ +╢████████████▓ ║████▓▓███▌ ╣█████████████▓ +▓█████████████ ▐█████████▀ ▓██████████████ +▓█████████████ ▐█████████▄ ███████████████ +▀████████████▌ ║█████████▌ ▀█████████████▌ + ████████████M ▓██████████ ▐█████████████⌐ + ▀██████████▌ ▐███████████▌ ▀███████████▌ + ╙▓█████▓ ▓██████████████▄ ▀███████▀ + ╝▓██▀ ╓▓████████████████▓ ▀▓██▀ + ,▄████████████████████▌, + ╝▀████████████████████▓▀' + `╙▀▀▓▓███████▓▀▀╩' diff --git a/src/logo/ascii/freebsd.txt b/src/logo/ascii/freebsd.txt new file mode 100644 index 0000000000..8526f42023 --- /dev/null +++ b/src/logo/ascii/freebsd.txt @@ -0,0 +1,15 @@ +``` $2` + $1` `.....---...$2....--.``` -/ + $1+o .--` $2/y:` +. + $1yo`:. $2:o `+- + $1y/ $2-/` -o/ + $1.- $2::/sy+:. + $1/ $2`-- / + $1`: $2:` + $1`: $2:` + $1/ $2/ + $1.- $2-. + $1-- $2-. + $1`:` $2`:` + .-- `--. + .---.....----. \ No newline at end of file diff --git a/src/logo/ascii/freebsd_small.txt b/src/logo/ascii/freebsd_small.txt new file mode 100644 index 0000000000..ee345f8926 --- /dev/null +++ b/src/logo/ascii/freebsd_small.txt @@ -0,0 +1,6 @@ +$1/\,-'''''-,/\ +\_) (_/ +| | +| | + ; ; + '-_____-' \ No newline at end of file diff --git a/src/logo/ascii/freemint.txt b/src/logo/ascii/freemint.txt new file mode 100644 index 0000000000..bc2842dbec --- /dev/null +++ b/src/logo/ascii/freemint.txt @@ -0,0 +1,15 @@ + ## + ## ######### + #### ## + #### #### ## +#### #### ## ## + #### #### ## ## + #### #### ## ## ## + #### ###### + ###### ## ## #### + #### ################ + #### ## #### + ## #### ###### + ## ## #### #### + ## ## ## ## ## #### + #### ## ## ## diff --git a/src/logo/ascii/frugalware.txt b/src/logo/ascii/frugalware.txt new file mode 100644 index 0000000000..7b760d3d67 --- /dev/null +++ b/src/logo/ascii/frugalware.txt @@ -0,0 +1,23 @@ + `++/::-.` + /o+++++++++/::-.` + `o+++++++++++++++o++/::-.` + /+++++++++++++++++++++++oo++/:-.`` + .o+ooooooooooooooooooosssssssso++oo++/:-` + ++osoooooooooooosssssssssssssyyo+++++++o: + -o+ssoooooooooooosssssssssssssyyo+++++++s` + o++ssoooooo++++++++++++++sssyyyyo++++++o: + :o++ssoooooo${c2}/-------------${c1}+syyyyyo+++++oo + `o+++ssoooooo${c2}/-----${c1}+++++ooosyyyyyyo++++os: + /o+++ssoooooo${c2}/-----${c1}ooooooosyyyyyyyo+oooss + .o++++ssooooos${c2}/------------${c1}syyyyyyhsosssy- + ++++++ssooooss${c2}/-----${c1}+++++ooyyhhhhhdssssso + -s+++++syssssss${c2}/-----${c1}yyhhhhhhhhhhhddssssy. + sooooooyhyyyyyh${c2}/-----${c1}hhhhhhhhhhhddddyssy+ + :yooooooyhyyyhhhyyyyyyhhhhhhhhhhdddddyssy` + yoooooooyhyyhhhhhhhhhhhhhhhhhhhddddddysy/ +-ysooooooydhhhhhhhhhhhddddddddddddddddssy + .-:/+osssyyyysyyyyyyyyyyyyyyyyyyyyyyssy: + ``.-/+oosysssssssssssssssssssssss + ``.:/+osyysssssssssssssh. + `-:/+osyyssssyo + .-:+++` diff --git a/src/logo/ascii/funtoo.txt b/src/logo/ascii/funtoo.txt new file mode 100644 index 0000000000..ad7a2e6e8f --- /dev/null +++ b/src/logo/ascii/funtoo.txt @@ -0,0 +1,10 @@ + .dKXXd . + :XXl;:. .OXo +.'OXO'' .''''''''''''''''''''':XNd..'oco.lco, +xXXXXXX, cXXXNNNXXXXNNXXXXXXXXNNNNKOOK; d0O .k + kXX xXo KNNN0 KNN. 'xXNo :c; 'cc. + kXX xNo KNNN0 KNN. :xxxx. 'NNo + kXX xNo loooc KNN. oNNNN. 'NNo + kXX xN0:. KNN' oNNNX' ,XNk + kXX xNNXNNNNNNNNXNNNNNNNNXNNOxXNX0Xl + ... ......................... .;cc;. diff --git a/src/logo/ascii/galliumos.txt b/src/logo/ascii/galliumos.txt new file mode 100644 index 0000000000..fdc4b71cfe --- /dev/null +++ b/src/logo/ascii/galliumos.txt @@ -0,0 +1,19 @@ +sooooooooooooooooooooooooooooooooooooo+: +yyooooooooooooooooooooooooooooooooo+/::: +yyysoooooooooooooooooooooooooooo+/:::::: +yyyyyoooooooooooooooooooooooo+/::::::::: +yyyyyysoooooooooooooooooo++/:::::::::::: +yyyyyyysoooooooooooooo++/::::::::::::::: +yyyyyyyyysoooooo${c2}sydddys${c1}+/::::::::::::::: +yyyyyyyyyysooo${c2}smMMMMMMMNd${c1}+:::::::::::::: +yyyyyyyyyyyyo${c2}sMMMMMMMMMMMN${c1}/::::::::::::: +yyyyyyyyyyyyy${c2}dMMMMMMMMMMMM${c1}o//::::::::::: +yyyyyyyyyyyyy${c2}hMMMMMMMMMMMm${c1}--//:::::::::: +yyyyyyyyyyyyyy${c2}hmMMMMMMMNy${c1}:..-://:::::::: +yyyyyyyyyyyyyyy${c2}yyhhyys+:${c1}......://::::::: +yyyyyyyyyyyyyyys+:--...........-///::::: +yyyyyyyyyyyys+:--................://:::: +yyyyyyyyyo+:-.....................-//::: +yyyyyyo+:-..........................://: +yyyo+:-..............................-// +o/:-...................................: diff --git a/src/logo/ascii/garuda.txt b/src/logo/ascii/garuda.txt new file mode 100644 index 0000000000..2234a61dd9 --- /dev/null +++ b/src/logo/ascii/garuda.txt @@ -0,0 +1,18 @@ + .%;888:8898898: + x;XxXB%89b8:b8%b88: + .8Xxd 8X:. + .8Xx; 8x:. + .tt8x .d x88; + .@8x8; .db: xx@; + ,tSXX° .bbbbbbbbbbbbbbbbbbbB8x@; + .SXxx bBBBBBBBBBBBBBBBBBBBbSBX8; + ,888S pd! +8X88/ q +8X88/ +GBB. + x%88 d888@8@X@X@X88X@@XX@@X@8@X. + dxXd dB8b8b8B8B08bB88b998888b88x. + dxx8o .@@;. + dx88 .t@x. + d:SS@8ba89aa67a853Sxxad. + .d988999889889899dd. \ No newline at end of file diff --git a/src/logo/ascii/garuda_dragon.txt b/src/logo/ascii/garuda_dragon.txt new file mode 100644 index 0000000000..26f7013b80 --- /dev/null +++ b/src/logo/ascii/garuda_dragon.txt @@ -0,0 +1,24 @@ + .:--=========--:.. + .:-=+++++===-----=======-:. + :=++++-:.. ..:-===-:. + .+++=:. .-=---. + . :-: :---: + := . :---: + .=-: :-. .---: + :-===--::. .::::. ---: + .::--====-===+=-----=-: ---: + :: :-++++====--=-:=====--=--: .--- ++**=:+++===++++++==- -===== -==-. ---: +*****+==++==--::::::======== . ===-. :--- +****==++-::.:::::-.::--======-.-=== .--- +***+=+-::::--:. -==:-==--=======-::. . :--- +=**++-::::== -+===-==: :::.:-=-==--- :--: +.*+*-:::-+= ...::==== .:: .=-:--. .. + -*++:::=+-: .:=- -- .: . ... + =*++:.++-+: .:. =-.: :-: :: :. + -*++-=+=-+=-=++===-. .====: .::::. + :++++++-:::--.-:=== --. + .=+++++- .= +.=:= .:: + :=+++++:. .: : . :---- + .-++++=-:.. .:--===-. + .-=+++++===-----=======-:. diff --git a/src/logo/ascii/garuda_small.txt b/src/logo/ascii/garuda_small.txt new file mode 100644 index 0000000000..7716d673ee --- /dev/null +++ b/src/logo/ascii/garuda_small.txt @@ -0,0 +1,5 @@ + .----. + .' , '. + .' '-----| +'. -----, + '.____.' \ No newline at end of file diff --git a/src/logo/ascii/gentoo.txt b/src/logo/ascii/gentoo.txt new file mode 100644 index 0000000000..a90dd33100 --- /dev/null +++ b/src/logo/ascii/gentoo.txt @@ -0,0 +1,18 @@ + -/oyddmdhs+:. + -o$2dNMMMMMMMMNNmhy+$1-` + -y$2NMMMMMMMMMMMNNNmmdhy$1+- + `o$2mMMMMMMMMMMMMNmdmmmmddhhy$1/` + om$2MMMMMMMMMMMN$1hhyyyo$2hmdddhhhd$1o` +.y$2dMMMMMMMMMMd$1hs++so/s$2mdddhhhhdm$1+` + oy$2hdmNMMMMMMMN$1dyooy$2dmddddhhhhyhN$1d. + :o$2yhhdNNMMMMMMMNNNmmdddhhhhhyym$1Mh + .:$2+sydNMMMMMNNNmmmdddhhhhhhmM$1my + /m$2MMMMMMNNNmmmdddhhhhhmMNh$1s: + `o$2NMMMMMMMNNNmmmddddhhdmMNhs$1+` + `s$2NMMMMMMMMNNNmmmdddddmNMmhs$1/. + /N$2MMMMMMMMNNNNmmmdddmNMNdso$1:` ++M$2MMMMMMNNNNNmmmmdmNMNdso$1/- +yM$2MNNNNNNNmmmmmNNMmhs+/$1-` +/h$2MMNNNNNNNNMNdhs++/$1-` +`/$2ohdmmddhys+++/:$1.` + `-//////:--. \ No newline at end of file diff --git a/src/logo/ascii/gentoo_small.txt b/src/logo/ascii/gentoo_small.txt new file mode 100644 index 0000000000..5c471a7a59 --- /dev/null +++ b/src/logo/ascii/gentoo_small.txt @@ -0,0 +1,7 @@ + _-----_ +( \ +\ 0 \ + $2\ ) + / _/ +( _- +\____- \ No newline at end of file diff --git a/src/logo/ascii/ghostbsd.txt b/src/logo/ascii/ghostbsd.txt new file mode 100644 index 0000000000..f77302680c --- /dev/null +++ b/src/logo/ascii/ghostbsd.txt @@ -0,0 +1,13 @@ + ,gggggg. + ,agg9* .g) + .agg* ._.,gg* + ,gga* (ggg*' + ,ga* ,ga* + ,ga' .ag* + ,ga' .agga' + 9g' .agg'g*,a + 'gggg*',gga' + .gg*' + .gga* + .gga* + (ga* diff --git a/src/logo/ascii/glaucus.txt b/src/logo/ascii/glaucus.txt new file mode 100644 index 0000000000..6878951e92 --- /dev/null +++ b/src/logo/ascii/glaucus.txt @@ -0,0 +1,12 @@ + ,, ,d88P + ,d8P ,ad8888* + ,888P d88888* ,,ad8888P* + d d888P a88888P* ,ad8888888* + .d8 d8888: d888888* ,d888888P* + .888; 88888b d8888888b8888888P + d8888J888888a88888888888888P* ,d + 88888888888888888888888888P ,,d8* + 888888888888888888888888888888888* + *8888888888888888888888888888888* + Y888888888P* `*``*888888888888* + *^888^* *Y888P** diff --git a/src/logo/ascii/gnewsense.txt b/src/logo/ascii/gnewsense.txt new file mode 100644 index 0000000000..d6a43f5df8 --- /dev/null +++ b/src/logo/ascii/gnewsense.txt @@ -0,0 +1,12 @@ + ..,,,,.. + .oocchhhhhhhhhhccoo. + .ochhlllllllc hhhhhh ollllllhhco. + ochlllllllllll hhhllllllhhh lllllllllllhco + .cllllllllllllll hlllllo +hllh llllllllllllllc. +ollllllllllhco'' hlllllo +hllh ``ochllllllllllo +hllllllllc' hllllllllllllh `cllllllllh +ollllllh +llllllllllll+ hllllllo + `cllllh. ohllllllho .hllllc' + ochllc. ++++ .cllhco + `+occooo+. .+ooocco+' + `+oo++++ ++++oo+' diff --git a/src/logo/ascii/gnome.txt b/src/logo/ascii/gnome.txt new file mode 100644 index 0000000000..71e7b21b1d --- /dev/null +++ b/src/logo/ascii/gnome.txt @@ -0,0 +1,21 @@ + ,@@@@@@@@, + @@@@@@ @@@@@@@@@@@@ + ,@@. @@@@@@@ *@@@@@@@@@@@@ + @@@@@% @@@@@@( @@@@@@@@@@@& + @@@@@@ @@@@* @@@@@@@@@# +@@@@* @@@@, *@@@@@% +@@@@@. + @@@@# @@@@@@@@@@@@@@@@ + ,@@@@@@@@@@@@@@@@@@@@@@@, + ,@@@@@@@@@@@@@@@@@@@@@@@@@@& + .@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@( + @@@@@@@@@@@@@@@@@@@@% + @@@@@@@@@@@@@@@@ + @@@@@@@@@@@@* @@@@@@@@/ + &@@@@@@@@@@ @@@@@@@@@* + @@@@@@@@@@@, @@@@@@@@@* + ,@@@@@@@@@@@@@@@@@@@@& + &@@@@@@@@@@@@@@ + ... \ No newline at end of file diff --git a/src/logo/ascii/gnu.txt b/src/logo/ascii/gnu.txt new file mode 100644 index 0000000000..0b9c3e249c --- /dev/null +++ b/src/logo/ascii/gnu.txt @@ -0,0 +1,18 @@ + _-`````-, ,- '- . + .' .- - | | - -. `. + /.' / `. \ +:/ : _... ..._ `` : +:: : /._ .`:'_.._\. || : +:: `._ ./ ,` : \ . _.'' . +`:. / | -. \-. \\_ / + \:._ _/ .' .@) \@) ` `\ ,.' + _/,--' .- .\,-.`--`. + ,'/'' (( \ ` ) + /'/' \ `-' ( + '/'' `._,-----' + ''/' .,---' + ''/' ;: + ''/'' ''/ + ''/''/'' + '/'/' + `; \ No newline at end of file diff --git a/src/logo/ascii/gobolinux.txt b/src/logo/ascii/gobolinux.txt new file mode 100644 index 0000000000..a8583004a3 --- /dev/null +++ b/src/logo/ascii/gobolinux.txt @@ -0,0 +1,6 @@ + _____ _ + / ____| | | +| | __ ___ | |__ ___ +| | |_ |/ _ \| '_ \ / _ \ +| |__| | (_) | |_) | (_) | + \_____|\___/|_.__/ \___/ diff --git a/src/logo/ascii/grapheneos.txt b/src/logo/ascii/grapheneos.txt new file mode 100644 index 0000000000..c1b8152e82 --- /dev/null +++ b/src/logo/ascii/grapheneos.txt @@ -0,0 +1,23 @@ + B? + G~ + G~& + G!^:^?# + &^.:::.J + &PG& #G5JJ7~^~?JY5B& #PG + B5JJPGJ77YG5JYP# && &B5JYPGJ7?YG5JYP# + &Y..::.:P& &?..::.:G + #!::::? B~::::J + B~J# B!?# + !P 75 + !P 75 + !5 7Y + &Y~:^!P &J~:^!P + P..::.:B Y..::.:# + #PYJJ~^^!JJYP# &B5YJ?~^^!JJYG# + &YYG# && #PYJ5G5??JGGYJ5G& && #PYP + B^.::..7& + J::::^G + #Y^G& + B~ + G! + # diff --git a/src/logo/ascii/grombyang.txt b/src/logo/ascii/grombyang.txt new file mode 100644 index 0000000000..6bbfa08bc5 --- /dev/null +++ b/src/logo/ascii/grombyang.txt @@ -0,0 +1,18 @@ + eeeeeeeeeeee + eeeeeeeeeeeeeeeee + eeeeeeeeeeeeeeeeeeeeeee + eeeee ${c2}.o+ ${c1}eeee + eeee ${c2}`ooo/ ${c1}eeee + eeee ${c2}`+oooo: ${c1}eeee +eee ${c2}`+oooooo: ${c1}eee +eee ${c2}-+oooooo+: ${c1}eee +ee ${c2}`/:oooooooo+: ${c1}ee +ee ${c2}`/+ +++ +: ${c1}ee +ee ${c2}+o+\ ${c1}ee +eee ${c2}+o+\ ${c1}eee +eee ${c2}// \\ooo/ \\\ ${c1}eee + eee ${c2}//++++oooo++++\\\ ${c1}eee + eeee ${c2}::::++oooo+::::: ${c1}eeee + eeeee ${c3}Grombyang OS ${c1} eeee + eeeeeeeeeeeeeeeeeeeeeee + eeeeeeeeeeeeeeeee diff --git a/src/logo/ascii/guix.txt b/src/logo/ascii/guix.txt new file mode 100644 index 0000000000..64b7a9972e --- /dev/null +++ b/src/logo/ascii/guix.txt @@ -0,0 +1,10 @@ + .. `. + `--..```..` `..```..--` + .-:///-:::. `-:::///:-. + ````.:::` `:::.```` + -//:` -::- + ://: -::- + `///- .:::` + -+++-:::. + :+/:::- + `-....` diff --git a/src/logo/ascii/guix_small.txt b/src/logo/ascii/guix_small.txt new file mode 100644 index 0000000000..ee48c00216 --- /dev/null +++ b/src/logo/ascii/guix_small.txt @@ -0,0 +1,7 @@ +|.__ __.| +|__ \\ / __| + \\ \\ / / + \\ \\ / / + \\ \\ / / + \\ \\/ / + \\__/ diff --git a/src/logo/ascii/haiku.txt b/src/logo/ascii/haiku.txt new file mode 100644 index 0000000000..36b432aa61 --- /dev/null +++ b/src/logo/ascii/haiku.txt @@ -0,0 +1,12 @@ +$3 MMMM MMMM + MMMM MMMM + MMMM MMMM + MMMM MMMM + MMMM$4 .ciO| /YMMMMM*" +$3 MMMM$4 .cOMMMMM|/MMMMM/` + , ,iMM|/MMMMMMMMMMMMMMM* + `*.__,-cMMMMMMMMMMMMMMMMM/`$3.MMM + MM$4MMMMMMM/`:MMM/ $3MMMM + MMMM MMMM + MMMM MMMM + """" """" \ No newline at end of file diff --git a/src/logo/ascii/haiku_small.txt b/src/logo/ascii/haiku_small.txt new file mode 100644 index 0000000000..595c3225d0 --- /dev/null +++ b/src/logo/ascii/haiku_small.txt @@ -0,0 +1,8 @@ + ,^, + / \\ +*--_ ; ; _--* +\\ '" "' / + '. .' +.-'" "'-. + '-.__. .__.-' + |_| \ No newline at end of file diff --git a/src/logo/ascii/hamonikr.txt b/src/logo/ascii/hamonikr.txt new file mode 100644 index 0000000000..c2f38f4328 --- /dev/null +++ b/src/logo/ascii/hamonikr.txt @@ -0,0 +1,23 @@ + cO0Ox. + .ldddddddo. + .lddddddddddo + 'lddddddddddddc + ,oddddddddddddd; + 'ldddddddddddddo. + .oddddddddddddddc. + ,dddddddddddddddo. + ,ccoooooooocoddooo: + ,cooooooooooooooooop ${c3} c000x. +${c1}.cooooooooooooooopcllll${c3} .cddddddo. +${c1}coooooooooooooop' .qlll.${c3} .ddoooooooo; +${c1}cooooooooooc; ${c3}'qlllp. .ddoooooooooo; +${c1}.cooooooc; ${c3}'lllbc...coooooooooooo; +${c1} .cooc' ${c3}.llllcoooooooooooooo. + .coooooooooooooop: + .coooooooooooooop' + .cooooooooooooop. + .cooooooooooooop. + .coooooooooooop. + .cooooooooooop. + .cooooooooop. + .cooooop' diff --git a/src/logo/ascii/hardclanz.txt b/src/logo/ascii/hardclanz.txt new file mode 100644 index 0000000000..19766d953e --- /dev/null +++ b/src/logo/ascii/hardclanz.txt @@ -0,0 +1,19 @@ +${c1} ........::::.... + ::################::.. + :########################:. + :######**###################: + :###${c2}&&&&^${c1}############ ${c2}&${c1}#######: + :#${c2}&&&&&${c1}.:##############:${c2}^&o${c1}`:###: + :#${c2}&&&&${c1}.:#################:.${c2}&&&${c1}`###: + :##${c2}&^${c1}:######################:${c2}^&&${c1}::##: + :#############################:${c2}&${c1}:##:: + :##########${c2}@@${c1}###########${c2}@@${c1}#####:.###: +:#########${c2}@@${c3}o${c2}@@${c1}#########${c2}@@${c3}o${c2}@@${c1}########: +:#######:${c2}@@${c3}o${c5}0${c3}o${c2}@@@@${c1}###${c2}@@@@${c3}o${c5}0${c3}o${c2}@@${c1}######: : + :######:${c2}@@@${c3}o${c2}@@@@@@${c1}V${c2}@@@@@@${c3}o${c2}@@@${c1}######: + :#####:${c2}@@@@@@@@@@@@@@@@@@@${c1}:####; + :####:.${c2}@@@@@@@@@@@@@@@@${c1}:#####: + `:####:.${c2}@@@@@@@@@@@@@@${c1}:#####: + ``:##:.${c2}@@@@@@@@@@@@${c1}^## # : + : ## ${c2}\@@@;@@@/ ${c1}:: # : + ${c2} VVV diff --git a/src/logo/ascii/hash.txt b/src/logo/ascii/hash.txt new file mode 100644 index 0000000000..1ddaf1758c --- /dev/null +++ b/src/logo/ascii/hash.txt @@ -0,0 +1,13 @@ + + ###### + + ### ###### ### + ##### ###### ##### + ###### ###### ###### + +####### '"###### '"######## +####### ###### ######## +####### ###### ######## + + ###### '"###### '"###### + ##### ###### ##### + ### ###### ### + ~ ###### ~ diff --git a/src/logo/ascii/huayra.txt b/src/logo/ascii/huayra.txt new file mode 100644 index 0000000000..5cca3f8804 --- /dev/null +++ b/src/logo/ascii/huayra.txt @@ -0,0 +1,17 @@ +${c2} ` + . . ` + `` - . . + `.` -` `. - `` .` + ..`-`-` + - / .` ``` + .--.+--`+:- :/.` .-``.` + -+/so::h:.d-`./:`.` + :hNhyMomy:os-...-. ```` + .dhsshNmNhoo+:-``.``` + ${c1}`ohy:-${c2}NMds+::-.`` + ````${c1}.hNN+`${c2}mMNho/:-....```` + ````` `../dmNhoo+/:..`` + ```` .dh++o/:....` +.+s/` `/s-.-.:.`` ```` +::` `::`..` + .` `.. + `` diff --git a/src/logo/ascii/hybrid.txt b/src/logo/ascii/hybrid.txt new file mode 100644 index 0000000000..bc0d064442 --- /dev/null +++ b/src/logo/ascii/hybrid.txt @@ -0,0 +1,16 @@ +${c1} / ${c2}# +${c1}////& ${c2}##### +${c1}///// ${c2}###### +${c1}///// ////////// ${c2}###### +${c1}///// //////////////////// ${c2}###### +${c1}////////////////////////// ${c2}###### +${c1}///////// /// ${c2}###### +${c1}/////// / ${c2}###### +${c1}////// ${c2}###### +${c1}///// ${c2}###### +${c1}///// ${c2}###### +${c1}///// ${c2}###### +${c1}///// ${c2}###### +${c1}///// ${c2}###### +${c1}///// ${c2}######### +${c1}////& ${c2}######## diff --git a/src/logo/ascii/hydroos.txt b/src/logo/ascii/hydroos.txt new file mode 100644 index 0000000000..df5bbe4a54 --- /dev/null +++ b/src/logo/ascii/hydroos.txt @@ -0,0 +1,8 @@ + _ _ _ ____ _____ +| | | | | | / __ \ / ____| +| |__| |_ _ __| |_ __ ___ | | | | (___ +| __ | | | |/ _` | '__/ _ \| | | |\___ \ +| | | | |_| | (_| | | | (_) | |__| |____) | +|_| |_|\__, |\__,_|_| \___/ \____/|_____/ + __/ | + |___/ diff --git a/src/logo/ascii/hyperbola.txt b/src/logo/ascii/hyperbola.txt new file mode 100644 index 0000000000..396a7a195a --- /dev/null +++ b/src/logo/ascii/hyperbola.txt @@ -0,0 +1,16 @@ + WW + KX W + WO0W NX0O + NOO0NW WNXK0OOKW + W0OOOOOOOOOOOOKN + N0OOOOOOO0KXW + WNXXXNW + NXK00000KN + WNK0OOOOOOOOOO0W + NK0OOOOOOOOOOOOOO0W + X0OOOOOOO00KK00OOOOOK + X0OOOO0KNWW WX0OO0W + X0OO0XNW KOOW + N00KNW KOW + NKXN W0W +WW W diff --git a/src/logo/ascii/hyperbola_small.txt b/src/logo/ascii/hyperbola_small.txt new file mode 100644 index 0000000000..b3adf7d9ed --- /dev/null +++ b/src/logo/ascii/hyperbola_small.txt @@ -0,0 +1,7 @@ + |`__.`/ + \____/ + .--. + / \\ + / ___ \\ + / .` `.\\ +/.` `.\\ diff --git a/src/logo/ascii/iglunix.txt b/src/logo/ascii/iglunix.txt new file mode 100644 index 0000000000..a36537a3ba --- /dev/null +++ b/src/logo/ascii/iglunix.txt @@ -0,0 +1,12 @@ + | + | | + | +| ________ +| /\ | \ + / \ | \ | + / \ \ | +/ \________\ +\ / / + \ / / + \ / / + \/________/ diff --git a/src/logo/ascii/instantos.txt b/src/logo/ascii/instantos.txt new file mode 100644 index 0000000000..150b520c33 --- /dev/null +++ b/src/logo/ascii/instantos.txt @@ -0,0 +1,20 @@ + 'cx0XWWMMWNKOd:'. + .;kNMMMMMMMMMMMMMWNKd' + 'kNMMMMMMWNNNWMMMMMMMMXo. +,0MMMMMW0o;'..,:dKWMMMMMWx. +OMMMMMXl. .xNMMMMMNo +WMMMMNl .kWWMMMMO' +MMMMMX; oNWMMMMK, +NMMMMWo .OWMMMMMK, +kWMMMMNd. ,kWMMMMMMK, +'kWMMMMWXxl:;;:okNMMMMMMMMK, + .oXMMMMMMMWWWMMMMMMMMMMMMK, + 'oKWMMMMMMMMMMMMMMMMMMMK, + .;lxOKXXXXXXXXXXXXXXXO;...... + ................,d0000000kd:. + .kMMMMMMMMMW0; + .kMMMMMMMMMMMX + .xMMMMMMMMMMMW + cXMMMMMMMMMM0 + :0WMMMMMMNx, + .o0NMWNOc. diff --git a/src/logo/ascii/irix.txt b/src/logo/ascii/irix.txt new file mode 100644 index 0000000000..ae9329bb41 --- /dev/null +++ b/src/logo/ascii/irix.txt @@ -0,0 +1,19 @@ + ./ohmNd/ +dNmho/- + `:+ydNMMMMMMMM.-MMMMMMMMMdyo:. + `hMMMMMMNhs/sMMM-:MMM+/shNMMMMMMh` + -NMMMMMmo-` /MMM-/MMM- `-omMMMMMN. + `.`-+hNMMMMMNhyMMM-/MMMshmMMMMMmy+...` ++mMNds:-:sdNMMMMMMMyyMMMMMMMNdo:.:sdMMm+ +dMMMMMMmy+.-/ymNMMMMMMMMNmy/-.+hmMMMMMMd +oMMMMmMMMMNds:.+MMMmmMMN/.-odNMMMMmMMMM+ +.MMMM-/ymMMMMMmNMMy..hMMNmMMMMMmy/-MMMM. + hMMM/ `/dMMMMMMMN////NMMMMMMMd/. /MMMh + /MMMdhmMMMmyyMMMMMMMMMMMMhymMMMmhdMMM: + `mMMMMNho//sdMMMMM//NMMMMms//ohNMMMMd + `/so/:+ymMMMNMMMM` mMMMMMMMmh+::+o/` + `yNMMNho-yMMMM` NMMMm.+hNMMNh` + -MMMMd: oMMMM. NMMMh :hMMMM- + -yNMMMmooMMMM- NMMMyomMMMNy- + .omMMMMMMMM-`NMMMMMMMmo. + `:hMMMMMM. NMMMMMh/` + .odNm+ /dNms. diff --git a/src/logo/ascii/itc.txt b/src/logo/ascii/itc.txt new file mode 100644 index 0000000000..f27c4c3c2b --- /dev/null +++ b/src/logo/ascii/itc.txt @@ -0,0 +1,10 @@ +${c1}....................-==============+... +${c1}....................-==============:... +${c1}...:===========-....-==============:... +${c1}...-===========:....-==============-... +${c1}....*==========+........-::********-... +${c1}....*===========+.:*====**==*+-.-...... +${c1}....:============*+-..--:+**====*---... +${c1}......::--........................::... +${c1}..+-:+-.+::*:+::+:-++::++-.:-.*.:++:++. +${c1}..:-:-++++:-::--:+::-::.:++-++:++--:-:. diff --git a/src/logo/ascii/januslinux.txt b/src/logo/ascii/januslinux.txt new file mode 100644 index 0000000000..e81cc69a48 --- /dev/null +++ b/src/logo/ascii/januslinux.txt @@ -0,0 +1,24 @@ + 'l: + loooooo + loooo coooool + looooooooooooooooooool + looooooooooooooooo + lool cooo + coooooooloooooooo + clooooo ;lood cloooo + :loooocooo cloo loooo + loooo :ooooool loooo +looo cooooo cooooo +looooooooooooo ;loooooo ${c2}looooooc +${c1}looooooooo loo cloooooool ${c2}looooc +${c1} cooo cooooooooooo ${c2}looolooooool +${c1} cooo: ${c2}coooooooooooooooooool + loooooooooooolc: loooc; + cooo: loooooooooooc + ;oool looooooo: + coool olc, + looooc ,, + coooooc loc + :oooool, coool:, looool:, + looool: ooooooooooooooo: + cooolc .ooooooooooool diff --git a/src/logo/ascii/kaisen.txt b/src/logo/ascii/kaisen.txt new file mode 100644 index 0000000000..be9cd08942 --- /dev/null +++ b/src/logo/ascii/kaisen.txt @@ -0,0 +1,17 @@ + `:+oyyho. + `+:`sdddddd/ + `+` :ho oyo++ohds-` + .ho :dd. .: `sddddddhhyso+/- + ody.ddd-:yd- +hysssyhddddddddho` + yddddddhddd` ` `--` -+hddddddh. + hddy-+dddddy+ohh/..+sddddy/:::+ys + :ddd/sdddddddddd- oddddddd ` + `yddddddddddddddd/ /ddddddd/ +:. :ydddddddddddddddddo..sddddddy/` +odhdddddddo- `ddddh+-``....-+hdddddds. +-ddddddhd: /dddo -ydddddddhdddddddd- + /hdy:o - `:sddds .`./hdddddddddddddo + `/- `+hddyosy+ :dddddddy-.-od/ + :sydds -hddddddd` / + .+shd- `:ohddddddddd` + `:+ooooooooooooo: diff --git a/src/logo/ascii/kali.txt b/src/logo/ascii/kali.txt new file mode 100644 index 0000000000..84176a04b7 --- /dev/null +++ b/src/logo/ascii/kali.txt @@ -0,0 +1,21 @@ +.............. + ..,;:ccc,. + ......''';lxO. +.....''''..........,:ld; + .';;;:::;,,.x, + ..'''. 0Xxoc:,. ... + .... ,ONkc;,;cokOdc',. + . OMo ':${c2}dd${c1}o. + dMc :OO; + 0M. .:o. + ;Wd + ;XO, + ,d0Odlc;,.. + ..',;:cdOOd::,. + .:d;.':;. + 'd, .' + ;l .. + .o + c + .' + . diff --git a/src/logo/ascii/kali_small.txt b/src/logo/ascii/kali_small.txt new file mode 100644 index 0000000000..c8a468cead --- /dev/null +++ b/src/logo/ascii/kali_small.txt @@ -0,0 +1,16 @@ + -#. # + @### + -###### + @######### +=##. .##### +## ## ## +## ## # +## @### +##. ### + ##% ##- + -##% -* + :*##+ + :*#* + -# + @ + : diff --git a/src/logo/ascii/kaos.txt b/src/logo/ascii/kaos.txt new file mode 100644 index 0000000000..8648a71c10 --- /dev/null +++ b/src/logo/ascii/kaos.txt @@ -0,0 +1,16 @@ + .. + ..... ..OSSAAAAAAA.. + .KKKKSS. .SSAAAAAAAAAAA. +.KKKKKSO. .SAAAAAAAAAA... +KKKKKKS. .OAAAAAAAA. +KKKKKKS. .OAAAAAA. +KKKKKKS. .SSAA.. +.KKKKKS..OAAAAAAAAAAAA........ + DKKKKO.=AA=========A===AASSSO.. + AKKKS.==========AASSSSAAAAAASS. + .=KKO..========ASS.....SSSSASSSS. + .KK. .ASS..O.. =SSSSAOSS: + .OK. .ASSSSSSSO...=A.SSA. + .K ..SSSASSSS.. ..SSA. + .SSS.AAKAKSSKA. + .SSS....S.. diff --git a/src/logo/ascii/kde.txt b/src/logo/ascii/kde.txt new file mode 100644 index 0000000000..716339e210 --- /dev/null +++ b/src/logo/ascii/kde.txt @@ -0,0 +1,19 @@ + `..---+/---..` + `---.`` `` `.---.` + .--.` `` `-:-. + `:/: `.----//----.` :/- + .:. `---` `--.` .:` + .:` `--` .:- `:. + `/ `:. `.-::-.` -:` `/` + /. /. `:++++++++:` .: .: +`/ .: `+++++++++++/ /` `+` +/+` -- .++++++++++++` :. .+: +`/ .: `+++++++++++/ /` `+` + /` /. `:++++++++:` .: .: + ./ `:. `.:::-.` -:` `/` + .:` `--` .:- `:. + .:. `---` `--.` .:` + `:/: `.----//----.` :/- + .-:.` `` `-:-. + `---.`` `` `.---.` + `..---+/---..` \ No newline at end of file diff --git a/src/logo/ascii/kibojoe.txt b/src/logo/ascii/kibojoe.txt new file mode 100644 index 0000000000..5e8cf510fc --- /dev/null +++ b/src/logo/ascii/kibojoe.txt @@ -0,0 +1,13 @@ +${c3} ./+oooooo+/. + -/+ooooo+/:.` + ${c1}`${c3}yyyo${c2}+++/++${c3}osss${c1}. + ${c1}+NMN${c3}yssssssssssss${c1}. + ${c1}.dMMMMN${c3}sssssssssssy${c1}Ns` + +MMMMMMMm${c3}sssssssssssh${c1}MNo` + `hMMMMMNNNMd${c3}sssssssssssd${c1}MMN/ + .${c3}syyyssssssy${c1}NNmmmmd${c3}sssss${c1}hMMMMd: + -NMmh${c3}yssssssssyhhhhyssyh${c1}mMMMMMMMy` + -NMMMMMNN${c3}mdhyyyyyyyhdm${c1}NMMMMMMMMMMMN+ +`NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMd. +ods+/:-----://+oyydmNMMMMMMMMMMMMMMMMMN- +` .-:+osyhhdmmNNNmdo diff --git a/src/logo/ascii/kiss.txt b/src/logo/ascii/kiss.txt new file mode 100644 index 0000000000..b9d7cad31a --- /dev/null +++ b/src/logo/ascii/kiss.txt @@ -0,0 +1,7 @@ + $3 ___ + ($2.· $3| + ($1<> $3| + / $2__$3 \ + ( $1/ \ $3/| +$1_$3/\ $2__)$3/$1_$3) +$1\/$3-____$1\/$2 diff --git a/src/logo/ascii/kogaion.txt b/src/logo/ascii/kogaion.txt new file mode 100644 index 0000000000..1a305e06b7 --- /dev/null +++ b/src/logo/ascii/kogaion.txt @@ -0,0 +1,20 @@ + ;; ,; + ;;; ,;; + ,;;;; ;;;; + ,;;;;;;;; ;;;; + ;;;;;;;;;;; ;;;;; + ,;;;;;;;;;;;; ';;;;;, + ;;;;;;;;;;;;;;, ';;;;;;; + ;;;;;;;;;;;;;;;;;, ';;;;; +; ';;;;;;;;;;;;;;;;;;, ;;; +;;;, ';;;;;;;;;;;;;;;;;;;,;; +;;;;;, ';;;;;;;;;;;;;;;;;;, +;;;;;;;;, ';;;;;;;;;;;;;;;;, +;;;;;;;;;;;;, ';;;;;;;;;;;;;; +';;;;;;;;;;;;; ';;;;;;;;;;;;; + ';;;;;;;;;;;;;, ';;;;;;;;;;; + ';;;;;;;;;;;;; ;;;;;;;;;; + ';;;;;;;;;;;; ;;;;;;;; + ';;;;;;;; ;;;;;; + ';;;;; ;;;; + ';;; ;; diff --git a/src/logo/ascii/korora.txt b/src/logo/ascii/korora.txt new file mode 100644 index 0000000000..709289afd3 --- /dev/null +++ b/src/logo/ascii/korora.txt @@ -0,0 +1,16 @@ +${c2} ____________ + _add55555555554${c1}: + _w?'${c1}``````````'${c2})k${c1}: + _Z'${c1}`${c2} ]k${c1}: + m(${c1}`${c2} )k${c1}: + _.ss${c1}`${c2}m[${c1}`${c2}, ]e${c1}: + .uY"^`${c1}`${c2}Xc${c1}`${c2}?Ss. d(${c1}` + jF'${c1}`${c2} `@. ${c1}`${c2}Sc .jr${c1}` + jr${c1}`${c2} `?n_ ${c1}`${c2}$; _a2"${c1}` +.m${c1}:${c2} `~M${c1}`${c2}1k${c1}`${c2}5?!`${c1}` +:#${c1}:${c2} ${c1}`${c2})e${c1}``` +:m${c1}:${c2} ,#'${c1}` +:#${c1}:${c2} .s2'${c1}` +:m,________.aa7^${c1}` +:#baaaaaaas!J'${c1}` + ``````````` diff --git a/src/logo/ascii/krassos.txt b/src/logo/ascii/krassos.txt new file mode 100644 index 0000000000..aa3bdcaa3d --- /dev/null +++ b/src/logo/ascii/krassos.txt @@ -0,0 +1,19 @@ + ${c2}**@@@@@@@@@@@* + ${c2},@@@@%${c1}(((((((((((((${c2}%@@@@, + ${c2}#@@&${c1}(((((((((((((((((((((((${c2}&@@% + ${c2}@@&${c1}(((((((((((((((((((((((((((((${c2}@@@ + ${c2}@@&${c1}(((((((((((((((((((((((((((((((((${c2}&@@ + ${c2}.@@${c1}(((((((((((((((((((((((((((((((((((((${c2}@@. + ${c2}@@${c1}(((((((((((((((((((((((((((((((((((((((${c2}@@ + ${c2}@@#${c1}(((((((((((((((((((((((((((((${c2}%@@@@@@@#${c1}(#${c2}@@ + ${c2}.@@${c1}((((((((((((((((${c2}#%@@@@@@@@@&%#${c1}((((${c2}%@&${c1}((((${c2}@@. + ${c2}.@@${c1}(((((((/(${c2}&@@@@@@%${c1}(/((((((((((((((${c2}@@/${c1}(((((${c2}@@. + ${c2}.@@${c1}(///////////////////////////////${c2}@${c1}(///////${c2}@@ + ${c2}%@#${c1}/////////////////////////////(${c2}#${c1}////////${c2}%@% + ${c2} @@${c1}(///////////////////////////${c2}%${c1}/////////(${c2}@@ + ${c2}@@#${c1}***********************************${c2}%@@ + ${c2}*@@${c1}********************************${c2}/@@/ + ${c2},@@#${c1}***************************${c2}%@@* + ${c2}@@@&${c1}********************${c2}/@@@@ + ${c2}&@@@@&${c1}(//***//(${c2}&@@@@& + ${c2}**@@@@@@@@@@@* diff --git a/src/logo/ascii/kslinux.txt b/src/logo/ascii/kslinux.txt new file mode 100644 index 0000000000..c2246410bb --- /dev/null +++ b/src/logo/ascii/kslinux.txt @@ -0,0 +1,11 @@ +K K U U RRRR ooo +K K U U R R o o +KKK U U RRRR o o +K K U U R R o o +K K UUU R R ooo + +${c2} SSS AAA W W AAA +S A A W W A A + SSS AAAAA W W W AAAAA + S A A WW WW A A + SSS A A W W A A diff --git a/src/logo/ascii/kubuntu.txt b/src/logo/ascii/kubuntu.txt new file mode 100644 index 0000000000..d19bca23e2 --- /dev/null +++ b/src/logo/ascii/kubuntu.txt @@ -0,0 +1,20 @@ +$1 `.:/ossyyyysso/:. + .:oyyyyyyyyyyyyyyyyyyo:` + -oyyyyyyyo$2dMMy$1yyyyyyysyyyyo- + -syyyyyyyyyy$2dMMy$1oyyyy$2dmMMy$1yyyys- + oyyys$2dMy$1syyyy$2dMMMMMMMMMMMMMy$1yyyyyyo + `oyyyy$2dMMMMy$1syysoooooo$2dMMMMy$1yyyyyyyyo` + oyyyyyy$2dMMMMy$1yyyyyyyyyyys$2dMMy$1sssssyyyo +-yyyyyyyy$2dMy$1syyyyyyyyyyyyyys$2dMMMMMy$1syyy- +oyyyysoo$2dMy$1yyyyyyyyyyyyyyyyyy$2dMMMMy$1syyyo +yyys$2dMMMMMy$1yyyyyyyyyyyyyyyyyysosyyyyyyyy +yyys$2dMMMMMy$1yyyyyyyyyyyyyyyyyyyyyyyyyyyyy +oyyyyysos$2dy$1yyyyyyyyyyyyyyyyyy$2dMMMMy$1syyyo +-yyyyyyyy$2dMy$1syyyyyyyyyyyyyys$2dMMMMMy$1syyy- + oyyyyyy$2dMMMy$1syyyyyyyyyyys$2dMMy$1oyyyoyyyo + `oyyyy$2dMMMy$1syyyoooooo$2dMMMMy$1oyyyyyyyyo + oyyysyyoyyyys$2dMMMMMMMMMMMy$1yyyyyyyo + -syyyyyyyyy$2dMMMy$1syyy$2dMMMy$1syyyys- + -oyyyyyyy$2dMMy$1yyyyyysosyyyyo- + ./oyyyyyyyyyyyyyyyyyyo/. + `.:/oosyyyysso/:.` \ No newline at end of file diff --git a/src/logo/ascii/langitketujuh.txt b/src/logo/ascii/langitketujuh.txt new file mode 100644 index 0000000000..6b72d3f013 --- /dev/null +++ b/src/logo/ascii/langitketujuh.txt @@ -0,0 +1,11 @@ +$2. $1'7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7 +$2L7. $1'7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7 +$2L7L7L $17L7L7L7L7L7L7L7L7L7L7L7L7L7 +$2L7L7L7 $1L7L7L7 +$2L7L7L7 $1'L7L7L7L7L7L7L7L7L7L7 +$2L7L7L7 $1'L7L7L7L7L7L7L7L7 +$2L7L7L7 $1'L7L7L7L7L7L7 +$2L7L7L7 $1L7L7L7 +$2L7L7L7L7L7L7L7L7L7L7LL7L7L7. $1'7L7L7 +$2L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L. $1'L7 +$2L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7. $1' diff --git a/src/logo/ascii/laxeros.txt b/src/logo/ascii/laxeros.txt new file mode 100644 index 0000000000..38d24c8f07 --- /dev/null +++ b/src/logo/ascii/laxeros.txt @@ -0,0 +1,20 @@ + /. + `://:- + `//////: + .////////:` + -//////////:` + -/////////////` + :///////////////. + `://////.```-//////- + `://///:` .//////- + `//////: `//////: + .//////- `://///:` + -//////- `://///:` + -//////. ://////` + ://////` -//////. + `/////:` ./////: + .-::-` .:::-` + +.:://////////////////////////////////::. +//////////////////////////////////////// +.:////////////////////////////////////:. diff --git a/src/logo/ascii/lede.txt b/src/logo/ascii/lede.txt new file mode 100644 index 0000000000..459ae94ec2 --- /dev/null +++ b/src/logo/ascii/lede.txt @@ -0,0 +1,9 @@ + _________ + / /\ + / LE / \ + / DE / \ +/________/ LE \ +\ \ DE / + \ LE \ / + \ DE \ / + \________\/ diff --git a/src/logo/ascii/libreelec.txt b/src/logo/ascii/libreelec.txt new file mode 100644 index 0000000000..9a6534e3fe --- /dev/null +++ b/src/logo/ascii/libreelec.txt @@ -0,0 +1,20 @@ +${c1} :+ooo/. ${c2}./ooo+: +${c1} :+ooooooo/. ${c2}./ooooooo+: +${c1} :+ooooooooooo:${c2}:ooooooooooo+: +${c1} :+ooooooooooo+- ${c2}-+ooooooooooo+: +${c1} :+ooooooooooo+- ${c3}-- ${c2}-+ooooooooooo+: +${c1}.+ooooooooooo+- ${c3}:+oo+: ${c2}-+ooooooooooo+- +${c1}-+ooooooooo+- ${c3}:+oooooo+: ${c2}-+oooooooooo- +${c1} :+ooooo+- ${c3}:+oooooooooo+: ${c2}-+oooooo: +${c1} :+o+- ${c3}:+oooooooooooooo+: ${c2}-+oo: +${c4} ./ ${c3}:oooooooooooooooooo: ${c5}/. +${c4} ./oo+: ${c3}-+oooooooooooooo+- ${c5}:+oo/. +${c4} ./oooooo+: ${c3}-+oooooooooo+- ${c5}:+oooooo/. +${c4}-oooooooooo+: ${c3}-+oooooo+- ${c5}:+oooooooooo- +${c4}.+ooooooooooo+: ${c3}-+oo+- ${c5}:+ooooooooooo+. +${c4} -+ooooooooooo+: ${c3}.. ${c5}:+ooooooooooo+- +${c4} -+ooooooooooo+: ${c5}:+ooooooooooo+- +${c4} -+oooooooooo+:${c5}:+oooooooooo+- +${c4} -+oooooo+: ${c5}:+oooooo+- +${c4} -+oo+: ${c5}:+oo+- +${c4} .. ${c5}.. diff --git a/src/logo/ascii/linspire.txt b/src/logo/ascii/linspire.txt new file mode 100644 index 0000000000..3b8fbd450f --- /dev/null +++ b/src/logo/ascii/linspire.txt @@ -0,0 +1,12 @@ +${c2} __^ +${c2} __/ \\ +${c2} MMy dMy __/ \\ +${c2} dMMy MMy ${c1}MM${c2} \\ +${c2} MMMy ,, ${c1}dMMMMn ${c2}\\ +${c2} dMMy dMM dMMMMMMy ${c1}dMM MM dMMMMMy dMM MM.nMMM dMMMMMM +${c1}MMM ${c2}MMy MMy MMy ${c1}dMM MMy MMy MMy MMy dy dMy +${c1}MMM ${c2}dMM dMM MMy ${c1}dMMMMy dMM dMM dMM dMM dMMMMMMM +${c2} dMMy MMy MMy MMy ${c1}dMMy MM MMy MMy MMy dMM +${c2}dMMy dMM dMM dMM ${c1}dMM MMy dMMMMMy dMM dMM MMy MM +${c2}MMMMMMMMMM MMy MMy MMy ${c1}dMMMyyy MMy MMy MMy dMMMMMMy +${c2} ${c1}dy diff --git a/src/logo/ascii/linux.txt b/src/logo/ascii/linux.txt new file mode 100644 index 0000000000..fc8a5b456b --- /dev/null +++ b/src/logo/ascii/linux.txt @@ -0,0 +1,12 @@ + $2##### + $2####### + $2##$1O$2#$1O$2## + $2#$3#####$2# + $2##$1##$3###$1##$2## + $2#$1##########$2## + $2#$1############$2## + $2#$1############$2### + $3##$2#$1###########$2##$3# +$3######$2#$1#######$2#$3###### +$3#######$2#$1#####$2#$3####### + $3#####$2#######$3##### \ No newline at end of file diff --git a/src/logo/ascii/linux_small.txt b/src/logo/ascii/linux_small.txt new file mode 100644 index 0000000000..7446180b57 --- /dev/null +++ b/src/logo/ascii/linux_small.txt @@ -0,0 +1,7 @@ + $1___ + ($2.. $1\ + ($3<> $1| + /$2/ \ $1\ + ( $2| | $1/| +$3_$1/\ $2__)$1/$3_$1) +$3\/$1-____$3\/ diff --git a/src/logo/ascii/linuxlite.txt b/src/logo/ascii/linuxlite.txt new file mode 100644 index 0000000000..c6a398b8d6 --- /dev/null +++ b/src/logo/ascii/linuxlite.txt @@ -0,0 +1,20 @@ + ,xXc + .l0MMMMMO + .kNMMMMMWMMMN, + KMMMMMMKMMMMMMo + 'MMMMMMNKMMMMMM: + kMMMMMMOMMMMMMO + .MMMMMMX0MMMMMW. + oMMMMMMxWMMMMM: + WMMMMMNkMMMMMO +:MMMMMMOXMMMMW +.0MMMMMxMMMMM; +:;cKMMWxMMMMO +'MMWMMXOMMMMl + kMMMMKOMMMMMX: + .WMMMMKOWMMM0c + lMMMMMWO0MNd:' + oollXMKXoxl;. + ':. .: .' + .. + . diff --git a/src/logo/ascii/linuxlite_small.txt b/src/logo/ascii/linuxlite_small.txt new file mode 100644 index 0000000000..6fd817d4d1 --- /dev/null +++ b/src/logo/ascii/linuxlite_small.txt @@ -0,0 +1,7 @@ +${c1} /\\ + / \\ + / ${c2}/ ${c1}/ +> ${c2}/ ${c1}/ +\\ ${c2}\\ ${c1}\\ + \\_${c2}\\${c1}_\\ +${c2} \\ diff --git a/src/logo/ascii/live_raizo.txt b/src/logo/ascii/live_raizo.txt new file mode 100644 index 0000000000..ebc079feb4 --- /dev/null +++ b/src/logo/ascii/live_raizo.txt @@ -0,0 +1,20 @@ + `......` + -+shmNMMMMMMNmhs/. + :smMMMMMmmhyyhmmMMMMMmo- + -hMMMMd+:. `----` .:odMMMMh- + `hMMMN+. .odNMMMMMMNdo. .yMMMMs` + hMMMd. -dMMMMmdhhdNMMMNh` .mMMMh +oMMMm` :MMMNs.:sddy:-sMMMN- `NMMM+ +mMMMs dMMMo sMMMMMMd yMMMd sMMMm +----` .---` oNMMMMMh `---. .---- + .sMMy: + /MM/ + +dMMms. + hMMMMMMN + `dMMMMMMm: + .+ss+sMNysMMoomMd+ss+. + +MMMMMMN` +MM/ hMMMMMNs + sMMMMMMm-hNMMMd-hMMMMMMd + :yddh+`hMMMMMMN :yddy/` + .hMMMMd: + `..` diff --git a/src/logo/ascii/lmde.txt b/src/logo/ascii/lmde.txt new file mode 100644 index 0000000000..9e45de8355 --- /dev/null +++ b/src/logo/ascii/lmde.txt @@ -0,0 +1,17 @@ +$2 `.-::---.. +$1 .:++++ooooosssoo:. + .+o++::. `.:oos+. +$1 :oo:.` -+oo$2: +$1 $2`$1+o/` .$2::::::$1-. .++-$2` +$1$2`$1/s/ .yyyyyyyyyyo: +o-$2` +$1$2`$1so .ss ohyo` :s-$2: +$1$2`$1s/ .ss h m myy/ /s`$2` +$1`s: `oo s m Myy+-o:` +`oo :+sdoohyoydyso/. + :o. .:////////++: +$1 `/++ $2-:::::- +$1 $2`$1++- +$1 $2`$1/+- +$1 $2.$1+/. +$1 $2.$1:+-. + `--.`` \ No newline at end of file diff --git a/src/logo/ascii/lunar.txt b/src/logo/ascii/lunar.txt new file mode 100644 index 0000000000..dd4373e83c --- /dev/null +++ b/src/logo/ascii/lunar.txt @@ -0,0 +1,13 @@ +`-. `-. + -ohys/-` `:+shy/` + -omNNdyo/` :+shmNNy/` + ${c3} - + /mMmo + hMMMN` + .NMMs + ${c1} -:+oooo+//: ${c3}/MN${c1}. -///oooo+/-` + /:.` ${c3}/${c1} `.:/` +${c3} __ + | | _ _ ___ ___ ___ + | |__| | | | .'| _| + |_____|___|_|_|__,|_| diff --git a/src/logo/ascii/macos.txt b/src/logo/ascii/macos.txt new file mode 100644 index 0000000000..6ecf8840e8 --- /dev/null +++ b/src/logo/ascii/macos.txt @@ -0,0 +1,17 @@ + $1..' + ,xNMM. + .OMMMMo + lMM" + .;loddo:. .olloddol;. + cKMMMMMMMMMMNWMMMMMMMMMM0: + $2.KMMMMMMMMMMMMMMMMMMMMMMMWd. + XMMMMMMMMMMMMMMMMMMMMMMMX. +$3;MMMMMMMMMMMMMMMMMMMMMMMM: +:MMMMMMMMMMMMMMMMMMMMMMMM: +.MMMMMMMMMMMMMMMMMMMMMMMMX. + kMMMMMMMMMMMMMMMMMMMMMMMMWd. + $4'XMMMMMMMMMMMMMMMMMMMMMMMMMMk + 'XMMMMMMMMMMMMMMMMMMMMMMMMK. + $5kMMMMMMMMMMMMMMMMMMMMMMd + ;KMMMMMMMWXXWMMMMMMMk. + "cooc*" "*coo'" \ No newline at end of file diff --git a/src/logo/ascii/macos2.txt b/src/logo/ascii/macos2.txt new file mode 100644 index 0000000000..af4248e11c --- /dev/null +++ b/src/logo/ascii/macos2.txt @@ -0,0 +1,17 @@ + $1..' + ,xN . + .O o + l " + .;loddo:. .olloddol;. + cK NW 0: + $2.K Wd. + X X. +$3; : +: : +. X. + k Wd. + $4'X k + 'X K. + $5k d + ;K WXXW k. + "cooc*" "*coo'" \ No newline at end of file diff --git a/src/logo/ascii/macos2_small.txt b/src/logo/ascii/macos2_small.txt new file mode 100644 index 0000000000..bb108fda78 --- /dev/null +++ b/src/logo/ascii/macos2_small.txt @@ -0,0 +1,7 @@ +$1 .:' + __ :'__ +$2 .'` `-' ``. +$3: .-' +$4: : + : `-; +$5 `.__.-.__.' \ No newline at end of file diff --git a/src/logo/ascii/macos_small.txt b/src/logo/ascii/macos_small.txt new file mode 100644 index 0000000000..2d90ee3e46 --- /dev/null +++ b/src/logo/ascii/macos_small.txt @@ -0,0 +1,7 @@ +$1 .:' + __ :'__ +$2 .'`__`-'__``. +$3:__________.-' +$4:_________: + :_________`-; +$5 `.__.-.__.' \ No newline at end of file diff --git a/src/logo/ascii/mageia.txt b/src/logo/ascii/mageia.txt new file mode 100644 index 0000000000..cd2566debd --- /dev/null +++ b/src/logo/ascii/mageia.txt @@ -0,0 +1,19 @@ + .°°. + °° .°°. + .°°°. °° + . . + °°° .°°°. + .°°°. '___' +${c2} .${c1}'___' ${c2} . + :dkxc;'. ..,cxkd; + .dkk. kkkkkkkkkk .kkd. +.dkk. ';cloolc;. .kkd +ckk. .kk; +xO: cOd +xO: lOd +lOO. .OO: +.k00. .00x + .k00; ;00O. + .lO0Kc;,,,,,,;c0KOc. + ;d00KKKKKK00d; + .,KKKK,. diff --git a/src/logo/ascii/mageia_small.txt b/src/logo/ascii/mageia_small.txt new file mode 100644 index 0000000000..84bf0dc4cb --- /dev/null +++ b/src/logo/ascii/mageia_small.txt @@ -0,0 +1,7 @@ + * + * + ** +${c2} /\\__/\\ +/ \\ +\\ / + \\____/ diff --git a/src/logo/ascii/magpieos.txt b/src/logo/ascii/magpieos.txt new file mode 100644 index 0000000000..20da686504 --- /dev/null +++ b/src/logo/ascii/magpieos.txt @@ -0,0 +1,20 @@ + ;00000 :000Ol + .x00kk00: O0kk00k; + l00: :00. o0k :O0k. + .k0k. x${c2}d$dddd${c1}k' .d00; + k0k. ${c2}.dddddl ${c1}o00, + o00. ${c2}':cc:. ${c1}d0O +.00l ,00. +l00. d0x +k0O .:k0o +O0k ;dO0000d. +k0O .O0O${c2}xxxxk${c1}00: +o00. k0O${c2}dddddd${c1}occ +'00l x0O${c2}dddddo${c3};..${c1} + x00. .x00${c2}kxxd${c3}:..${c1} + .O0x .:oxxx${c4}Okl.${c1} + .x0d ${c4},xx,${c1} + .:o. ${c4}.xd ckd${c1} + .. ${c4}dxl .xx; + :xxolldxd' + ;oxdl. diff --git a/src/logo/ascii/mandriva.txt b/src/logo/ascii/mandriva.txt new file mode 100644 index 0000000000..635d1b1a64 --- /dev/null +++ b/src/logo/ascii/mandriva.txt @@ -0,0 +1,15 @@ +$2 `` + `-. +$1 ` $2.--- +$1 -/ $2-::--` +$1 `++ $2`----...```-:::::. +$1 `os. $2.::::::::::::::-``` ` ` +$1 +s+ $2.::::::::::::::::---...--` +$1-ss: $2`-::::::::::::::::-.``.`` +$1/ss- $2.::::::::::::-.`` ` +$1+ss: $2.::::::::::::- +$1/sso $2.::::::-::::::- +$1.sss/ $2-:::-.` .::::: +$1 /sss+. $2..`$1 `--` $2.::: +$1 -ossso+/:://+/-` $2.:` +$1 -/+ooo+/-. $2` \ No newline at end of file diff --git a/src/logo/ascii/manjaro.txt b/src/logo/ascii/manjaro.txt new file mode 100644 index 0000000000..7f35123e22 --- /dev/null +++ b/src/logo/ascii/manjaro.txt @@ -0,0 +1,14 @@ +██████████████████ ████████ +██████████████████ ████████ +██████████████████ ████████ +██████████████████ ████████ +████████ ████████ +████████ ████████ ████████ +████████ ████████ ████████ +████████ ████████ ████████ +████████ ████████ ████████ +████████ ████████ ████████ +████████ ████████ ████████ +████████ ████████ ████████ +████████ ████████ ████████ +████████ ████████ ████████ \ No newline at end of file diff --git a/src/logo/ascii/manjaro_small.txt b/src/logo/ascii/manjaro_small.txt new file mode 100644 index 0000000000..e6aceacdb6 --- /dev/null +++ b/src/logo/ascii/manjaro_small.txt @@ -0,0 +1,7 @@ +||||||||| |||| +||||||||| |||| +|||| |||| +|||| |||| |||| +|||| |||| |||| +|||| |||| |||| +|||| |||| |||| \ No newline at end of file diff --git a/src/logo/ascii/massos.txt b/src/logo/ascii/massos.txt new file mode 100644 index 0000000000..5cc4e796f2 --- /dev/null +++ b/src/logo/ascii/massos.txt @@ -0,0 +1,18 @@ +-+++/+++osyyhdmNNMMMMNdy/ +/MMMMMMMMMMMMMMMMMMMMMMMMm. +/MMMMMMMMMMMMMMMMMMMMMMMMMm +/MMMMMMMMMMMMMMMMMMMMMMMMMM: +:ddddddddhddddddddhdddddddd/ +/NNNNNNNm:NNNNNNNN-NNNNNNNNo +/MMMMMMMN:MMMMMMMM-MMMMMMMMs +/MMMMMMMN:MMMMMMMM-MMMMMMMMs +/MMMMMMMN:MMMMMMMM-MMMMMMMMs +/MMMMMMMN:MMMMMMMM-MMMMMMMMs +/MMMMMMMN:MMMMMMMM-MMMMMMMMs +/MMMMMMMN:MMMMMMMM-MMMMMMMMs +/MMMMMMMN:MMMMMMMM-MMMMMMMMs +/MMMMMMMN:MMMMMMMM-MMMMMMMMs +:MMMMMMMN:MMMMMMMM-MMMMMMMMs + dMMMMMMN:MMMMMMMM-MMMMMMMMs + `yNMMMMN:MMMMMMMM-MMMMMMMMs + `:+oss.ssssssss.ssssssss/ diff --git a/src/logo/ascii/matuusos.txt b/src/logo/ascii/matuusos.txt new file mode 100644 index 0000000000..bf7505daec --- /dev/null +++ b/src/logo/ascii/matuusos.txt @@ -0,0 +1,20 @@ +░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ +░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ +░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ +░░░░░░░░░░░░░░░░▒▓▓████▓▒▒░░░░░░░░░░░░░░░░ +░░░░░░░░░░░░░▒▓████████████▓░░░░░░░░░░░░░░ +░░░░░░░░░░░░▓████████████████▒░░░░░░░░░░░░ +░░░░░░░░░░░▓██████████████████▒░░░░░░░░░░░ +░░░░░░░░░░▓████▒▓███████▓▓█████░░░░░░░░░░░ +░░░░░░░░░░██████▓░▓████▒░██████▓░░░░░░░░░░ +░░░░░░░░░▒███████▓░▒▓▒░░████████░░░░░░░░░░ +░░░░░░░░░▒█████████▒░░░█████████░░░░░░░░░░ +░░░░░░░░░░██████████▓▒██████████░░░░░░░░░░ +░░░░░░░░░░▓████████████████████▒░░░░░░░░░░ +░░░░░░░░░░░███████████████████▓░░░░░░░░░░░ +░░░░░░░░░░░░█████████████████▓░░░░░░░░░░░░ +░░░░░░░░░░░░░▓██████████████▒░░░░░░░░░░░░░ +░░░░░░░░░░░░░░░▒▓████████▓░░░░░░░░░░░░░░░░ +░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ +░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ +░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ diff --git a/src/logo/ascii/maui.txt b/src/logo/ascii/maui.txt new file mode 100644 index 0000000000..650371f48e --- /dev/null +++ b/src/logo/ascii/maui.txt @@ -0,0 +1,20 @@ + `.-://////:--` + .:/oooooooooooooooo+:. + `:+ooooooooooooooooooooooo:` + `:oooooooooooooooooooooooooooo/` + ..```-oooooo/-`` `:oooooo+:.` `-- + :. +oo+-` /ooo/` -/ + -o. `o+- +o/` -o: +`oo` ::` :o/ `+. .+o` /oo. +/o+ . -+oo- ` /oo/ `ooo/ ++o- /ooo+` .+ooo. :ooo+ +++ .+oooo: -oooo+ `oooo+ +:. .oooooo` :ooooo- :oooo: +` .oooooo: :ooooo+ `ooo+-` + .+oooooo` -oooooo: `o/- + +oooooo: .ooooooo. + /ooooooo` /ooooooo/ .. + `:oooooooo/:::/ooooooooo+:--:/:` + `:+oooooooooooooooooooooo+:` + .:+oooooooooooooooo+:. + `.-://////:-.` diff --git a/src/logo/ascii/meowix.txt b/src/logo/ascii/meowix.txt new file mode 100644 index 0000000000..73682942a6 --- /dev/null +++ b/src/logo/ascii/meowix.txt @@ -0,0 +1,10 @@ +${c1} #${c2}% ${c3}&${c4}* +${c1} ##${c2}%% ${c3}&&${c4}** +${c1} ## ${c2}%% ${c3}&& ${c4}** +${c1} ## ${c2}%% ${c3}&& ${c4}** +${c1} ## ${c2}%% ${c3}&& ${c4}** +${c1} ## ${c2}%% ${c3}&& ${c4}** +${c1} ## ${c2}%%${c3}&& ${c4}** +${c1} ## ${c2}%% ${c4}** +${c1} ## ${c4}** +${c1}## ${c4}** diff --git a/src/logo/ascii/mer.txt b/src/logo/ascii/mer.txt new file mode 100644 index 0000000000..11cdca1c4f --- /dev/null +++ b/src/logo/ascii/mer.txt @@ -0,0 +1,27 @@ + dMs + .-` + `y`-o+` + ``NMMy + .--`:++. + .hNNNNs + /MMMMMN + `ommmd/ +/ + ```` +/ + `:+sssso/-` + .-::. `-::-` `smNMNmdmNMNd/ .://-` +.ymNMNNdmNMMNm+` -dMMh:.....+dMMs `sNNMMNo +dMN+::NMMy::hMM+ mMMo `ohhy/ `dMM+ yMMy::- +MMm yMM- :MMs NMN` `:::::--sMMh dMM` +MMm yMM- -MMs mMM+ `ymmdsymMMMs dMM` +NNd sNN- -NNs -mMNs-.--..:dMMh` dNN +--- .--` `--. .smMMmdddmMNdo` .-- + ./ohddds+:` + +h- `.:-. + ./`.dMMMN+ + +MMMMMd + `+dmmy- + ``` .+` + .dMNo-y. + `hmm/ + .:` + dMs diff --git a/src/logo/ascii/minix.txt b/src/logo/ascii/minix.txt new file mode 100644 index 0000000000..da32a8eb06 --- /dev/null +++ b/src/logo/ascii/minix.txt @@ -0,0 +1,17 @@ +$2 -sdhyo+:-` -/syymm: + sdyooymmNNy. `` .smNmmdysNd + odyoso+syNNmysoyhhdhsoomNmm+/osdm/ + :hhy+-/syNNmddhddddddmNMNo:sdNd: + `smNNdNmmNmddddddddddmmmmmmmy` + `ohhhhdddddmmNNdmddNmNNmdddddmdh- + odNNNmdyo/:/-/hNddNy-`..-+ydNNNmd: + `+mNho:` smmd/ sNNh :dmms` -+ymmo. +-od/ -m$1mm$2mo -NN+ +m$1mm$2m- yms: ++sms -.` :so: .NN+ :os/ .-`mNh: +.-hyh+:////- -sNNd:` .--://ohNs- + `:hNNNNNNNMMd/sNMmhsdMMh/ymmNNNmmNNy/ + -+sNNNNMMNNNsmNMo: :NNmymNNNNMMMms: + //oydNMMMMydMMNysNMMmsMMMMMNyo/` + ../-yNMMy--/::/-.sMMmos+.` + -+oyhNsooo+omy/``` + `::ohdmds-` \ No newline at end of file diff --git a/src/logo/ascii/mint.txt b/src/logo/ascii/mint.txt new file mode 100644 index 0000000000..ed7e6f4c6d --- /dev/null +++ b/src/logo/ascii/mint.txt @@ -0,0 +1,19 @@ + $2...-:::::-... + .-MMMMMMMMMMMMMMM-. + .-MMMM$1`..-:::::::-..`$2MMMM-. + .:MMMM$1.:MMMMMMMMMMMMMMM:.$2MMMM:. + -MMM$1-M---MMMMMMMMMMMMMMMMMMM.$2MMM- + `:MMM$1:MM` :MMMM:....::-...-MMMM:$2MMM:` + :MMM$1:MMM` :MM:` `` `` `:MMM:$2MMM: +.MMM$1.MMMM` :MM. -MM. .MM- `MMMM.$2MMM. +:MMM$1:MMMM` :MM. -MM- .MM: `MMMM-$2MMM: +:MMM$1:MMMM` :MM. -MM- .MM: `MMMM:$2MMM: +:MMM$1:MMMM` :MM. -MM- .MM: `MMMM-$2MMM: +.MMM$1.MMMM` :MM:--:MM:--:MM: `MMMM.$2MMM. + :MMM$1:MMM- `-MMMMMMMMMMMM-` -MMM-$2MMM: + :MMM$1:MMM:` `:MMM:$2MMM: + .MMM$1.MMMM:--------------:MMMM.$2MMM. + '-MMMM$1.-MMMMMMMMMMMMMMM-.$2MMMM-' + '.-MMMM$1``--:::::--``$2MMMM-.' + '-MMMMMMMMMMMMM-' + ``-:::::-`` \ No newline at end of file diff --git a/src/logo/ascii/mint_old.txt b/src/logo/ascii/mint_old.txt new file mode 100644 index 0000000000..e94eca0c2f --- /dev/null +++ b/src/logo/ascii/mint_old.txt @@ -0,0 +1,16 @@ +MMMMMMMMMMMMMMMMMMMMMMMMMmds+. +MMm----::-://////////////oymNMd+` +MMd $2/++ $1-sNMd: +MMNso/` $2dMM `.::-. .-::.` $1.hMN: +ddddMMh $2dMM :hNMNMNhNMNMNh: $1`NMm + NMm $2dMM .NMN/-+MMM+-/NMN` $1dMM + NMm $2dMM -MMm `MMM dMM. $1dMM + NMm $2dMM -MMm `MMM dMM. $1dMM + NMm $2dMM .mmd `mmm yMM. $1dMM + NMm $2dMM` ..` ... ydm. $1dMM + hMM- $2+MMd/-------...-:sdds $1dMM + -NMm- $2:hNMNNNmdddddddddy/` $1dMM + -dMNs-$2``-::::-------.`` $1dMM + `/dMNmy+/:-------------:/yMMM + ./ydNMMMMMMMMMMMMMMMMMMMMM + .MMMMMMMMMMMMMMMMMMM \ No newline at end of file diff --git a/src/logo/ascii/mint_small.txt b/src/logo/ascii/mint_small.txt new file mode 100644 index 0000000000..9d294e0df5 --- /dev/null +++ b/src/logo/ascii/mint_small.txt @@ -0,0 +1,7 @@ + __________ +|_ \ + | $2| _____ $1| + | $2| | | | $1| + | $2| | | | $1| + | $2\__$2___/ $1| + \_________/ \ No newline at end of file diff --git a/src/logo/ascii/miracle_linux.txt b/src/logo/ascii/miracle_linux.txt new file mode 100644 index 0000000000..f7d0219773 --- /dev/null +++ b/src/logo/ascii/miracle_linux.txt @@ -0,0 +1,16 @@ + ,A + .### + .#' .#### .#. + r##: :#### ####. + +###; :#### ######C + :####: #### ,######".#. +.# :####. :### #####'.#####. +##: `####. ### ###'.########+. +#### `####::## ##'.#######+' + ####+.`###i## #',####:' + `+###MI`##### 'l###:' + `+####+`### ;#E' + `+###:## #' + `:### ' + '## + '; diff --git a/src/logo/ascii/msys2.txt b/src/logo/ascii/msys2.txt new file mode 100644 index 0000000000..32a7ed32ee --- /dev/null +++ b/src/logo/ascii/msys2.txt @@ -0,0 +1,25 @@ +$2 ... + 5GB###GJ. !YPGGGG + 7@@@@@@@B. :G@@@@@@@ + 7@@@@@@@@Y ~&@@@@@@@@$3YJYY5YY?L + $2!@@@@@@@@@@^ ^&@@@@@@@$3#PP555555PBY + $2~&@@@@@@@@@@? ^&@@@@@@$3#5YY5YYYYYYYY#7 + $2^&@@@@@@@@@@@B :#@@@@@@@$3G5BBYGPYYYYYY#J + $2^#@@@&J#@@@@@@@~ .B@@@@@@@@@@@P $3?#YYYYYPB. + $2:#@@@@7 G@@@@@@@J P@@@#!&@@@@@@G$3.GGYYYYGB^ + $2:#@@@@J Y@@@@@@@B 5@@@&:.&@@@@@@&$3BBYYY5B5. + $2:#@@@@Y !@@@@@@@@!Y@@@&~ .#@@@@@@$3GYYYYYBP JP~ + $2:#@@@@P :&@@@@@@@@@@@&~ B@@@@@$3#5YYYYYPGPGPGG + $2^#@@@@G. P@@@@@@@@@@@! P@@@@$3GYYYYYYYYYYYYBY + $2^#@@@@B: ^@@@@@@@@@@7 !@@@$3#GGGGGGGPPPP5GB: + $2!&@@@@B: Y@@@@@@@@? P@@@@@@@@@&? $3^PY: + $27&@@@@5. P@@@@@@? P@@@@@@@@@B + Y@@@&P! 5@@@@7 7G@@@@@&P~ +.JJ?~: ^JY~ ^!5J!^: + $1:@P5#B. #G 7&^ :@P5#B. + !&P^. ?@~ #P !&P^. + .?BG! #G5@~ .?BG! + :.B@. 7@@5 :.B@. + !PYY5Y :&@^ !PYY5Y + ~@Y + !5: \ No newline at end of file diff --git a/src/logo/ascii/mx.txt b/src/logo/ascii/mx.txt new file mode 100644 index 0000000000..b80cb098e7 --- /dev/null +++ b/src/logo/ascii/mx.txt @@ -0,0 +1,17 @@ +MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNMMMMMMMMM +MMMMMMMMMMNs..yMMMMMMMMMMMMMm: +NMMMMMMM +MMMMMMMMMN+ :mMMMMMMMMMNo` -dMMMMMMMM +MMMMMMMMMMMs. `oNMMMMMMh- `sNMMMMMMMMM +MMMMMMMMMMMMN/ -hMMMN+ :dMMMMMMMMMMM +MMMMMMMMMMMMMMh- +ms. .sMMMMMMMMMMMMM +MMMMMMMMMMMMMMMN+` ` +NMMMMMMMMMMMMMM +MMMMMMMMMMMMMMNMMd: .dMMMMMMMMMMMMMMM +MMMMMMMMMMMMm/-hMd- `sNMMMMMMMMMMMMM +MMMMMMMMMMNo` -` :h/ -dMMMMMMMMMMMM +MMMMMMMMMd: /NMMh- `+NMMMMMMMMMM +MMMMMMMNo` :mMMN+` `-hMMMMMMMM +MMMMMMh. `oNMMd: `/mMMMMMM +MMMMm/ -hMd- `sNMMMM +MMNs` - :dMMM +Mm: `oMM +MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM diff --git a/src/logo/ascii/mx_small.txt b/src/logo/ascii/mx_small.txt new file mode 100644 index 0000000000..b12cdd4743 --- /dev/null +++ b/src/logo/ascii/mx_small.txt @@ -0,0 +1,7 @@ + \\\\ / + \\\\/ + \\\\ + /\\/ \\\\ + / \\ /\\ + / \\/ \\ +/__________\\ diff --git a/src/logo/ascii/namib.txt b/src/logo/ascii/namib.txt new file mode 100644 index 0000000000..ee4ff6ba85 --- /dev/null +++ b/src/logo/ascii/namib.txt @@ -0,0 +1,20 @@ + .:+shysyhhhhysyhs+:. + -/yyys syyy/- + -shy yhs- + -yhs shy- + +hy yh+ + +ds sd+ +/ys so sy/ +sh smMMNdyo hs +yo ymMMMMNNMMNho oy +N ydMMMNNMMMMMMMMMmy N +N shmMMMMNNMMMMMMMMMMMMMNy N +yo ooshmNMMMNNNNMMMMMMMMMMMMMMMMMms oy +sd yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy ds +/ys sy/ + +ds sd+ + +hy yh+ + -yhs shy- + -shy yhs- + -/yyys syyy/- + .:+shysyhyhhysyhs+:. diff --git a/src/logo/ascii/nekos.txt b/src/logo/ascii/nekos.txt new file mode 100644 index 0000000000..8dfeb3c3e9 --- /dev/null +++ b/src/logo/ascii/nekos.txt @@ -0,0 +1,23 @@ + @@@@@ + @@@@@@@@@. + @@@@@@@@ @@@ + @@@@@@@@@@@ @@. + @@@@@@@@@@@@@ . + @@@@@@@@@@@@@@@@@ , + @@@@@@@@@@@@@@@@@@@ + @@@@@${c2}///${c1}@@@@@@@${c2}///${c1}@@@ + @@@@${c2}/***${c1}@@@@@@@${c2}**//${c1}@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@ + @@@/ /@@@@@@@@@/ /@@@ + @@@@@@ @@@${c3}██${c1}@@@@ @@@@@@ + @@@@@@/ /@${c2}██${c3}██${c2}██${c1}@@/ /@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@ + ##########%%%% + ##########%% %% + @ @@@#######@@%%% + @@@ @@@@####@@@@ % + @@@ @@@@@@@#@@@@@@@ + @@@ @@@@@@@@@@@@@@@ + @@@@ @@@@@@@@@@@@@@@@@ + @@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/src/logo/ascii/neptune.txt b/src/logo/ascii/neptune.txt new file mode 100644 index 0000000000..b88d03169f --- /dev/null +++ b/src/logo/ascii/neptune.txt @@ -0,0 +1,17 @@ + ./+sydddddddys/-. + .+ymNNdyooo/:+oooymNNmy/` + `/hNNh/.` `-+dNNy:` + /mMd/. .++.:oy/ .+mMd- + `sMN/ oMMmdy+. `oNNo + `hMd. `/ymy/. :NMo + oMN- `/dMd: /MM- +`mMy -dMN+` mMs +.MMo -NMM/ yMs + dMh mMMMo:` `NMo + /MM/ /ymMMMm- sMN. + +Mm: .hMMd` oMN/ + +mNs. `yNd/` -dMm- + .yMNs: `/.` `/yNNo` + .odNNy+-` .:ohNNd/. + -+ymNNmdyyyyyyydmNNmy+. + `-//sssssss//. diff --git a/src/logo/ascii/netbsd.txt b/src/logo/ascii/netbsd.txt new file mode 100644 index 0000000000..6308771de4 --- /dev/null +++ b/src/logo/ascii/netbsd.txt @@ -0,0 +1,17 @@ +$1 `-/oshdmNMNdhyo+:-` +$2y$1/s+:-`` `.-:+oydNMMMMNhs/-`` +$2-m+$1NMMMMMMMMMMMMMMMMMMMNdhmNMMMmdhs+/-` + $2-m+$1NMMMMMMMMMMMMMMMMMMMMmy+:` + $2-N/$1dMMMMMMMMMMMMMMMds:` + $2-N/$1hMMMMMMMMMmho:` + $2-N/$1-:/++/:.` +$2 :M+ + :Mo + :Ms + :Ms + :Ms + :Ms + :Ms + :Ms + :Ms + :Ms \ No newline at end of file diff --git a/src/logo/ascii/netrunner.txt b/src/logo/ascii/netrunner.txt new file mode 100644 index 0000000000..abbaef9bd0 --- /dev/null +++ b/src/logo/ascii/netrunner.txt @@ -0,0 +1,20 @@ + .:oydmMMMMMMmdyo:` + -smMMMMMMMMMMMMMMMMMMds- + +mMMMMMMMMMMMMMMMMMMMMMMMMd+ + /mMMMMMMMMMMMMMMMMMMMMMMMMMMMMm/ + `hMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMy` + .mMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMd` + dMMMMMMMMMMMMMMMMMMMMMMNdhmMMMMMMMMMMh ++MMMMMMMMMMMMMNmhyo+/-. -MMMMMMMMMMMM/ +mMMMMMMMMd+:.` `mMMMMMMMMMMMMd +MMMMMMMMMMMdy/. yMMMMMMMMMMMMMM +MMMMMMMMMMMMMMMNh+` +MMMMMMMMMMMMMMM +mMMMMMMMMMMMMMMMMMs -NMMMMMMMMMMMMMMd ++MMMMMMMMMMMMMMMMMN. `mMMMMMMMMMMMMMMM/ + dMMMMMMMMMMMMMMMMMy hMMMMMMMMMMMMMMMh + `dMMMMMMMMMMMMMMMMM-+MMMMMMMMMMMMMMMd` + `hMMMMMMMMMMMMMMMMmMMMMMMMMMMMMMMMy + /mMMMMMMMMMMMMMMMMMMMMMMMMMMMMm: + +dMMMMMMMMMMMMMMMMMMMMMMMMd/ + -odMMMMMMMMMMMMMMMMMMdo- + `:+ydmNMMMMNmhy+-` diff --git a/src/logo/ascii/nitrux.txt b/src/logo/ascii/nitrux.txt new file mode 100644 index 0000000000..c27c023565 --- /dev/null +++ b/src/logo/ascii/nitrux.txt @@ -0,0 +1,18 @@ +`:/. +`/yo +`/yo +`/yo .+:. +`/yo .sys+:.` +`/yo `-/sys+:.` +`/yo ./sss+:.` +`/yo .:oss+:-` +`/yo ./o///:-` +`/yo `.-:///////:` +`/yo `.://///++//-`` +`/yo `.-:////++++/-` +`/yo `-://///++o+/-` +`/yo `-/+o+++ooo+/-` +`/s+:+oooossso/.` +`//+sssssso:. +`+syyyy+:` +:+s+- diff --git a/src/logo/ascii/nixos.txt b/src/logo/ascii/nixos.txt new file mode 100644 index 0000000000..7bbf9b63aa --- /dev/null +++ b/src/logo/ascii/nixos.txt @@ -0,0 +1,20 @@ +$1 ▗▄▄▄ $2▗▄▄▄▄ ▄▄▄▖ +$1 ▜███▙ $2▜███▙ ▟███▛ +$1 ▜███▙ $2▜███▙▟███▛ +$1 ▜███▙ $2▜██████▛ +$1 ▟█████████████████▙ $2▜████▛ $1▟▙ +$1 ▟███████████████████▙ $2▜███▙ $1▟██▙ +$2 ▄▄▄▄▖ ▜███▙ $1▟███▛ +$2 ▟███▛ ▜██▛ $1▟███▛ +$2 ▟███▛ ▜▛ $1▟███▛ +$2▟███████████▛ $1▟██████████▙ +$2▜██████████▛ $1▟███████████▛ +$2 ▟███▛ $1▟▙ ▟███▛ +$2 ▟███▛ $1▟██▙ ▟███▛ +$2 ▟███▛ $1▜███▙ ▝▀▀▀▀ +$2 ▜██▛ $1▜███▙ $2▜██████████████████▛ +$2 ▜▛ $1▟████▙ $2▜████████████████▛ +$1 ▟██████▙ $2▜███▙ +$1 ▟███▛▜███▙ $2▜███▙ +$1 ▟███▛ ▜███▙ $2▜███▙ +$1 ▝▀▀▀ ▀▀▀▀▘ $2▀▀▀▘ \ No newline at end of file diff --git a/src/logo/ascii/nixos_old.txt b/src/logo/ascii/nixos_old.txt new file mode 100644 index 0000000000..3b26708033 --- /dev/null +++ b/src/logo/ascii/nixos_old.txt @@ -0,0 +1,28 @@ +$1 ____ $2_______ ____ +$1 /####\ $2\######\ /####\ +$1 ######\ $2\######\ /#####/ +$1 \######\ $2\######\ /#####/ +$1 \######\ $2\######\/#####/ $1/\ +$1 \######\ $2\###########/ $1/##\ +$1 ________\######\______$2\#########/ $1/####\ +$1 /#######################$2\#######/ $1/###### +$1 /#########################$2\######\ $1/######/ +$1 /###########################$2\######\ $1/######/ +$1 ¯¯¯¯¯¯¯¯¯¯¯¯$2/######/$1¯¯¯¯¯¯¯¯¯$2\######$1/######/ +$2 /######/ $2\####$1/######/________ +$2 _____________/######/ $2\##$1/################\ +$2 /###################/ $2\$1/##################\ +$2 \##################/$1\ /###################/ +$2 \################/$1##\ /######/¯¯¯¯¯¯¯¯¯¯¯¯¯ +$2 ¯¯¯¯¯¯¯¯/######/$1####\ /######/ +$2 /######/$1######\$2_________$1/######/$2____________ +$2 /######/ $1\######\$2###########################/ +$2 /######/ $1\######\$2#########################/ +$2 ######/ $1/#######\$2#######################/ +$2 \####/ $1/#########\$2¯¯¯¯¯¯\######\¯¯¯¯¯¯¯¯ +$2 \##/ $1/###########\$2 \######\ +$2 \/ $1/#####/\######\$2 \######\ +$1 $1/#####/ \######\$2 \######\ +$1 $1/#####/ \######\$2 \###### +$1 $1\####/ \######\$2 \####/ +$1 $1¯¯¯¯ ¯¯¯¯¯¯¯$2 ¯¯¯¯ \ No newline at end of file diff --git a/src/logo/ascii/nixos_small.txt b/src/logo/ascii/nixos_small.txt new file mode 100644 index 0000000000..be1b628a3f --- /dev/null +++ b/src/logo/ascii/nixos_small.txt @@ -0,0 +1,7 @@ + \\ \\ // + ==\\__\\/ // + // \\// +==// //== + //\\___// +// /\\ \\== + // \\ \\ diff --git a/src/logo/ascii/nobara.txt b/src/logo/ascii/nobara.txt new file mode 100644 index 0000000000..dd05b8bb70 --- /dev/null +++ b/src/logo/ascii/nobara.txt @@ -0,0 +1,17 @@ +⢀⣤⣴⣶⣶⣶⣦⣤⡀⠀⣀⣠⣤⣴⣶⣶⣶⣶⣶⣶⣶⣶⣤⣤⣀⡀ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⡀ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⠉⠁⠀⠀⠉⠉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⢀⣀⣀⡀⠀⠀⠀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠀⢠⣾⣿⣿⣿⣿⣷⡄⠀⠀⠀⠻⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⣀⣀⣬⣽⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠈⠻⢿⣿⣿⡿⠟⠁⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⣤⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠛⠉⠉⠛⠛⢿⣿⣿⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿ +⠘⢿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⠟⠁ + ⠈⠙⠛⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠛⠛⠛⠉⠁ diff --git a/src/logo/ascii/nomadbsd.txt b/src/logo/ascii/nomadbsd.txt new file mode 100644 index 0000000000..e30917e7a8 --- /dev/null +++ b/src/logo/ascii/nomadbsd.txt @@ -0,0 +1,13 @@ + _======__ + (===============\\ + (===================\\ + _ _---__ + (= ====- + (= ====== + (== ====== + (== ====== + (==\\ \\=-_ _=/ /====/ + (==\\ \\========/ /====/ /====-_ + (==\\ \\=====/ /==/ /===-- +/================/ /===- +\\===========/ \ No newline at end of file diff --git a/src/logo/ascii/nurunner.txt b/src/logo/ascii/nurunner.txt new file mode 100644 index 0000000000..a4fa6c5241 --- /dev/null +++ b/src/logo/ascii/nurunner.txt @@ -0,0 +1,19 @@ + ,xc + ;00cxXl + ;K0, .xNo. + :KO' .lXx. + cXk. ;xl cXk. + cXk. ;k:.,xo. cXk. + .lXx. :x::0MNl,dd. :KO, + .xNx. cx;:KMMMMMNo'dx. ;KK; + .dNl. cd,cXMMMMMMMMMWd,ox' 'OK: +;WK. 'K,.KMMMMMMMMMMMMMWc.Kx lMO + 'OK: 'dl'xWMMMMMMMMMM0::x: 'OK: + .kNo .xo'xWMMMMMM0;:O: ;KK; + .dXd. .do,oNMMO;ck: ;00, + oNd. .dx,;'cO; ;K0, + oNx. okk; ;K0, + lXx. :KO' + cKk' cXk. + ;00:lXx. + ,kd. diff --git a/src/logo/ascii/nutyx.txt b/src/logo/ascii/nutyx.txt new file mode 100644 index 0000000000..6adc33fa75 --- /dev/null +++ b/src/logo/ascii/nutyx.txt @@ -0,0 +1,23 @@ + . + . + ... + ... + .... .........--. + ..-++-----....--++++++---. + .-++++++-. .-++++++++++++-----.. + .--... .++..-+++--.....-++++++++++--.. + . .-+-. .**- .... ..-+----.. + .+++. .*+. + -++-----. + .+++++- ++. .*+. .....-+++-----. + -+++-++. .+. .-+***++***++--++++. . + -+-. -- -. -*- ...... ..--. +.-. .+- . -+. +. .+- +. + -- -- + -+----. .- + -++-.+. . + .++. -- + +. ----. + . .+. .. + - . + . diff --git a/src/logo/ascii/obarun.txt b/src/logo/ascii/obarun.txt new file mode 100644 index 0000000000..2e57389d48 --- /dev/null +++ b/src/logo/ascii/obarun.txt @@ -0,0 +1,19 @@ + ,;::::; + ;cooolc;, + ,coool; + ,loool, + loooo; + :ooool + cooooc ,:ccc; + looooc :oooooool + cooooo ;oooooooooo, + :ooooo; :ooooooooooo + oooooo oooooooooooc +:oooooo :ooooooooool +loooooo ;oooooooool +looooooc .coooooooc +cooooooo: ,;co; +,ooooooool; ,:loc + cooooooooooooloooooc + ;ooooooooooooool; + ;looooooolc; diff --git a/src/logo/ascii/obrevenge.txt b/src/logo/ascii/obrevenge.txt new file mode 100644 index 0000000000..d561ad2175 --- /dev/null +++ b/src/logo/ascii/obrevenge.txt @@ -0,0 +1,18 @@ + __ __ + _@@@@ @@@g_ + _@@@@@@ @@@@@@ + _@@@@@@M W@@@@@@_ + j@@@@P ^W@@@@ + @@@@L____ _____Q@@@@ +Q@@@@@@@@@@j@@@@@@@@@@ +@@@@@ T@j@ T@@@@@ +@@@@@ ___Q@J@ _@@@@@ +@@@@@fMMM@@j@jggg@@@@@@ +@@@@@ j@j@^MW@P @@@@ +Q@@@@@ggg@@f@ @@@@@@L +^@@@@WWMMP ^ Q@@@@ + @@@@@_ _@@@@l + W@@@@@g_____g@@@@@P + @@@@@@@@@@@@@@@@l + ^W@@@@@@@@@@@P + ^TMMMMTll diff --git a/src/logo/ascii/omnios.txt b/src/logo/ascii/omnios.txt new file mode 100644 index 0000000000..6852c5d9cb --- /dev/null +++ b/src/logo/ascii/omnios.txt @@ -0,0 +1,8 @@ + ____ __ __ _ _ _ + / __ \ | \/ || \ | || | +| | | || || \| || | +| |__| || |\/| || , `${c2}_${c1}||${c2}_${c1}| ${c2}____${c1} + \____/ |_| |_||_|\${c2}/ __ \ / ___| + | | | ||(__ + ${c3}community${c2} | |__| | ___)| + ${c3}edition${c2} \____/ |____/ diff --git a/src/logo/ascii/openbsd.txt b/src/logo/ascii/openbsd.txt new file mode 100644 index 0000000000..3a09b3af04 --- /dev/null +++ b/src/logo/ascii/openbsd.txt @@ -0,0 +1,23 @@ +$3 _ + (_) +$1 | . +$1 . |L /| . $3 _ +$1 _ . |\ _| \--+._/| . $3(_) +$1 / ||\| Y J ) / |/| ./ + J |)'( | ` F`.'/ $3 _ +$1 -<| F __ .-< $3(_) +$1 | / .-'$3. $1`. /$3-. $1L___ + J \\ < $3\ $1 | | $5O$3\\$1|.-' $3 _ +$1 _J \\ .- \\$3/ $5O $3| $1| \\ |$1F $3(_) +$1 '-F -<_. \\ .-' `-' L__ +__J _ _. >-' $1)$4._. $1|-' +$1 `-|.' /_. $4\_| $1 F + /.- . _.< + /' /.' .' `\\ + /L /' |/ _.-'-\\ + /'J ___.---'\| + |\ .--' V | `. ` + |/`. `-. `._) + / .-.\\ + \\ ( `\\ + `.\\ \ No newline at end of file diff --git a/src/logo/ascii/openbsd_small.txt b/src/logo/ascii/openbsd_small.txt new file mode 100644 index 0000000000..a96b2f1c15 --- /dev/null +++ b/src/logo/ascii/openbsd_small.txt @@ -0,0 +1,7 @@ +$1 _____ + \\- -/ + \\_/ \\ + | $2O O$1 | + |_ < ) 3 ) + / \\ / + /-_____-\\ \ No newline at end of file diff --git a/src/logo/ascii/openeuler.txt b/src/logo/ascii/openeuler.txt new file mode 100644 index 0000000000..38ec0c009a --- /dev/null +++ b/src/logo/ascii/openeuler.txt @@ -0,0 +1,23 @@ + `.cc.` + ``.cccccccc..` + `.cccccccccccccccc.` + ``.cccccccccccccccccccccc.`` + `..cccccccccccccccccccccccccccc..` +`.ccccccccccccccc${c2}/++/${c1}ccccccccccccccccc.` +.ccccccccccccccc${c2}mNMMNdo+oso+${c1}ccccccccccc. +.cccccccccc${c2}/++odms+//+mMMMMm/:+syso/${c1}cccc +.ccccccccc${c2}yNNMMMs:::/::+o+/:${c1}c${c2}dMMMMMm${c1}cccc +.ccccccc${c2}:+NmdyyhNNmNNNd:${c1}ccccc${c1}${c2}:oyyyo:${c1}cccc +.ccc${c2}:ohdmMs:${c1}cccc${c2}+mNMNmy${c1}ccccccccccccccccc +.cc${c2}/NMMMMMo////:${c1}c${c2}:///:${c1}cccccccccccccccccc +.cc${c2}:syysyNMNNNMNy${c1}ccccccccccccccccccccccc +.cccccccc${c2}+MMMMMNy${c1}c${c2}:/+++/${c1}cccccccccccccccc +.ccccccccc${c2}ohhhs/${c1}c${c2}omMMMMNh${c1}ccccccccccccccc +.ccccccccccccccc${c2}:MMMMMMMM/${c1}cccccccccccccc +.cccccccccccccccc${c2}sNNNNNd+${c1}cccccccccccccc. +`..cccccccccccccccc${c2}/+/:${c1}cccccccccccccc..` + ``.cccccccccccccccccccccccccccc.`` + `.cccccccccccccccccccccc.` + ``.cccccccccccccc.`` + `.cccccccc.` + `....` diff --git a/src/logo/ascii/openindiana.txt b/src/logo/ascii/openindiana.txt new file mode 100644 index 0000000000..c76d8f7ba4 --- /dev/null +++ b/src/logo/ascii/openindiana.txt @@ -0,0 +1,16 @@ +${c2} .sy/ + .yh+ + + ${c1}-+syyyo+- ${c2} /+. + ${c1}+ddo/---/sdh/ ${c2} ym- + ${c1}`hm+ `sms${c2} ym-```````.-. + ${c1}sm+ sm/ ${c2} ym- +s + ${c1}hm. /mo ${c2} ym- /h + ${c1}omo ym: ${c2} ym- `os` + ${c1}smo` .ym+ ${c2} ym- .os- + `` ${c1}:ymy+///oyms- ${c2} ym- .+s+. + ..` ${c1}`:+oo+/-` ${c2} -//oyo- + -:` .:oys/. ++- `./oyys/. +h+` `.-:+oyyyo/-` +`/ossssysso+/-.` diff --git a/src/logo/ascii/openkylin.txt b/src/logo/ascii/openkylin.txt new file mode 100644 index 0000000000..288e2b54d7 --- /dev/null +++ b/src/logo/ascii/openkylin.txt @@ -0,0 +1,18 @@ + + /KKK] + KKKKKKK` ]KKKK\ + KKKKK/ /KKKKKKKKK\ + KKKK/ ,KKKKKKKKKKKK^ + ,]KKK =KKK` /KKKKKKOOOOOO` +,KKKKKK =KK /` [\OOOOOOO\ + \KKKKK =K ,OOOOOOO` + ,KKKKK =^ \OOOOOO + ,KKKK ^ OOOOOO^ + *KKK^ =OOOOO^ + OOKK^ OOOOOO^ + \OOOK\ /OOOOOO` + OOOOOO] ,OOOOOOO^ + ,OOOOOOOO\] ,[OOOOOOOOO/ + \OOOOOOOOOOOOOOOOOOOOO` + [OOOOOOOOOOOOOOOO/` + ,[OOOOOOOOO] \ No newline at end of file diff --git a/src/logo/ascii/openmamba.txt b/src/logo/ascii/openmamba.txt new file mode 100644 index 0000000000..61bca9fbcb --- /dev/null +++ b/src/logo/ascii/openmamba.txt @@ -0,0 +1,21 @@ + ````` + .-/+ooooooooo+/:-` + ./ooooooooooooooooooo+:. + -+oooooooooooooooooooooooo+- + .+ooooooooo+/:---::/+ooooooooo+. + :oooooooo/-` `-/oo${c2}s´${c1}oooo.${c2}s´${c1} + :ooooooo/` `${c2}sNds${c1}ooo${c2}sNds${c1} + -ooooooo- ${c2}:dmy${c1}ooo${c2}:dmy${c1} + +oooooo: :oooooo- +.ooooooo .://:` +:oooooo+ ./+o+:` +-ooooooo` `oooooo+ +`ooooooo: /oooooo+ + -ooooooo: :ooooooo. + :ooooooo+. .+ooooooo: + :oooooooo+-` `-+oooooooo: + .+ooooooooo+/::::://oooooooooo+. + -+oooooooooooooooooooooooo+- + .:ooooooooooooooooooo+:. + `-:/ooooooooo+/:.` + `````` diff --git a/src/logo/ascii/openmandriva.txt b/src/logo/ascii/openmandriva.txt new file mode 100644 index 0000000000..7a036bbc1f --- /dev/null +++ b/src/logo/ascii/openmandriva.txt @@ -0,0 +1,22 @@ + `````` + `-:/+++++++//:-.` + .:+++oooo+/:.`` `` + `:+ooooooo+:. `-:/++++++/:.` + -+oooooooo:` `-++o+/::::://+o+/- + `/ooooooooo- -+oo/.` `-/oo+. + `+ooooooooo. :os/` .+so: + +sssssssss/ :ss/ `+ss- + :ssssssssss` sss` .sso + ossssssssss `yyo sys +`sssssssssss` `yys `yys +`sssssssssss: +yy/ +yy: + oyyyyyyyyyys. `oyy/` `+yy+ + :yyyyyyyyyyyo. `+yhs:. `./shy/ + oyyyyyyyyyyys:` .oyhys+:----/+syhy+. ` + `syyyyyyyyyyyyo-` .:osyhhhhhyys+:``.:` + `oyyyyyyyyyyyyys+-`` `.----.```./oo. + /yhhhhhhhhhhhhhhyso+//://+osyhy/` + `/yhhhhhhhhhhhhhhhhhhhhhhhhy/` + `:oyhhhhhhhhhhhhhhhhhhyo:` + .:+syhhhhhhhhys+:-` + ``....`` \ No newline at end of file diff --git a/src/logo/ascii/openstage.txt b/src/logo/ascii/openstage.txt new file mode 100644 index 0000000000..b113be8563 --- /dev/null +++ b/src/logo/ascii/openstage.txt @@ -0,0 +1,17 @@ + /(/ + .(((((((, + /(((((((((/ + .(((((/,/(((((, + *(((((* ,(((((/ + (((((* .*/(( + *((((/ (//(/* + /((((* ((((((((((, + . /((((* (((((((((((((. + ((. *((((/ ,(((((((( + ,(((/ (((((/ ** ,((((((* + /(((((. .(((((/ //(((* *(((((/ + .(((((, ((/ .(((((/. .(((((, + /((((* ,(((((((/ ,((((( + /(((((((((((((((((((/. /(((((((((/ + /(((((((((((((((((, /(((((((((((/ + */(((((//*. */((/(/(/* diff --git a/src/logo/ascii/opensuse.txt b/src/logo/ascii/opensuse.txt new file mode 100644 index 0000000000..a407c4bfbf --- /dev/null +++ b/src/logo/ascii/opensuse.txt @@ -0,0 +1,18 @@ + $2.;ldkO0000Okdl;. + .;d00xl:^''''''^:ok00d;. + .d00l' 'o00d. + .d0Kd'$1 Okxol:;,. $2:O0d + .OK$1KKK0kOKKKKKKKKKKOxo:, $2lKO. + ,0K$1KKKKKKKKKKKKKKK0P^$2,,,$1^dx:$2 ;00, +.OK$1KKKKKKKKKKKKKKKk'$2.oOPPb.$1'0k.$2 cKO. +:KK$1KKKKKKKKKKKKKKK: $2kKx..dd $1lKd$2 'OK: +dKK$1KKKKKKKKKOx0KKKd $2^0KKKO' $1kKKc$2 dKd +dKK$1KKKKKKKKKK;.;oOKx,..$2^$1..;kKKK0.$2 dKd +:KK$1KKKKKKKKKK0o;...^cdxxOK0O/^^' $2.0K: + kKK$1KKKKKKKKKKKKK0x;,,......,;od $2lKk + '0K$1KKKKKKKKKKKKKKKKKKKK00KKOo^ $2c00' + 'kK$1KKOxddxkOO00000Okxoc;'' $2.dKk' + l0Ko. .c00l' + 'l0Kk:. .;xK0l' + 'lkK0xl:;,,,,;:ldO0kl' + '^:ldxkkkkxdl:^' \ No newline at end of file diff --git a/src/logo/ascii/opensuse_leap.txt b/src/logo/ascii/opensuse_leap.txt new file mode 100644 index 0000000000..e0d8cddc82 --- /dev/null +++ b/src/logo/ascii/opensuse_leap.txt @@ -0,0 +1,16 @@ + .-++:. + ./oooooo/- + `:oooooooooooo:. + -+oooooooooooooooo+-` + ./oooooooooooooooooooooo/- + :oooooooooooooooooooooooooo: + ` `-+oooooooooooooooooooo/- ` + `:oo/- .:ooooooooooooooo+:` `-+oo/. +`/oooooo:. -/oooooooooo/. ./oooooo/. + `:+ooooo+-` `:+oooo+- `:oooooo+:` + .:oooooo/. .::` -+oooooo/. + -/oooooo:. ./oooooo+- + `:+ooooo+-:+oooooo:` + ./oooooooooo/. + -/oooo+:` + `:/. \ No newline at end of file diff --git a/src/logo/ascii/opensuse_small.txt b/src/logo/ascii/opensuse_small.txt new file mode 100644 index 0000000000..0099a02958 --- /dev/null +++ b/src/logo/ascii/opensuse_small.txt @@ -0,0 +1,7 @@ + _______ +__| __ \ + / .\ \ + \__/ | + _______| + \_______ +__________/ \ No newline at end of file diff --git a/src/logo/ascii/opensuse_tumbleweed.txt b/src/logo/ascii/opensuse_tumbleweed.txt new file mode 100644 index 0000000000..fefdeee4ad --- /dev/null +++ b/src/logo/ascii/opensuse_tumbleweed.txt @@ -0,0 +1,13 @@ + ...... + .,cdxxxoc,. .:kKMMMNWMMMNk:. + cKMMN0OOOKWMMXo. A ;0MWk:' ':OMMk. + ;WMK;' 'lKMMNM, :NMK' 'OMW; + cMW; WMMMN ,XMK' oMM. +.MMc ''^*~l. xMN: KM0 +'MM. .NMO oMM +.MM, .kMMl xMN + KM0 .kMM0' .dl>~,. .WMd + 'XM0. ,OMMK' OMMM7' .XMK + *WMO:. .;xNMMk' NNNMKl. .xWMx + ^ONMMNXMMMKx; V 'xNMWKkxllox0NMWk' + ''''' ':dOOXXKOxl' \ No newline at end of file diff --git a/src/logo/ascii/openwrt.txt b/src/logo/ascii/openwrt.txt new file mode 100644 index 0000000000..47e4e1944e --- /dev/null +++ b/src/logo/ascii/openwrt.txt @@ -0,0 +1,9 @@ + _______ +| |.-----.-----.-----. +| - || _ | -__| | +|_______|| __|_____|__|__| + |__| + ________ __ +| | | |.----.| |_ +| | | || _|| _| +|________||__| |____| \ No newline at end of file diff --git a/src/logo/ascii/opnsense.txt b/src/logo/ascii/opnsense.txt new file mode 100644 index 0000000000..4e62c7e899 --- /dev/null +++ b/src/logo/ascii/opnsense.txt @@ -0,0 +1,20 @@ + .''''''''''''''''''''''''''''''''''' + oocc:::::::::::::::::::::::::::::::cox + ;00; o0O + .,:' .;;;;;;;;;;;;;;;;;;;;;;;;;; ;:, + .',;;cxOOOOOOOOOOOOOOOOOOOOOOOkd:;;,.. + .,cll:' ':llc,. + ,;;:okxdxd: :dxdxko:;;, + .xxxx0XNNK0O. .O0KNNX0xxxx. + ,${c2}cc:${c1},. .,${c2}:cc${c1}, + ........;${c2}ccc:${c1};. .;${c2}:ccc${c1};........ + ${c2}ccccccccccccccc ccccccccccccccc${c1} + ........;${c2}ccc:${c1};. .;${c2}:ccc${c1};........ + ,${c2}cc:${c1},. .,${c2}:cc${c1}, + .xxxx0XNNK0O. .O0KNNX0xxxx. + ,;;:okxdxd: :dxdxko:;;, + .,cll:' ':llc,. + .,,;,ckOOOOOOOOOOOOOOOOOOOOOOOOx;,;,'. + .:l' ........................... ;:; + lOk' cdd + ;lccccccccccccccccccccccccccccccccccc:. diff --git a/src/logo/ascii/oracle.txt b/src/logo/ascii/oracle.txt new file mode 100644 index 0000000000..988ebea547 --- /dev/null +++ b/src/logo/ascii/oracle.txt @@ -0,0 +1,11 @@ + `-/+++++++++++++++++/-.` + `/syyyyyyyyyyyyyyyyyyyyyyys/. + :yyyyo/-...............-/oyyyy/ + /yyys- .oyyy+ +.yyyy` `syyy- +:yyyo /yyy/ +.yyyy` `syyy- + /yyys. .oyyyo + /yyyyo:-...............-:oyyyy/` + `/syyyyyyyyyyyyyyyyyyyyyyys+. + `.:/+ooooooooooooooo+/:.` \ No newline at end of file diff --git a/src/logo/ascii/orchid.txt b/src/logo/ascii/orchid.txt new file mode 100644 index 0000000000..aa1fec39c7 --- /dev/null +++ b/src/logo/ascii/orchid.txt @@ -0,0 +1,20 @@ +${c2} .==. + .-${c3}#${c1}@@${c3}#${c2}-. + .-${c3}##${c1}@@@@${c3}##${c2}-. + .-${c3}##${c1}@@@@@@@@${c3}##${c2}-. + :*${c1}@@@@@${c3}####${c1}@@@@@${c2}*: + ..:*${c1}@@@@${c2}==--==${c1}@@@@${c2}*:.. + .-*${c1}%%${c3}#${c2}==${c3}#${c1}@@${c3}#${c2}====${c3}#${c1}@@${c3}#${c2}==${c3}#${c1}%%${c2}*-. + .-${c3}#${c1}@@@@@${c3}##${c2}==${c3}#${c1}@@${c2}++${c1}@@${c3}##${c2}==${c3}#${c1}@@@@@${c3}#${c2}-. + .-${c3}#${c1}@@@@@${c2}#${c1}@@@${c3}#${c2}++#====${c3}#${c2}++#${c1}@@@${c2}#${c1}@@@@@${c3}#${c2}-. +.-${c3}#${c1}@@@@@${c3}#${c2}-==**${c3}###${c2}+:--:+${c3}###${c2}**==-${c3}#${c1}@@@@@${c3}#${c2}-. +.-${c3}#${c1}@@@@@${c3}#${c2}-==**${c3}###${c2}+:--:+${c3}###${c2}**==-${c3}#${c1}@@@@@${c3}#${c2}-. + .-${c3}#${c1}@@@@@${c2}#${c1}@@@${c3}#${c2}++#====${c3}#${c2}++#${c1}@@@${c2}#${c1}@@@@@${c3}#${c2}-. + .-${c3}#${c1}@@@@@${c3}##${c2}==${c3}#${c1}@@${c2}++${c1}@@${c3}##${c2}==${c3}#${c1}@@@@@${c3}#${c2}-. + .-*${c1}%%${c3}#${c2}==${c3}#${c1}@@${c3}#${c2}====${c3}#${c1}@@${c3}#${c2}==${c3}#${c1}%%${c2}*-. + ..:*${c1}@@@@${c2}==--==${c1}@@@@${c2}*:.. + :*${c1}@@@@@${c3}####${c1}@@@@@${c2}*: + .-${c3}##${c1}@@@@@@@@${c3}##${c2}-. + .-${c3}##${c1}@@@@${c3}##${c2}-. + .-${c3}#${c1}@@${c3}#${c2}-. + .==. diff --git a/src/logo/ascii/orchid_small.txt b/src/logo/ascii/orchid_small.txt new file mode 100644 index 0000000000..a124cbedd4 --- /dev/null +++ b/src/logo/ascii/orchid_small.txt @@ -0,0 +1,13 @@ + ${c2}:##: + -#${c1}@@@@${c2}#- + #${c1}@@${c2}=..=${c1}@@${c2}# + +${c1}@@${c2}- -${c1}@@${c2}+ + -#${c1}@@${c2}*..*${c1}@${c2}..${c1}@${c2}*..*${c1}@@${c2}#- + :#${c1}@@${c2}*+%${c1}@${c2}= . . =${c1}@${c2}%+*${c1}@@${c2}#: ++${c1}@@@${c2}: :-. .-: :${c1}@@@${c2}+ + :#${c1}@@${c2}*+%${c1}@${c2}= . . =${c1}@${c2}%+*${c1}@@${c2}#: + -#${c1}@@${c2}*..*${c1}@${c2}..${c1}@${c2}*..*${c1}@@${c2}#- + +${c1}@@${c2}- -${c1}@@${c2}+ + #${c1}@@${c2}=..=${c1}@@${c2}# + -#${c1}@@@@${c2}#- + :##: diff --git a/src/logo/ascii/os_elbrus.txt b/src/logo/ascii/os_elbrus.txt new file mode 100644 index 0000000000..b70cac89c6 --- /dev/null +++ b/src/logo/ascii/os_elbrus.txt @@ -0,0 +1,14 @@ +▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ +██▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀██ +██ ██ +██ ███████ ███████ ██ +██ ██ ██ ██ ██ ██ +██ ██ ██ ██ ██ ██ +██ ██ ██ ██ ██ ██ +██ ██ ██ ██ ██ ██ +██ ██ ███████ ███████ +██ ██ ██ +██ ██▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄██ +██ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀██ +██ ██ +███████████████████████████ diff --git a/src/logo/ascii/osmc.txt b/src/logo/ascii/osmc.txt new file mode 100644 index 0000000000..a7d8868db3 --- /dev/null +++ b/src/logo/ascii/osmc.txt @@ -0,0 +1,20 @@ + -+shdmNNNNmdhs+- + .+hMNho/:..``..:/ohNMh+. + :hMdo. .odMh: + -dMy- -yMd- + sMd- -dMs + hMy +. .+ yMh + yMy dMs. .sMd yMy +:Mm dMNMs` `sMNMd `mM: +yM+ dM//mNs``sNm//Md +My +mM- dM: +NNNN+ :Md -Mm +mM- dM: `oNN+ :Md -Mm +yM+ dM/+NNo` :Md +My +:Mm` dMMNs` :Md `mM: + yMy dMs` -ms yMy + hMy +. yMh + sMd- -dMs + -dMy- -yMd- + :hMdo. .odMh: + .+hMNho/:..``..:/ohNMh+. + -+shdmNNNNmdhs+- diff --git a/src/logo/ascii/pacbsd.txt b/src/logo/ascii/pacbsd.txt new file mode 100644 index 0000000000..0909bf35fe --- /dev/null +++ b/src/logo/ascii/pacbsd.txt @@ -0,0 +1,24 @@ + :+sMs. + `:ddNMd- -o--` + -sMMMMh: `+N+`` + yMMMMMs` .....-/-... `mNh/ + yMMMMMmh+-`:sdmmmmmmMmmmmddy+-``./ddNMMm + yNMMNMMMMNdyyNNMMMMMMMMMMMMMMMhyshNmMMMm + :yMMMMMMMMMNdooNMMMMMMMMMMMMMMMMNmy:mMMd + +MMMMMMMMMmy:sNMMMMMMMMMMMMMMMMMMMmshs- + :hNMMMMMMN+-+MMMMMMMMMMMMMMMMMMMMMMMs. + .omysmNNhy/+yNMMMMMMMMMMNMMMMMMMMMNdNNy- + /hMM:::::/hNMMMMMMMMMMMm/-yNMMMMMMN.mMNh` +.hMMMMdhdMMMMMMMMMMMMMMmo `sMMMMMMN mMMm- +:dMMMMMMMMMMMMMMMMMMMMMdo+ oMMMMMMN`smMNo` +/dMMMMMMMMMMMMMMMMMMMMMNd/` :yMMMMMN:-hMMM. +:dMMMMMMMMMMMMMMMMMMMMMNh` oMMMMMMNo/dMNN` +:hMMMMMMMMMMMMMMMMMMMMMMNs--sMMMMMMMNNmy++` + sNMMMMMMMMMMMMMMMMMMMMMMMmmNMMMMMMNho::o. + :yMMMMMMMMMMMMMNho+sydNNNNNNNmysso/` -// + /dMMMMMMMMMMMMMs- ````````..`` + .oMMMMMMMMMMMMNs` ./y:` + +dNMMNMMMMMMMmy` ``./ys. + `/hMMMMMMMMMMMNo-`` `.+yy+-` + `-/hmNMNMMMMMMmmddddhhy/-` + `-+oooyMMMdsoo+/:. diff --git a/src/logo/ascii/panwah.txt b/src/logo/ascii/panwah.txt new file mode 100644 index 0000000000..dc33feae74 --- /dev/null +++ b/src/logo/ascii/panwah.txt @@ -0,0 +1,21 @@ + HHH + HAAAH HHH + HAAAAH HAAAH + HAAAAAAH HAAAAH + HAAAAAAH HAAAAAH + HAAAAAAAAH${c2}WWWWWWWWWWWWWWWW ${c1}HAAAAAH + HAAAAAAAAH${c2}WWWWWWWWWWWWWWWWWWWW${c1} HAAAAAH + HAA${c2}WWWWWWWWWWWWWWWWWWWWWWWWWWWWW${c1}AAAAAH${c2} + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW${c1}WAH${c2} + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWW${c1}AAA${c2}WWWW WWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWW${c1}AAA${c2}WWWWW WWWWWWW WWWWWWWWWWWWWWW + WW${c1}AAA${c2}WWWWWWWWWWWWWWWWW WWWWW${c1}AAA${c2}WWWWWWWW + ${c1}AAA${c2}WWWWW${c1}OOOOOOOOOOO${c2}WWWWWWWWWWW${c1}AAA${c2}WWWWWW + ${c1}OOOO${c3}GGGGGGG${c1}OOOO${c2}WWWWWWWWWW${c1}AAA${c2}WWWW + ${c1}OOO${c3}GGGGGGG${c1}OOO${c2}WWWWWWWWWWWW${c1}AAA${c2}W + ${c1}OOOOOOOOO diff --git a/src/logo/ascii/parabola.txt b/src/logo/ascii/parabola.txt new file mode 100644 index 0000000000..3fd077655e --- /dev/null +++ b/src/logo/ascii/parabola.txt @@ -0,0 +1,16 @@ + `.-. `. + `.` `:++. `-+o+. + `` `:+/. `:+/. `-+oooo+ + ``-::-.:+/. `:+/. `-+oooooo+ + `.-:///- ..` .-. `-+oooooooo- + `..-..` `+ooooooooo: +`` :oooooooo/ + `ooooooo: + `oooooo: + -oooo+. + +ooo/` + -ooo- + `+o/. + /+- + //` + -. \ No newline at end of file diff --git a/src/logo/ascii/parabola_small.txt b/src/logo/ascii/parabola_small.txt new file mode 100644 index 0000000000..da9f704e40 --- /dev/null +++ b/src/logo/ascii/parabola_small.txt @@ -0,0 +1,6 @@ + __ __ __ _ +.`_//_//_/ / `. + / .` + / .` + /.` + /` \ No newline at end of file diff --git a/src/logo/ascii/parch.txt b/src/logo/ascii/parch.txt new file mode 100644 index 0000000000..566954cabd --- /dev/null +++ b/src/logo/ascii/parch.txt @@ -0,0 +1,19 @@ + +s;;:o- + s/sssso+/-'+\\ + +/ssssss/` + /ssssssss/ + \\ 'sssssss: + `o+;ssssssso\\ + /sssssssssssss\\+ + ;ssssssssssssssss: + :sssssssssssssssssso; + /ssssssssssssssssssssss + `+ssssssssssssssssssssso\\ + so+'+ssssssssssssssss+'` + '` +osssssoooooosssss++oo\\ + /sssssssooooooosssssssso + `osssssssssoooossssssssso: + \\sssssssssssssssssssss; + `+osssssssssssssss:/' + `\\osssssssssso;+' + `\\+;so:+-` diff --git a/src/logo/ascii/pardus.txt b/src/logo/ascii/pardus.txt new file mode 100644 index 0000000000..5305949e0e --- /dev/null +++ b/src/logo/ascii/pardus.txt @@ -0,0 +1,18 @@ + .smNdy+- `.:/osyyso+:.` -+ydmNs. +/Md- -/ymMdmNNdhso/::/oshdNNmdMmy/. :dM/ +mN. oMdyy- -y `-dMo .Nm +.mN+` sMy hN+ -: yMs `+Nm. + `yMMddMs.dy `+` sMddMMy` + +MMMo .` . oMMM+ + `NM/ `````.` `.````` +MN` + yM+ `.-:yhomy ymohy:-.` +My + yM: yo oy :My + +Ms .N` `N. +h sM+ + `MN - -::::::- : :o:+`NM` + yM/ sh -dMMMMd- ho +y+My + .dNhsohMh-//: /mm/ ://-yMyoshNd` + `-ommNMm+:/. oo ./:+mMNmmo:` + `/o+.-somNh- :yy: -hNmos-.+o/` + ./` .s/`s+sMdd+``+ddMs+s`/s. `/. + : -y. -hNmddmNy. .y- : + -+ `..` +- diff --git a/src/logo/ascii/parrot.txt b/src/logo/ascii/parrot.txt new file mode 100644 index 0000000000..d1f0d1ea76 --- /dev/null +++ b/src/logo/ascii/parrot.txt @@ -0,0 +1,24 @@ + `:oho/-` +`mMMMMMMMMMMMNmmdhy- + dMMMMMMMMMMMMMMMMMMs` + +MMsohNMMMMMMMMMMMMMm/ + .My .+dMMMMMMMMMMMMMh. + + :NMMMMMMMMMMMMNo + `yMMMMMMMMMMMMMm: + /NMMMMMMMMMMMMMy` + .hMMMMMMMMMMMMMN+ + ``-NMMMMMMMMMd- + /MMMMMMMMMMMs` + mMMMMMMMsyNMN/ + +MMMMMMMo :sNh. + `NMMMMMMm -o/ + oMMMMMMM. + `NMMMMMM+ + +MMd/NMh + mMm -mN` + /MM `h: + dM` . + :M- + d: + -+ + - diff --git a/src/logo/ascii/parsix.txt b/src/logo/ascii/parsix.txt new file mode 100644 index 0000000000..2753a461af --- /dev/null +++ b/src/logo/ascii/parsix.txt @@ -0,0 +1,21 @@ + ${c2}-/+/:. + ${c2}.syssssys. + ${c1}.--. ${c2}ssssssssso${c1} ..--. + :++++++: ${c2}+ssssssss+${c1} ./++/+++: + /+++++++++.${c2}.yssooooy`${c1}-+///////o- + /++++++++++.${c2}+soooos:${c1}:+////////+- + :+++++////o-${c2}oooooo-${c1}+/////////- + `-/++//++-${c4}.-----.-${c1}:+/////:- + ${c3}-://::--${c1}-:/:${c4}.--.````.--.${c1}:::-${c3}--::::::. +${c3}-/:::::::://:${c4}.:-` `-:${c3}`:/:::::::--/- +${c3}/::::::::::/-${c4}--. .-.${c3}-/://///::::/ +${c3}-/:::::::::/:${c4}`:-. .-:${c3}`:///////////- + `${c3}-::::--${c1}.-://.${c4}---....---${c1}`:+/:-${c3}--::::-` + ${c1}-/+///+o/-${c4}.----.${c1}.:oo+++o+. + ${c1}-+/////+++o:${c2}syyyyy.${c1}o+++++++++: + ${c1}.+////+++++-${c2}+sssssy+${c1}.++++++++++\ + ${c1}.+:/++++++.${c2}.yssssssy-${c1}`+++++++++: + ${c1}:/+++++- ${c2}+sssssssss ${c1}-++++++- + ${c1}`--` ${c2}+sssssssso ${c1}`--` + ${c2}+sssssy+` + ${c2}`.::-` diff --git a/src/logo/ascii/pcbsd.txt b/src/logo/ascii/pcbsd.txt new file mode 100644 index 0000000000..4641cbc695 --- /dev/null +++ b/src/logo/ascii/pcbsd.txt @@ -0,0 +1,27 @@ + .. + s. + +y + yN + -MN `. + :NMs `m + .yMMm` `No + `-/+++sdMMMNs+-`+Ms + `:oo+-` .yMMMMy` `-+oNMh + -oo- +NMMMM/ oMMh- + .s+` ` oMMMMM/ - oMMMhy. + +s`- :: :MMMMMd -o `mMMMy`s+ + y+ h .Ny+oNMMMMMN/ sh+NMMMMo +y + s+ .ds -NMMMMMMMMMMNdhdNMMMMMMh` +s +-h .NM` `hMMMMMMMMMMMMMMNMMNy: h- +y- hMN` hMMmMMMMMMMMMNsdMNs. -y +m` mMMy` oMMNoNMMMMMMo` sMMMo `m +m` :NMMMdyydMMMMo+MdMMMs sMMMd` `m +h- `+ymMMMMMMMM--M+hMMN/ +MMMMy -h +:y `.sMMMMM/ oMM+.yMMNddNMMMMMm y: + y: `s dMMN- .MMMM/ :MMMMMMMMMMh :y + `h: `mdmMMM/ yMMMMs sMMMMMMMMN- :h` + so -NMMMN /mmd+ `dMMMMMMMm- os + :y: `yMMM` `+NMMMMMMNo`:y: + /s+`.omy /NMMMMMNh/.+s: + .+oo:-. /mdhs+::oo+. + -/o+++++++++++/- diff --git a/src/logo/ascii/pclinuxos.txt b/src/logo/ascii/pclinuxos.txt new file mode 100644 index 0000000000..64172a3a65 --- /dev/null +++ b/src/logo/ascii/pclinuxos.txt @@ -0,0 +1,19 @@ + mhhhyyyyhhhdN + dyssyhhhhhhhhhhhssyhN + Nysyhhyo/:-.....-/oyhhhssd + Nsshhy+. `/shhysm + dohhy/ -shhsy + dohhs` /hhys +N+hho ${c2}+ssssss+- .+syhys+ ${c1}/hhsy +ohhh` ${c2}ymmo++hmm+`smmy/::+y` ${c1}shh+ ++hho ${c2}ymm- /mmy+mms ${c1}:hhod +/hh+ ${c2}ymmhhdmmh.smm/ ${c1}.hhsh ++hhs ${c2}ymm+::-` /mmy` ` ${c1}/hh+m +yyhh- ${c2}ymm- /dmdyosyd` ${c1}`yhh+ + ohhy` ${c2}://` -/+++/- ${c1}ohhom + N+hhy- `shhoh + sshho. `+hhyom + dsyhhs/. `:ohhhoy + dysyhhhso///://+syhhhssh + dhyssyhhhhhhyssyyhN + mddhdhdmN diff --git a/src/logo/ascii/pearos.txt b/src/logo/ascii/pearos.txt new file mode 100644 index 0000000000..bf151de5fe --- /dev/null +++ b/src/logo/ascii/pearos.txt @@ -0,0 +1,21 @@ + .+yh + sMMMo + sMMN+ + +o: +$2 ./oyyys+. + :dMMMMMMMMMm/ + :MMMMMMMMMMMMMy + yMMMMMMMMMMMMMN +$3 mMMMMMMMMMMMMs` + yMMMMMMMMMMMMo + -mMMMMMMMMMMMMM` + oMMMMMMMMMMMMMMM` +$4 oMMMMMMMMMMMMMMMMy + .MMMMMMMMMMMMMMMMMMy` + +MMMMMMMMMMMMMMMMMMMMy/` + /MMMMMMMMMMMMMMMMMMMMMMMNds +$5 `mMMMMMMMMMMMMMMMMMMMMMMMM/ + .mMMMMMMMMMMMMMMMMMMMMMM+ + `oNMMMMMMMMMMMMMMMMMMd- + `+hMMMMMMMMMMMMMms- + -/osyhhyso:. diff --git a/src/logo/ascii/pengwin.txt b/src/logo/ascii/pengwin.txt new file mode 100644 index 0000000000..4306068e39 --- /dev/null +++ b/src/logo/ascii/pengwin.txt @@ -0,0 +1,15 @@ +${c3} ...` +${c3} `-///:-` +${c3} .+${c2}ssys${c3}/ +${c3} +${c2}yyyyy${c3}o ${c2} +${c2} -yyyyyy: +${c2} `.:/+ooo+/:` -yyyyyy+ +${c2} `:oyyyyyys+:-.`syyyyyy: +${c2} .syyyyyyo-` .oyyyyyyo +${c2}`syyyyyy `-+yyyyyyy/` +${c2}/yyyyyy+ -/osyyyyyyo/. +${c2}+yyyyyy- `.-:::-.` +${c2}.yyyyyy- +${c3} :${c2}yyyyy${c3}o +${c3} .+${c2}ooo${c3}+ +${c3} `.::/:. diff --git a/src/logo/ascii/pentoo.txt b/src/logo/ascii/pentoo.txt new file mode 100644 index 0000000000..c3c763ea19 --- /dev/null +++ b/src/logo/ascii/pentoo.txt @@ -0,0 +1,20 @@ +${c2} `:oydNNMMMMNNdyo:` + :yNMMMMMMMMMMMMMMMMNy: + :dMMMMMMMMMMMMMMMMMMMMMMd: + oMMMMMMMho/-....-/ohMMMMMMMo + oMMMMMMy. .yMMMMMMo + .MMMMMMo oMMMMMM. + +MMMMMm mMMMMM+ + oMMMMMh hMMMMMo + //hMMMMMm//${c1}`${c2} ${c1}`${c2}////mMMMMMh// +MMMMMMMMMMM${c1}/${c2} ${c1}/o/`${c2} ${c1}.${c2}smMMMMMMMMMMM +MMMMMMMMMMm ${c1}`NMN:${c2} ${c1}.${c2}yMMMMMMMMMM +MMMMMMMMMMMh${c1}:.${c2} dMMMMMMMMM +MMMMMMMMMMMMMy${c1}.${c2} ${c1}-${c2}NMMMMMMMMM +MMMMMMMMMMMd:${c1}`${c2} ${c1}-${c2}yNMMMMMMMMMM +MMMMMMMMMMh${c1}`${c2} ${c1}./${c2}hNMMMMMMMMMMMM +MMMMMMMMMM${c1}s${c2} ${c1}.:${c2}ymMMMMMMMMMMMMMMM +MMMMMMMMMMN${c1}s:..-/${c2}ohNMMMMMMMMMMMMMMMMMM +MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM +MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM diff --git a/src/logo/ascii/peppermint.txt b/src/logo/ascii/peppermint.txt new file mode 100644 index 0000000000..85f25fdc25 --- /dev/null +++ b/src/logo/ascii/peppermint.txt @@ -0,0 +1,21 @@ +${c1} PPPPPPPPPPPPPP +${c1} PPPP${c2}MMMMMMM${c1}PPPPPPPPPPP +${c1} PPPP${c2}MMMMMMMMMM${c1}PPPPPPPP${c2}MM${c1}PP +${c1} PPPPPPPP${c2}MMMMMMM${c1}PPPPPPPP${c2}MMMMM${c1}PP +${c1} PPPPPPPPPPPP${c2}MMMMMM${c1}PPPPPPP${c2}MMMMMMM${c1}PP +${c1} PPPPPPPPPPPP${c2}MMMMMMM${c1}PPPP${c2}M${c1}P${c2}MMMMMMMMM${c1}PP +${c1} PP${c2}MMMM${c1}PPPPPPPPPP${c2}MMM${c1}PPPPP${c2}MMMMMMM${c1}P${c2}MM${c1}PPPP +${c1} P${c2}MMMMMMMMMM${c1}PPPPPP${c2}MM${c1}PPPPP${c2}MMMMMM${c1}PPPPPPPP +${c1}P${c2}MMMMMMMMMMMM${c1}PPPPP${c2}MM${c1}PP${c2}M${c1}P${c2}MM${c1}P${c2}MM${c1}PPPPPPPPPPP +${c1}P${c2}MMMMMMMMMMMMMMMM${c1}PP${c2}M${c1}P${c2}MMM${c1}PPPPPPPPPPPPPPPP +${c1}P${c2}MMM${c1}PPPPPPPPPPPPPPPPPPPPPPPPPPPPPP${c2}MMMMM${c1}P +${c1}PPPPPPPPPPPPPPPP${c2}MMM${c1}P${c2}M${c1}P${c2}MMMMMMMMMMMMMMMM${c1}PP +${c1}PPPPPPPPPPP${c2}MM${c1}P${c2}MM${c1}PPPP${c2}MM${c1}PPPPP${c2}MMMMMMMMMMM${c1}PP +${c1} PPPPPPPP${c2}MMMMMM${c1}PPPPP${c2}MM${c1}PPPPPP${c2}MMMMMMMMM${c1}PP +${c1} PPPP${c2}MM${c1}P${c2}MMMMMMM${c1}PPPPPP${c2}MM${c1}PPPPPPPPPP${c2}MMMM${c1}PP +${c1} PP${c2}MMMMMMMMM${c1}P${c2}M${c1}PPPP${c2}MMMMMM${c1}PPPPPPPPPPPPP +${c1} PP${c2}MMMMMMM${c1}PPPPPPP${c2}MMMMMM${c1}PPPPPPPPPPPP +${c1} PP${c2}MMMM${c1}PPPPPPPPP${c2}MMMMMMM${c1}PPPPPPPP +${c1} PP${c2}MM${c1}PPPPPPPP${c2}MMMMMMMMMM${c1}PPPP +${c1} PPPPPPPPPP${c2}MMMMMMMM${c1}PPPP +${c1} PPPPPPPPPPPPPP diff --git a/src/logo/ascii/phyos.txt b/src/logo/ascii/phyos.txt new file mode 100644 index 0000000000..4bd8feaff9 --- /dev/null +++ b/src/logo/ascii/phyos.txt @@ -0,0 +1,18 @@ + ' +.^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.^^^^^. + :777777777777777777777777777777^~7777: + .~~~~~~~~~~~~~~~~~~~~~^~7777!:!777!. + ~7!!!!!!!!!!!!!!!!!^:!777~^!777~ + ^77777!!!!!!!!!7!^^7777^^7777^ + ^7777~.~~~~^. .~7777^~7777: + :!777~^!777~. !777!:~777!: + .!777!:~777!:~77~:!777!. + ~777!^~7777:^~^!777~ + ^7777^^7777^^7777^ + :7777~^!7777777: + .!777!:!7777!. + .~777!:~77~. + ~7777^~~ + ^7777. + :77: + .. diff --git a/src/logo/ascii/pisi.txt b/src/logo/ascii/pisi.txt new file mode 100644 index 0000000000..5fee6715a3 --- /dev/null +++ b/src/logo/ascii/pisi.txt @@ -0,0 +1,19 @@ + \Fv/!- `:?lzC +${c1} Q!::=zFx! ${c2}`;v6WBCicl;` ${c1},vCC\!::#. +${c1} ,%:::,'` ${c2}+#%@@FQ@@. ,cF%i${c1}``-',::a? +${c1} +m:,'```${c2}}3,/@@Q\@@ "af-${c1} `-'"7f + =o'.` ${c2}/m' :Q@:Qg ,kl${c1} `.|o + :k` '${c2}$+ 'Narm >d,${c1} ii + #`${c2}!p. `C , 'd+${c1} %' +${c2} !0m `6Kv + =a m+ + !A !\L|: :|L\! $: + .8` Q''%Q#' '#Q%''Q `0- + :6 E|.6QQu uQQ6.|E p: + i{ \jts9? ?9stj\ u\ + |a` -''. `e> + ,m+ ${c1}'^ !`${c2}s@@@@a${c1}'"`+`${c2} >e' + !3|${c1}`|=>>r- ${c2}'U%:${c1} '>>>=:`\3! + 'xopE| ${c2}`'${c1} `ledoz- + `;=>>+`${c2}`^llci/|==|/iclc;`${c1}'>>>>: + `^`+~ ${c2}````${c1} !!-^ diff --git a/src/logo/ascii/pnm_linux.txt b/src/logo/ascii/pnm_linux.txt new file mode 100644 index 0000000000..3c3f3842e6 --- /dev/null +++ b/src/logo/ascii/pnm_linux.txt @@ -0,0 +1,19 @@ + ``.---..` `--` + ``.---........-:.${c2}-::`${c1} + ${c2}./::-${c1}........${c2}--::.````${c1} + ${c2}.:://:::${c1}----${c2}::::-..${c1} + ..${c2}--:::::--::::++-${c1}.` + ${c2}`-:-`${c1} .-ohy+::${c2}-:::${c1}/sdmdd:.${c2} `-:- + .-:::${c1}...${c3}sNNmds$y${c1}o/+${c3}sy+NN$m${c1}d+.`${c2}-:::-. + `.-:-${c1}./${c3}dN${c1}()${c3}yyooosd${c1}()${c3}$m${c1}dy${c2}-.::-.`${c1} + ${c2}`.${c1}-...-${c3}+hNdyyyyyydmy${c1}:......${c2}`${c1} + ``..--.....-${c3}yNNm${c4}hssssh${c3}mmdo${c1}.........``` +`-:://:.....${c3}hNNNNN${c4}mddm${c3}NNNmds${c1}.....//::--` + ```.:-...${c3}oNNNNNNNNNNNNNNmd/${c1}...:-.``` + .....${c3}hNNNNNNNNNNNNNNmds${c1}....` + --...${c3}hNNNNNNNNNNNNNNmdo${c1}..... + .:...${c3}/NNNNNNNNNNNNNNdd${c1}:....` + `-...${c3}+mNNNNNNNNNNNmh${c1}:...-. + ${c4}.:+o+/:-${c1}:+oo+///++o+/:-${c4}:/+ooo/:. + ${c4}+oo/:o- +oooooso.` + ${c4}.` ` `/ .-//- diff --git a/src/logo/ascii/pop.txt b/src/logo/ascii/pop.txt new file mode 100644 index 0000000000..b562610e59 --- /dev/null +++ b/src/logo/ascii/pop.txt @@ -0,0 +1,20 @@ + ///////////// + ///////////////////// + ///////$2*767$1//////////////// + //////$27676767676*$1////////////// + /////$276767$1//$27676767$1////////////// + /////$2767676$1///$2*76767$1/////////////// + ///////$2767676$1///$276767$1.///$27676*$1/////// +/////////$2767676$1//$276767$1///$2767676$1//////// +//////////$276767676767$1////$276767$1///////// +///////////$276767676$1//////$27676$1////////// +////////////,$27676$1,///////$2767$1/////////// +/////////////*$27676$1///////$276$1//////////// +///////////////$27676$1//////////////////// + ///////////////$27676$1///$2767$1//////////// + //////////////////////$2'$1//////////// + //////$2.7676767676767676767,$1////// + /////$2767676767676767676767$1///// + /////////////////////////// + ///////////////////// + ///////////// \ No newline at end of file diff --git a/src/logo/ascii/pop_small.txt b/src/logo/ascii/pop_small.txt new file mode 100644 index 0000000000..4865dd9469 --- /dev/null +++ b/src/logo/ascii/pop_small.txt @@ -0,0 +1,8 @@ +______ +\ _ \ __ + \ \ \ \ / / + \ \_\ \ / / + \ ___\ /_/ + \ \ _ + __\_\__(_)_ + (___________)` \ No newline at end of file diff --git a/src/logo/ascii/porteus.txt b/src/logo/ascii/porteus.txt new file mode 100644 index 0000000000..bc2cac4be9 --- /dev/null +++ b/src/logo/ascii/porteus.txt @@ -0,0 +1,23 @@ + `.-:::-.` + -+ydmNNNNNNNmdy+- + .+dNmdhs+//////+shdmdo. + .smmy+-` ./sdy: + `omdo. `.-/+osssso+/-` `+dy. + `yms. `:shmNmdhsoo++osyyo-``oh. + hm/ .odNmds/.` ``.....:::-+s +/m: `+dNmy:` `./oyhhhhyyooo++so +ys `yNmy- .+hmmho:-.` ``` +s: yNm+` .smNd+. +`` /Nm: +dNd+` + yN+ `smNy. + dm oNNy` + hy -mNm. + +y oNNo + `y` sNN: + `: +NN: + ` .mNo + /mm` + /my` + .sy` + .+: + ` diff --git a/src/logo/ascii/postmarketos.txt b/src/logo/ascii/postmarketos.txt new file mode 100644 index 0000000000..82e995bd7c --- /dev/null +++ b/src/logo/ascii/postmarketos.txt @@ -0,0 +1,18 @@ + /\\ + / \\ + / \\ + / \\ + / \\ + / \\ + \\ \\ + /\\ \\____ \\ + / \\____ \\ \\ + / / \\ \\ + / / \\ ___\\ + / / \\ / ____ + / / \\/ / \\ + / / __________/ \\ + / \\ \\ \\ + / \\ \\ \\ + / / / \\ +/___________/ /____________________\\ diff --git a/src/logo/ascii/postmarketos_small.txt b/src/logo/ascii/postmarketos_small.txt new file mode 100644 index 0000000000..0515ff07e1 --- /dev/null +++ b/src/logo/ascii/postmarketos_small.txt @@ -0,0 +1,9 @@ + /\\ + / \\ + / \\ + \\__ \\ + /\\__ \\ _\\ + / / \\/ __ + / / ____/ \\ + / \\ \\ \\ +/_____/ /________\\ diff --git a/src/logo/ascii/proxmox.txt b/src/logo/ascii/proxmox.txt new file mode 100644 index 0000000000..a601cdbd9e --- /dev/null +++ b/src/logo/ascii/proxmox.txt @@ -0,0 +1,20 @@ +${c1} .://:` `://:. + `hMMMMMMd/ /dMMMMMMh` + `sMMMMMMMd: :mMMMMMMMs` +${c2}`-/+oo+/:${c1}`.yMMMMMMMh- -hMMMMMMMy.`${c2}:/+oo+/-` +`:oooooooo/${c1}`-hMMMMMMMyyMMMMMMMh-`${c2}/oooooooo:` + `/oooooooo:${c1}`:mMMMMMMMMMMMMm:`${c2}:oooooooo/` + ./ooooooo+-${c1} +NMMMMMMMMN+ ${c2}-+ooooooo/. + .+ooooooo+-${c1}`oNMMMMNo`${c2}-+ooooooo+. + -+ooooooo/.${c1}`sMMs`${c2}./ooooooo+- + :oooooooo/${c1}`..`${c2}/oooooooo: + :oooooooo/`${c1}..${c2}`/oooooooo: + -+ooooooo/.`${c1}sMMs${c2}`./ooooooo+- + .+ooooooo+-`${c1}oNMMMMNo${c2}`-+ooooooo+. + ./ooooooo+-${c1} +NMMMMMMMMN+ ${c2}-+ooooooo/. + `/oooooooo:`${c1}:mMMMMMMMMMMMMm:${c2}`:oooooooo/` +`:oooooooo/`${c1}-hMMMMMMMyyMMMMMMMh-${c2}`/oooooooo:` +`-/+oo+/:`${c1}.yMMMMMMMh- -hMMMMMMMy.${c2}`:/+oo+/-` +${c1} `sMMMMMMMm: :dMMMMMMMs` + `hMMMMMMd/ /dMMMMMMh` + `://:` `://:` diff --git a/src/logo/ascii/puffos.txt b/src/logo/ascii/puffos.txt new file mode 100644 index 0000000000..46fde3a733 --- /dev/null +++ b/src/logo/ascii/puffos.txt @@ -0,0 +1,12 @@ + _,..._,m, + ,/' '""; + / ". + ,'mmmMMMMmm. \ + _/-"^^^^^"""%#%mm, ; + ,m,_,' "###) ;, +(###% \#/ ;##mm. + ^#/ __ ___ ; (######) + ; //.\\ //.\\ ; \####/ + _; (#\"// \\"/#) ; ,/ +@##\ \##/ = `"=" ,;mm/ +`\##>.____,...,____,<####@ diff --git a/src/logo/ascii/puppy.txt b/src/logo/ascii/puppy.txt new file mode 100644 index 0000000000..d650845dc3 --- /dev/null +++ b/src/logo/ascii/puppy.txt @@ -0,0 +1,18 @@ + `-/osyyyysosyhhhhhyys+- + -ohmNNmh+/hMMMMMMMMNNNNd+dMMMMNM+ + yMMMMNNmmddo/NMMMNNNNNNNNNo+NNNNNy +.NNNNNNmmmddds:MMNNNNNNNNNNNh:mNNN/ +-NNNdyyyhdmmmd`dNNNNNmmmmNNmdd/os/ +.Nm+shddyooo+/smNNNNmmmmNh. :mmd. + NNNNy:` ./hmmmmmmmNNNN: hNMh + NMN- -++- +NNNNNNNNNNm+..-sMMMM- +.MMo oNNNNo hNNNNNNNNmhdNNNMMMMM+ +.MMs /NNNN/ dNmhs+:-` yMMMMMMMM+ + mMM+ .. `sNN+. hMMMMhhMMM- + +MMMmo:...:sNMMMMMms:` hMMMMm.hMMy + yMMMMMMMMMMMNdMMMMMM::/+o+//dMMd` + sMMMMMMMMMMN+:oyyo:sMMMNNMMMNy` + :mMMMMMMMMMMMmddNMMMMMMMMmh/ + /dMMMMMMMMMMMMMMMMMMNdy/` + .+hNMMMMMMMMMNmdhs/. + .:/+ooo+/:-. diff --git a/src/logo/ascii/pureos.txt b/src/logo/ascii/pureos.txt new file mode 100644 index 0000000000..38aad933e4 --- /dev/null +++ b/src/logo/ascii/pureos.txt @@ -0,0 +1,12 @@ +dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmd +dNm//////////////////////////////////mNd +dNd dNd +dNd dNd +dNd dNd +dNd dNd +dNd dNd +dNd dNd +dNd dNd +dNd dNd +dNm//////////////////////////////////mNd +dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmd diff --git a/src/logo/ascii/pureos_small.txt b/src/logo/ascii/pureos_small.txt new file mode 100644 index 0000000000..a53b1d8f47 --- /dev/null +++ b/src/logo/ascii/pureos_small.txt @@ -0,0 +1,6 @@ + _____________ +| _________ | +| | | | +| | | | +| |_________| | +|_____________| diff --git a/src/logo/ascii/q4os.txt b/src/logo/ascii/q4os.txt new file mode 100644 index 0000000000..a696636e72 --- /dev/null +++ b/src/logo/ascii/q4os.txt @@ -0,0 +1,19 @@ + .:***** :=====. + .:******** :========. + .*********** :===========. + .:************ :============- + .************** :============== + :*************** :=============== + :**************. :=============== +.*************: .=============. +*************. .============: + +${c1}:############. ${c2}:==: +${c1}:##############. ${c2}:======: + ${c1}:################ ${c2}.==========: + ${c1}:############### ${c2}.===========: + ${c1}:############## ${c2}.===========: + ${c1}:############# ${c2}.=========: + ${c1}:########### ${c2}.=====: + ${c1}.######### ${c2}.=: + ${c1}.##### diff --git a/src/logo/ascii/qubes.txt b/src/logo/ascii/qubes.txt new file mode 100644 index 0000000000..0b40854050 --- /dev/null +++ b/src/logo/ascii/qubes.txt @@ -0,0 +1,21 @@ + `..--..` + `.----------.` + `..----------------..` + `.------------------------.`` + `..-------------....-------------..` +.::----------..`` ``..----------:+: +:////:----..` `..---:/ossso +:///////:` `/osssssso +:///////: /ssssssso +:///////: /ssssssso +:///////: /ssssssso +:///////: /ssssssso +:///////: /ssssssso +:////////-` .:sssssssso +:///////////-.` `-/osssssssssso +`//////////////:-```.:+ssssssssssssso- + .-://////////////sssssssssssssso/-` + `.:///////////sssssssssssssso:. + .-:///////ssssssssssssssssss/` + `.:////ssss+/+ssssssssssss. + `--//- `-/osssso/. diff --git a/src/logo/ascii/qubyt.txt b/src/logo/ascii/qubyt.txt new file mode 100644 index 0000000000..a0a52d53b1 --- /dev/null +++ b/src/logo/ascii/qubyt.txt @@ -0,0 +1,15 @@ +${c1} ########################${c2}(${c3}ooo +${c1} ########################${c2}(${c3}ooo +${c1}###${c2}(${c3}ooo ${c1}###${c2}(${c3}ooo +${c1}###${c2}(${c3}ooo ${c1}###${c2}(${c3}ooo +${c1}###${c2}(${c3}ooo ${c1}###${c2}(${c3}ooo +${c1}###${c2}(${c3}ooo ${c1}###${c2}(${c3}ooo +${c1}###${c2}(${c3}ooo ${c1}###${c2}(${c3}ooo +${c1}###${c2}(${c3}ooo ${c1}###${c2}(${c3}ooo +${c1}###${c2}(${c3}ooo ${c1}##${c3}o ${c2}((((${c3}ooo +${c1}###${c2}(${c3}ooo o${c2}((${c1}### ${c3}oooooo +${c1}###${c2}(${c3}ooo oo${c2}((${c1}###${c3}o +${c1}###${c2}(${c3}ooo ooo${c2}((${c1}### +${c1}################${c2}(${c3}oo oo${c2}((((${c3}o +${c2}(((((((((((((((((${c3}ooo ooooo + oooooooooooooooooo o diff --git a/src/logo/ascii/quibian.txt b/src/logo/ascii/quibian.txt new file mode 100644 index 0000000000..46541787ab --- /dev/null +++ b/src/logo/ascii/quibian.txt @@ -0,0 +1,18 @@ + `.--::::::::--.` + `.-:::-..`` ``..-::-.` + .::::-` .${c2}+${c1}:`` `.-::.` + .::::.` -::::::-` `.::. + `-:::-` -:::::::::--..`` .::` + `::::- .${c2}oy${c1}:::::::---.```.: `::` + -:::: `.-:::::::::::-.``` `:: +.::::.`-:::::::::::::. `:. +-::::.::::::::::::::: -: +::::::::::::::::::::` `: +:::::::::::::::::::- `: +::::::::::::::::::: -- +.:::::::::::::::::` `:` +`::::::::::::::::: -` + .:::::::::::::::- -` + `::::::::::::::- `.` + .::::::::::::- `` + `.--:::::-. diff --git a/src/logo/ascii/radix.txt b/src/logo/ascii/radix.txt new file mode 100644 index 0000000000..96d6ea6cef --- /dev/null +++ b/src/logo/ascii/radix.txt @@ -0,0 +1,18 @@ + .:oyhdmNo + `/yhyoosdms` + -o+/ohmmho- + ..`.:/:-` + `.--:::-.``${c2} + .+ydNMMMMMMNmhs:` +`omMMMMMMMMMMMMMMNh- +oNMMMNmddhhyyhhhddmy. +mMMMMNmmddhhysoo+/:-` +yMMMMMMMMMMMMMMMMNNh. +-dmmmmmNNMMMMMMMMMMs` + -+oossyhmMMMMMMMMd- + `sNMMMMMMMMMMMMMm: + `yMMMMMMNmdhhhh: + `sNMMMMMNmmho. + `+mMMMMMMMy. + .yNMMMm+` + `:yd+. diff --git a/src/logo/ascii/raspbian.txt b/src/logo/ascii/raspbian.txt new file mode 100644 index 0000000000..ec8020cdbe --- /dev/null +++ b/src/logo/ascii/raspbian.txt @@ -0,0 +1,23 @@ + $2`.::///+:/-. --///+//-:` + `+oooooooooooo: `+oooooooooooo: + /oooo++//ooooo: ooooo+//+ooooo. + `+ooooooo:-:oo- +o+::/ooooooo: + `:oooooooo+`` `.oooooooo+- + `:++ooo/. :+ooo+/.`$1 + ...` `.----.` ``.. + .::::-``:::::::::.`-:::-` + -:::-` .:::::::-` `-:::- + `::. `.--.` `` `.---.``.::` + .::::::::` -::::::::` ` + .::` .:::::::::- `::::::::::``::. +-:::` ::::::::::. ::::::::::.`:::- +:::: -::::::::. `-:::::::: :::: +-::- .-:::-.``....``.-::-. -::- + .. `` .::::::::. `..`.. + -:::-` -::::::::::` .:::::` + :::::::` -::::::::::` :::::::. + .::::::: -::::::::. :::::::: + `-:::::` ..--.` ::::::. + `...` `...--..` `...` + .:::::::::: + `.-::::-` \ No newline at end of file diff --git a/src/logo/ascii/raspbian_small.txt b/src/logo/ascii/raspbian_small.txt new file mode 100644 index 0000000000..eceb8c3ae0 --- /dev/null +++ b/src/logo/ascii/raspbian_small.txt @@ -0,0 +1,10 @@ + $2.~~. .~~. + '. \ ' ' / .'$1 + .~ .~~~..~. + : .~.'~'.~. : + ~ ( ) ( ) ~ +( : '~'.~.'~' : ) + ~ .~ ( ) ~. ~ + ( : '~' : ) + '~ .~~~. ~' + '~' \ No newline at end of file diff --git a/src/logo/ascii/ravynos.txt b/src/logo/ascii/ravynos.txt new file mode 100644 index 0000000000..a53a5733a1 --- /dev/null +++ b/src/logo/ascii/ravynos.txt @@ -0,0 +1,20 @@ + ..oooo.. + .o$$$$$$$$$$$$$$$$$$$$$$$$$$$$o. + od$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o + o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o + .$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$. + d$$$$$$$$$$$$$$$$$********$$$$$$$$$$$$$$$$$$$$$$$$$$$$$b + d$$$$$$$$$$$$$* °****?$$$$$$$$$$$$$$$$b + $$$$$$$$$$$$* °$$$$$$$$$$$$$ + d$$$$** .oo$$$$$$$$$$$$$$$$b + *° o$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$P + *$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + ?$$$$$$$$$$$$$$$$$$$$$$$$$$$$P + $$$$$$$$$$$$$$$$$$$$$$$$$P + $$$$$$$$$$$$$$$$$$$$$$$$P + ?$$$$$$$$$$$$$$$$$$$$* + $$$$$$$$$$$$$*° + d$$$$$$$$*° + ° diff --git a/src/logo/ascii/reborn.txt b/src/logo/ascii/reborn.txt new file mode 100644 index 0000000000..255deba848 --- /dev/null +++ b/src/logo/ascii/reborn.txt @@ -0,0 +1,20 @@ + $1.======================. + $1.#$2#*********$1%%$2*********#$1%: + $1:%$2#**********$1%%$2**********#$1%- + $1-%$2************$1%%$2************$1%= + $1+%$2******$1%%#####$1%%#####%%$2******$1%+ + $1*%%#$2****$1%#$3+=====$1%%$3=====+$1#%$2****$1#%%* + $1*%$2*#$1#%%#%#$3====+++$1%%$3+++====$1#%#%%#$2#*$1##. + $1.##$2*****$1#%%%#$3*++$1%######%$3*+*$1#%%%#$2*****$1#%. + $1:%#$2*****$1#%$3*=+*$1#%%$3*++++++*$1%%#$3*+=*$1%#$2*****$1#%: +$1-%#$2*****$1#%$3+====*$1%$3*++++++++*$1%#$3====+$1%#$2******$1%- +$1-%#$2*****$1#%$3+====*$1%$3*++++++++*$1%#$3====+$1%#$2******$1%= + $1:%#$2*****$1#%$3*=+*$1#%%$3*++++++*$1%%#$3*+=*$1%#$2*****$1#%- + $1.##$2*****$1#%%%#$3*+*$1%######%$3*+*$1#%%%#$2*****$1#%: + $1.##$2**$1#%%#%#$3====+++$1%%$3+++====$1#%#%%#$2#*$1##. + $1*%%#$2****$1%#$3+=====$1%%$3=====+$1#%$2****$1#%%* + $1+%$2******$1%%#####%%#####%%$2******$1%* + $1-%$2************$1%%$2************$1%= + $1:%$2#**********$1%%$2**********#$1%- + $1:%$2#*********$1%%$2*********#$1%: + $1.======================. \ No newline at end of file diff --git a/src/logo/ascii/reborn_small.txt b/src/logo/ascii/reborn_small.txt new file mode 100644 index 0000000000..dbb0288725 --- /dev/null +++ b/src/logo/ascii/reborn_small.txt @@ -0,0 +1,7 @@ + _______ + /\_____/\ + / /\___/\ \ +/_/_/ \_\_\ +\ \ \___/ / / + \ \/___\/ / + \/_____\/ diff --git a/src/logo/ascii/redcore.txt b/src/logo/ascii/redcore.txt new file mode 100644 index 0000000000..a226b918dd --- /dev/null +++ b/src/logo/ascii/redcore.txt @@ -0,0 +1,16 @@ + RRRRRRRRR + RRRRRRRRRRRRR + RRRRRRRRRR RRRRR + RRRRRRRRRRRRRRRRRRRRRRRRRRR + RRRRRRR RRR RRR RRRRRRRR +RRRRR RR RRRRRRRRR +RRRR RR RRRRRRRR RR RRRRRR +RRRR R RRRRRRRRRRRRRR RR RRRRR +RRRR R RRRRRRRRRRRRRRRRRR R RRRRR +RRRR RRRRRRRRRRRRRRRRRRR R RRRR + RRR RRRRRRRRRRRRRRRRRRRR R RRRR + RRR RRRRRRRRRRRRRRRRRRRR RRRR + RR RRRRRRRRRRRRRRRRRRR RRR + RR RRRRRRRRRRRRRRRRR RRR + RR RRRRRRRRRRRRRR RR + R RRRR RR diff --git a/src/logo/ascii/redstar.txt b/src/logo/ascii/redstar.txt new file mode 100644 index 0000000000..4340f5e49c --- /dev/null +++ b/src/logo/ascii/redstar.txt @@ -0,0 +1,18 @@ + .. + .oK0l + :0KKKKd. + .xKO0KKKKd + ,Od' .d0000l + .c;. .'''... ..'. +.,:cloddxxxkkkkOOOOkkkkkkkkxxxxxxxxxkkkx: +;kOOOOOOOkxOkc'...',;;;;,,,'',;;:cllc:,. + .okkkkd,.lko .......',;:cllc:;,,'''''. + .cdo. :xd' cd:. ..';'',,,'',,;;;,'. + . .ddl.;doooc'..;oc;'..';::;,'. + coo;.oooolllllllcccc:'. . + .ool''lllllccccccc:::::;. + ;lll. .':cccc:::::::;;;;' + :lcc:'',..';::::;;;;;;;,,. + :cccc::::;...';;;;;,,,,,,. + ,::::::;;;,'. ..',,,,'''. + ........ ...... diff --git a/src/logo/ascii/refracted_devuan.txt b/src/logo/ascii/refracted_devuan.txt new file mode 100644 index 0000000000..1ec9ff9b7a --- /dev/null +++ b/src/logo/ascii/refracted_devuan.txt @@ -0,0 +1,18 @@ + A + VW + VVW\\ + .yWWW\\ + ,;,,u,;yy;;v;uyyyyyyy ,WWWWW^ + *WWWWWWWWWWWWWWWW/ $VWWWWw , + ^*%WWWWWWVWWX $WWWW** ,yy + , "**WWW/' **' ,yy/WWW*` + &WWWWwy `*` <,ywWW%VWWW* + yWWWWWWWWWW* ., "**WW%W + ,&WWWWWM*"` ,y/ &WWWww ^* + XWWX*^ ,yWWWW09 .WWWWWWWWwy, + *` &WWWWWM WWWWWWWWWWWWWww, + (WWWWW` /#####WWW*********** + ^WWWW + VWW + Wh. + V/ diff --git a/src/logo/ascii/regata.txt b/src/logo/ascii/regata.txt new file mode 100644 index 0000000000..9760d18a11 --- /dev/null +++ b/src/logo/ascii/regata.txt @@ -0,0 +1,20 @@ + ddhso+++++osydd + dho/.`hh${c2}.:/+/:.${c1}hhh`:+yd + do-hhhhhh${c2}/sssssss+`${c1}hhhhh./yd + h/`hhhhhhh${c2}-sssssssss:${c1}hhhhhhhh-yd + do`hhhhhhhhh${c2}`ossssssso.${c1}hhhhhhhhhh/d + d/hhhhhhhhhhhh${c2}`/ossso/.${c1}hhhhhhhhhhhh.h + /hhhhhhhhhhhh${c3}`-/osyso/-`${c1}hhhhhhhhhhhh.h +shh${c4}-/ooo+-${c1}hhh${c3}:syyso+osyys/`${c1}hhh${c5}`+oo`${c1}hhh/ +h${c4}`ohhhhhhho`${c3}+yyo.${c1}hhhhh${c3}.+yyo`${c5}.sssssss.${c1}h`h +s${c4}:hhhhhhhhho${c3}yys`${c1}hhhhhhh${c3}.oyy/${c5}ossssssso-${c1}hs +s${c4}.yhhhhhhhy/${c3}yys`${c1}hhhhhhh${c3}.oyy/${c5}ossssssso-${c1}hs +hh${c4}./syyys+.${c1} ${c3}+yy+.${c1}hhhhh${c3}.+yyo`${c5}.ossssso/${c1}h`h +shhh${c4}``.`${c1}hhh${c3}`/syyso++oyys/`${c1}hhh${c5}`+++-`${c1}hh:h +d/hhhhhhhhhhhh${c3}`-/osyso+-`${c1}hhhhhhhhhhhh.h + d/hhhhhhhhhhhh${c6}`/ossso/.${c1}hhhhhhhhhhhh.h + do`hhhhhhhhh${c6}`ossssssso.${c1}hhhhhhhhhh:h + h/`hhhhhhh${c6}-sssssssss:${c1}hhhhhhhh-yd + h+.hhhhhh${c6}+sssssss+${c1}hhhhhh`/yd + dho:.hhh${c6}.:+++/.${c1}hhh`-+yd + ddhso+++++osyhd diff --git a/src/logo/ascii/regolith.txt b/src/logo/ascii/regolith.txt new file mode 100644 index 0000000000..50ae404fd7 --- /dev/null +++ b/src/logo/ascii/regolith.txt @@ -0,0 +1,18 @@ + ``....``` + `.:/++++++/::-.` + -/+++++++:.` + -++++++++:` + `/++++++++- + `/++++++++. -/+/ + /++++++++/ `` .:+++:. + -+++++++++/ ./++++:+++/-` + :+++++++++/ `+++++++/-` + :++++++++++` .-/+++++++` + `:++++++++++/``.-/++++:-:::-` ` + `:+++++++++++++++++/:.` ./` +:++/-:+++++++++/:-.. -/+. ++++++++++/::-...:/+++/-..````..-/+++. +`......``.::/+++++++++++++++++++++/. + -/+++++++++++++++++++++/. + .:/+++++++++++++++/-` + `.-:://////:-. diff --git a/src/logo/ascii/rhaymos.txt b/src/logo/ascii/rhaymos.txt new file mode 100644 index 0000000000..87e0aae043 --- /dev/null +++ b/src/logo/ascii/rhaymos.txt @@ -0,0 +1,14 @@ + ### + ##### + + ####### /######## + ############# ########### + ,########### #### ####(.. + #### #### ####* ########## + #### ##### ##### (#### + #### ########### ########### + #### ######### ########## + + ################################### + ##################################### +####################################### diff --git a/src/logo/ascii/rhel.txt b/src/logo/ascii/rhel.txt new file mode 100644 index 0000000000..d2fa4eff16 --- /dev/null +++ b/src/logo/ascii/rhel.txt @@ -0,0 +1,18 @@ + .MMM..:MMMMMMM + MMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMM. + MMMMMMMMMMMMMMMMMMMMMM + ,MMMMMMMMMMMMMMMMMMMMMM: + MMMMMMMMMMMMMMMMMMMMMMMM + .MMMM' MMMMMMMMMMMMMMMMMMMMMM + MMMMMM `MMMMMMMMMMMMMMMMMMMM. +MMMMMMMM MMMMMMMMMMMMMMMMMM . +MMMMMMMMM. `MMMMMMMMMMMMM' MM. +MMMMMMMMMMM. MMMM +`MMMMMMMMMMMMM. ,MMMMM. + `MMMMMMMMMMMMMMMMM. ,MMMMMMMM. + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM: + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + `MMMMMMMMMMMMMMMMMMMMMMMM: + ``MMMMMMMMMMMMMMMMM' \ No newline at end of file diff --git a/src/logo/ascii/rhel_old.txt b/src/logo/ascii/rhel_old.txt new file mode 100644 index 0000000000..766f87683c --- /dev/null +++ b/src/logo/ascii/rhel_old.txt @@ -0,0 +1,16 @@ + `.-..........` + `////////::.`-/. + -: ....-////////. + //:-::///////////` + `--::: `-://////////////: + //////- ``.-:///////// .` + `://////:-.` :///////::///:` + .-/////////:---/////////////: + .-://////////////////////. +${c2} yMN+`.-${c1}::///////////////-` +${c2} .-`:NMMNMs` `..-------..` + MN+/mMMMMMhoooyysshsss +MMM MMMMMMMMMMMMMMyyddMMM+ + MMMM MMMMMMMMMMMMMNdyNMMh` hyhMMM + MMMMMMMMMMMMMMMMyoNNNMMM+. MMMMMMMM + MMNMMMNNMMMMMNM+ mhsMNyyyyMNMMMMsMM diff --git a/src/logo/ascii/rocky.txt b/src/logo/ascii/rocky.txt new file mode 100644 index 0000000000..084313127e --- /dev/null +++ b/src/logo/ascii/rocky.txt @@ -0,0 +1,19 @@ + __wgliliiligw_, + _williiiiiiliilililw, + _%iiiiiilililiiiiiiiiiii_ + .Qliiiililiiiiiiililililiilm. + _iiiiiliiiiiililiiiiiiiiiiliil, + .lililiiilililiiiilililililiiiii, +_liiiiiiliiiiiiiliiiiiF{iiiiiilili, +jliililiiilililiiili@` ~ililiiiiiL +iiiliiiiliiiiiiili>` ~liililii +liliiiliiilililii` -9liiiil +iiiiiliiliiiiii~ "4lili +4ililiiiiilil~| -w, )4lf +-liiiiililiF' _liig, )' + )iiiliii@` _QIililig, + )iiii>` .Qliliiiililw + )<>~ .mliiiiiliiiiiil, + _gllilililiililii~ + giliiiiiiiiiiiiT` + -^~$ililili@~~' \ No newline at end of file diff --git a/src/logo/ascii/rocky_small.txt b/src/logo/ascii/rocky_small.txt new file mode 100644 index 0000000000..beb90607b4 --- /dev/null +++ b/src/logo/ascii/rocky_small.txt @@ -0,0 +1,12 @@ + `-/+++++++++/-.` + `-+++++++++++++++++-` +.+++++++++++++++++++++. +-+++++++++++++++++++++++. ++++++++++++++++/-/+++++++ ++++++++++++++/. ./+++++ ++++++++++++:. ./+++ ++++++++++:` `:/:` .:/ +-++++++:` .:+++++:` + .+++-` ./+++++++++:` + `-` ./+++++++++++- + -+++++++++:-.` diff --git a/src/logo/ascii/rosa.txt b/src/logo/ascii/rosa.txt new file mode 100644 index 0000000000..297c19f39e --- /dev/null +++ b/src/logo/ascii/rosa.txt @@ -0,0 +1,20 @@ + ROSAROSAROSAROSAR + ROSA AROS + ROS SAROSAROSAROSAR AROS + RO ROSAROSAROSAROSAROSAR RO + ARO AROSAROSAROSARO AROS ROS + ARO ROSAROS OSAR ROSA ROS + RO AROSA ROSAROSAROSA ROSAR RO +RO ROSAR ROSAROSAROSAR R ROSARO RO +RO ROSA AROSAROSAROSA AR ROSARO AR +RO AROS ROSAROSAROSA ROS AROSARO AR +RO AROS ROSAROSARO ROSARO ROSARO AR +RO ROS AROSAROS ROSAROSA AROSAR AR +RO ROSA ROS ROSAROSAR ROSARO RO + RO ROS AROSAROSAROSA ROSARO AR + ARO ROSA ROSAROSAROS AROSAR ARO + ARO OROSA R ROSAROS ROS + RO AROSAROS AROSAROSAR RO + AROS AROSAROSAROSARO AROS + ROSA SARO + ROSAROSAROSAROSAR \ No newline at end of file diff --git a/src/logo/ascii/sabayon.txt b/src/logo/ascii/sabayon.txt new file mode 100644 index 0000000000..70384adffb --- /dev/null +++ b/src/logo/ascii/sabayon.txt @@ -0,0 +1,18 @@ + ........... + .. .. + .. .. + .. ${c2}o ${c1}.. + .. ${c2}:W' ${c1}.. + .. ${c2}.d. ${c1}.. +:. ${c2}.KNO ${c1}.: +:. ${c2}cNNN. ${c1}.: +: ${c2}dXXX, ${c1}: +: ${c2}. dXXX, .cd, ${c1}: +: ${c2}'kc .. dKKK. ,ll;:' ${c1}: +: ${c2}.xkkxc;..dkkkc',cxkkl ${c1}: +:. ${c2}.,cdddddddddddddo:. ${c1}.: + .. ${c2}:lllllll: ${c1}.. + .. ${c2}',,,,, ${c1}.. + .. .. + .. .. + ............... diff --git a/src/logo/ascii/sabotage.txt b/src/logo/ascii/sabotage.txt new file mode 100644 index 0000000000..9f3adb713b --- /dev/null +++ b/src/logo/ascii/sabotage.txt @@ -0,0 +1,11 @@ + .|'''.| | '||''|. ..|''|| + ||.. ' ||| || || .|' || + ''|||. | || ||'''|. || || +. '|| .''''|. || || '|. || +|'....|' .|. .||. .||...|' ''|...|' + +|''||''| | ..|'''.| '||''''| + || ||| .|' ' || . + || | || || .... ||''| + || .''''|. '|. || || + .||. .|. .||. ''|...'| .||.....| diff --git a/src/logo/ascii/sailfish.txt b/src/logo/ascii/sailfish.txt new file mode 100644 index 0000000000..68b20ac262 --- /dev/null +++ b/src/logo/ascii/sailfish.txt @@ -0,0 +1,13 @@ + _a@b + _#b (b + _@@ @_ _, + _#^@ _#*^^*gg,aa@^^ + #- @@^ _a@^^ + @_ *g#b + ^@_ ^@_ + ^@_ @ + @(b (b + #b(b#^ + _@_#@^ + _a@a*^ +,a@*^ diff --git a/src/logo/ascii/salentos.txt b/src/logo/ascii/salentos.txt new file mode 100644 index 0000000000..fe819033d1 --- /dev/null +++ b/src/logo/ascii/salentos.txt @@ -0,0 +1,20 @@ + ``..`` + .-:+oshdNMMMMMMNdhyo+:-.` + -oydmMMMMMMMMMMMMMMMMMMMMMMMMMMNdhs/ +${c4} +hdddm${c1}NMMMMMMMMMMMMMMMMMMMMMMMMN${c4}mdddh+` +${c2}`MMMMMN${c4}mdddddm${c1}MMMMMMMMMMMM${c4}mdddddm${c3}NMMMMM- +${c2} mMMMMMMMMMMMN${c4}ddddhyyhhddd${c3}NMMMMMMMMMMMM` +${c2} dMMMMMMMMMMMMMMMMM${c4}oo${c3}MMMMMMMMMMMMMMMMMN` +${c2} yMMMMMMMMMMMMMMMMM${c4}hh${c3}MMMMMMMMMMMMMMMMMd +${c2} +MMMMMMMMMMMMMMMMM${c4}hh${c3}MMMMMMMMMMMMMMMMMy +${c2} :MMMMMMMMMMMMMMMMM${c4}hh${c3}MMMMMMMMMMMMMMMMMo +${c2} .MMMMMMMMMMMMMMMMM${c4}hh${c3}MMMMMMMMMMMMMMMMM/ +${c2} `NMMMMMMMMMMMMMMMM${c4}hh${c3}MMMMMMMMMMMMMMMMM- +${c2} mMMMMMMMMMMMMMMMM${c4}hh${c3}MMMMMMMMMMMMMMMMN` +${c2} hMMMMMMMMMMMMMMMM${c4}hh${c3}MMMMMMMMMMMMMMMMm +${c2} /MMMMMMMMMMMMMMMM${c4}hh${c3}MMMMMMMMMMMMMMMMy +${c2} .+hMMMMMMMMMMMMM${c4}hh${c3}MMMMMMMMMMMMMms: +${c2} `:smMMMMMMMMM${c4}hh${c3}MMMMMMMMMNh+. +${c2} .+hMMMMMM${c4}hh${c3}MMMMMMdo: +${c2} `:smMM${c4}yy${c3}MMNy/` + ${c2}.- ${c4}`${c3}:. diff --git a/src/logo/ascii/salientos.txt b/src/logo/ascii/salientos.txt new file mode 100644 index 0000000000..1fab8994e3 --- /dev/null +++ b/src/logo/ascii/salientos.txt @@ -0,0 +1,20 @@ + 00xxxx0 + 00xxxxxx0 + 0xxxxxxxxx 000000 + 0xxxxxxxxxx xxxxxxxxxx0 + 0xxxxxxxxxxx0 xxxxxxxxxxxxx0 + 0xxxxxxxxxxxx0 0xxxxxxxxxxxxxx0 + 0xxxxxxxxxxxxx0 0xxxxxxxxxxxxxxx0 +0xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx0 +xxxxxxxxxxxxxxxx0 0xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxx 0xxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx0 xxxxxxxxxxxxxx +0xxxxxxxxxxxxxxxxxx0 0xxxxxxxxxxxx0 + 0xxxxxxxxxxxxxxxxxx xxxxxxxxxxx0 + 0xxxxxxxxxxxxxxxxx xxxxxxxxxx0 + 0xxxxxxxxxxxxxxxx xxxxxxxxx0 + 0xxxxxxxxxxxx0 0xxxxxxx0 + 0xxxxxxx0 xxxxxx0 + 0xxx00 + x00 diff --git a/src/logo/ascii/salix.txt b/src/logo/ascii/salix.txt new file mode 100644 index 0000000000..828e4783d5 --- /dev/null +++ b/src/logo/ascii/salix.txt @@ -0,0 +1,18 @@ + __s_aaaaaaaaauuoXSSSSSSSS: + ._xSSSSSSSSSSSSSSSSSSSSSSSSSS: + _aSSSSSSSSSSSSSSSSSSSSSSSSSSSSS: + _xSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS: + + nSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS} + nSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS}` + XSSSSSSSSSSSSSSSSSSSSSSSSSSSS"` + SSSSSSSSSSSSSSSSSSSSSSSSS!"` +-""""""""""""""""""""""` diff --git a/src/logo/ascii/sambabox.txt b/src/logo/ascii/sambabox.txt new file mode 100644 index 0000000000..01c891875a --- /dev/null +++ b/src/logo/ascii/sambabox.txt @@ -0,0 +1,19 @@ + # + *////##### + /////////#########( + .((((((///// ,####(#((((( + /#######(((* (#(((((((((. +//((#(#(#, ((##( ,((((((// +////// #(##########( ////// +////// ((#(#(#(#(##########(///////// +/////( (((((((#########(##((((((///// +/(((#( ((((/ +####(# ((### +#########(((/////////(((((((((, (#(#( +########( /////////(((((((* ##### +####///, *////((( ((((((( +./////////// .//((((((((( + ///////////, *(/////((((* + ,/(((((((((##########/. + .((((((####### + ((##* diff --git a/src/logo/ascii/sasanqua.txt b/src/logo/ascii/sasanqua.txt new file mode 100644 index 0000000000..3521c65e47 --- /dev/null +++ b/src/logo/ascii/sasanqua.txt @@ -0,0 +1,18 @@ + __,_ + _╕⌐≡µ,√* º≡, + ñ "' ░ + ╞) _, ▒ __ + _,,,_ _Ñ╜^≡µ ≡' 1µ╕º^el "%µ + ∩' K Yµ& 1l ╞) + ▒ √" ^Ü 1" `1µ + Γ ║h _¿▒∞√;, ^≡, + K ^u_ ⌐* ╙¥ ╓Ñ + ⌠ º≡u,, ║I Å + Ü _∩" ║µ_¿╝" + Yu_ ▒ ╙º≡_ ║l1µ + ║l , Y∞µ___≡ª Γl + ╓hⁿ╖I 1l Ñ ╓Ñ + Ñ ¥,___≡1l ╓Ñ ¿╕ª + Ü ╙L ¿¿∩ª ╓P + ª≡,__ *ⁿ┤ⁿÑⁿ^µ √ª + ⁿ≡,,__√╝* "ⁿⁿ*" diff --git a/src/logo/ascii/scientific.txt b/src/logo/ascii/scientific.txt new file mode 100644 index 0000000000..ae236c7f88 --- /dev/null +++ b/src/logo/ascii/scientific.txt @@ -0,0 +1,20 @@ + =/;;/- + +: // + /; /; + -X H. +.//;;;:;;-, X= :+ .-;:=;:;#;. +M- ,=;;;#:, ,:#;;:=, ,@ +:# :#.=/++++/=.$= #= + ,#; #/:+/;,,/++:+/ ;+. + ,+/. ,;@+, ,#H;, ,/+, + ;+;;/= @. ${c3}.H${c2}#${c3}#X ${c1}-X :///+; + ;+=;;;.@, ${c2}.X${c3}M${c2}@$. ${c1}=X.//;=#/. + ,;: :@#= =$H: .+#- + ,#= #;-///==///-// =#, +;+ :#-;;;:;;;;-X- +: +@- .-;;;;M- =M/;;;-. -X + :;;::;;-. #- :+ ,-;;-;:== + ,X H. + ;/ #= + // +; + '////' diff --git a/src/logo/ascii/semc.txt b/src/logo/ascii/semc.txt new file mode 100644 index 0000000000..6ba73edeae --- /dev/null +++ b/src/logo/ascii/semc.txt @@ -0,0 +1,9 @@ + /\ + ______/ \ + / |()| ${c2}E M C +${c1} | (-- | | + \ \ | | +.----) | |__| +|_______/ / ${c3}"${c1} \ + ${c3}" + " diff --git a/src/logo/ascii/septor.txt b/src/logo/ascii/septor.txt new file mode 100644 index 0000000000..47d9e8239e --- /dev/null +++ b/src/logo/ascii/septor.txt @@ -0,0 +1,20 @@ +ssssssssssssssssssssssssssssssssssssssss +ssssssssssssssssssssssssssssssssssssssss +ssssssssssssssssssssssssssssssssssssssss +ssssssssssssssssssssssssssssssssssssssss +ssssssssss${c2};okOOOOOOOOOOOOOOko;${c1}ssssssssss +sssssssss${c2}oNWWWWWWWWWWWWWWWWWWNo${c1}sssssssss +ssssssss${c2}:WWWWWWWWWWWWWWWWWWWWWW:${c1}ssssssss +ssssssss${c2}lWWWWWk${c1}ssssssssss${c2}lddddd:${c1}ssssssss +ssssssss${c2}cWWWWWNKKKKKKKKKKKKOx:${c1}ssssssssss +${c3}yy${c1}sssssss${c2}OWWWWWWWWWWWWWWWWWWWWx${c1}sssssss${c3}yy +yyyyyyyyyy${c2}:kKNNNNNNNNNNNNWWWWWW:${c3}yyyyyyyy +yyyyyyyy${c2}sccccc;${c3}yyyyyyyyyy${c2}kWWWWW:${c3}yyyyyyyy +yyyyyyyy${c2}:WWWWWWNNNNNNNNNNWWWWWW;${c3}yyyyyyyy +yyyyyyyy${c2}.dWWWWWWWWWWWWWWWWWWWNd${c3}yyyyyyyyy +yyyyyyyyyy${c2}sdO0KKKKKKKKKKKK0Od;${c3}yyyyyyyyyy +yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy +yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy +yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy +yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy +yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy diff --git a/src/logo/ascii/serene.txt b/src/logo/ascii/serene.txt new file mode 100644 index 0000000000..fbdbcfb020 --- /dev/null +++ b/src/logo/ascii/serene.txt @@ -0,0 +1,20 @@ + __---''''''---__ + . . + : : + - _______----_- + s __----''' __---- + __h_ _-' _-' h + '-._''--.._ ; _-' y + : ''-._ '-._/ _-' : + y ':_ _--'' y + m .--'' '-._.;' m + m : : m + y '.._ '-__ y + : '--._ '''----___ : + y '--._ ''-- _ y + h '--._ : h + s __'; vs + - __..--'' - + :_..--'' : + . _ . + `''---______---''-`` diff --git a/src/logo/ascii/sharklinux.txt b/src/logo/ascii/sharklinux.txt new file mode 100644 index 0000000000..d1ab28757e --- /dev/null +++ b/src/logo/ascii/sharklinux.txt @@ -0,0 +1,15 @@ + `:shd/ + `:yNMMMMs + `-smMMMMMMN. + .+dNMMMMMMMMs + .smNNMMMMMMMMm` + .sNNNNNNNMMMMMM/ + `omNNNNNNNMMMMMMm + /dNNNNNNNNMMMMMMM+ + .yNNNNNNNNNMMMMMMMN` + +mNNNNNNNNNMMMMMMMMh + .hNNNNNNNNNNMMMMMMMMMs + +mMNNNNNNNNMMMMMMMMMMMs + .hNMMNNNNMMMMMMMMMMMMMMMd + .oNNNNNNNNNNMMMMMMMMMMMMMMMo +`:+syyssoo++++ooooossssssssssso: diff --git a/src/logo/ascii/shastraos.txt b/src/logo/ascii/shastraos.txt new file mode 100644 index 0000000000..c533a1a111 --- /dev/null +++ b/src/logo/ascii/shastraos.txt @@ -0,0 +1,19 @@ + ..,;;,'. + ':oo. ;o: + :o, ol + .oo ..';co: + ooo',;:looo; + .;lddl + cx .xl .c:' + dd xx xx ,d; +.xd cx. xx dd. + cx: .xo xx ,x: + 'xl xx cx' .xl + xd, xx .xd dx. + .xo:xx xx .xx + 'c xx:.'lx: + ..,;cxxxo + .';:codxxl lxo +cd. 'xo +:o, 'ld + .oc'...';lo diff --git a/src/logo/ascii/siduction.txt b/src/logo/ascii/siduction.txt new file mode 100644 index 0000000000..139798e974 --- /dev/null +++ b/src/logo/ascii/siduction.txt @@ -0,0 +1,20 @@ + _aass, + jQh: =$w + QWmwawQW + )$QQQQ@( .. + _a_a. ~??^ syDY?Sa, + _mW>-<$c jWmi imm. + ]QQwayQE 4QQmgwmQQ` + ?WWQWP' -9QQQQQ@'._aas, + _a%is. .adYYs,. -"?!` aQB*~^3$c +_Qh;.nm .QWc. {QL ]QQp;..vmQ/ +"QQmmQ@ -QQQggmQP ]QQWmggmQQ( + -???" "$WQQQY` __, ?QQQQQQW! + _yZ!?q, - .yWY!!Sw, "???^ + .QQa_=qQ mQm>..vmm + $QQWQQP $QQQgmQQ@ + "???" _aa, -9WWQQWY` + _mB>~)$a -~~ + mQms_vmQ. + ]WQQQQQP + -?T??" diff --git a/src/logo/ascii/skiffos.txt b/src/logo/ascii/skiffos.txt new file mode 100644 index 0000000000..11ba4cd0c0 --- /dev/null +++ b/src/logo/ascii/skiffos.txt @@ -0,0 +1,9 @@ +${c2} ,@@@@@@@@@@@w,_ + ${c2}====~~~,,.${c2}A@@@@@@@@@@@@@@@@@W,_ + ${c1}`||||||||||||||L{${c2}"@$@@@@@@@@B" + ${c1}`|||||||||||||||||||||L{${c2}"$D + ${c2}@@@@@@@@@@@@@@@@@@@@@${c1}_||||}==, + ${c2}*@@@@@@@@@@@@@@@@@@@@@@@@@p${c1}||||==, + ${c1}`'||LLL{{""${c2}@$B@@@@@@@@@@@@@@@p${c1}|| + ${c1}`~=|||||||||||L"${c2}$@@@@@@@@@@@ + ${c1}````'"""""""${c2}'"""""""" diff --git a/src/logo/ascii/slackel.txt b/src/logo/ascii/slackel.txt new file mode 100644 index 0000000000..d650f26f15 --- /dev/null +++ b/src/logo/ascii/slackel.txt @@ -0,0 +1,22 @@ + _aawmmmmmwwaaaaas,,,_. + .ammmmm###mmmmmmm###BQmm##mws + .am###mmBmBmBmBmBmBmmmmm#mmmm#2 + 3$2WWWWWQWQQwwQw$1cii|i|ii= + =lii|ii|n$2QWWWQ$1|)i$2|i$1%i|]$2TQWWWWm$1|ii|i|i= +.li|i|i|m$2WWWQV$1|ii$2wmD$1|iiii|$2TWWWWm$1|i|iiii, +=iii$2www|$WQWk$1|i$2aWWWD$1|i|i|ii]$2QQWQk$1|ii|i|= +iii$2QWWWQz$WW$1|i$2jQQWQm$1w|ii$2wW$1k|$2TTTTY$1i|i|iii +iiI$2QWQWWtyQQ$1|i|$2$WWWWWQWk$1||i|i|ii||i|ii|i +<|i|$2TTT|mQQWz$1|i$23D$1]C|$2nD$W$1|ii$2vWWWWk$1||ii|i> +-|ii|i|i$2WWWQw$1|$2Tt$1|i3$2T$1|$2T$1|i|$2nQWQWDk$1|ii|ii` + <|i|iii|$2VWQWWQ$1|i|i|||ii$2wmWWQWD$1||ii|ii+ + <|ii|i|i]$2$W@$1tv$2QQQWQQQWWTTHT$11|iii|i|> + <|i|ii|ii||v$2QWWWQWWW@vmWWWm$1|i|i|i> + -<|i|ii|ii|i|$2TTTTTT$1|]$2QQWWWC$1|ii>` + -<|i|ii|i|ii|i|i|ii3$2TTT$1t|i>` + ~<|ii|ii|iiiii|i|||i>~ + -~~<|ii|i||i>~~` \ No newline at end of file diff --git a/src/logo/ascii/ubuntu_mate.txt b/src/logo/ascii/ubuntu_mate.txt new file mode 100644 index 0000000000..71bddca1d5 --- /dev/null +++ b/src/logo/ascii/ubuntu_mate.txt @@ -0,0 +1,20 @@ +$1 .:/+oossssoo+/:.` + `:+ssssssssssssssssss+:` + -+sssssssssssssss$2y$1ssssssss+- + .osssssssssssss$2yy$1ss$2mMmh$1ssssssso. + /sssssssss$2ydmNNNmmd$1s$2mMMMMNdy$1sssss/ + `+ssssssss$2hNNdy$1sssssss$2mMMMMNdy$1ssssss+` + +sssssss$2yNNh$1ss$2hmNNNNm$1s$2mMmh$1s$2ydy$1sssssss+ +-sssss$2y$1ss$2Nm$1ss$2hNNh$1ssssss$2y$1s$2hh$1ss$2mMy$1sssssss- ++ssss$2yMNdy$1ss$2hMd$1ssssssssss$2hMd$1ss$2NN$1sssssss+ +sssss$2yMMMMMmh$1sssssssssssss$2NM$1ss$2dMy$1sssssss +sssss$2yMMMMMmhy$1ssssssssssss$2NM$1ss$2dMy$1sssssss ++ssss$2yMNdy$1ss$2hMd$1ssssssssss$2hMd$1ss$2NN$1sssssss+ +-sssss$2y$1ss$2Nm$1ss$2hNNh$1ssssssss$2dh$1ss$2mMy$1sssssss- + +sssssss$2yNNh$1ss$2hmNNNNm$1s$2mNmh$1s$2ymy$1sssssss+ + +ssssssss$2hNNdy$1sssssss$2mMMMMmhy$1ssssss+ + /sssssssss$2ydmNNNNmd$1s$2mMMMMNdh$1sssss/ + .osssssssssssss$2yy$1ss$2mMmdy$1sssssso. + -+sssssssssssssss$2y$1ssssssss+- + `:+ssssssssssssssssss+:` + .:/+oossssoo+/:. \ No newline at end of file diff --git a/src/logo/ascii/ubuntu_old.txt b/src/logo/ascii/ubuntu_old.txt new file mode 100644 index 0000000000..5a816363b1 --- /dev/null +++ b/src/logo/ascii/ubuntu_old.txt @@ -0,0 +1,20 @@ + .-/+oossssoo+/-. + `:+ssssssssssssssssss+:` + -+ssssssssssssssssssyyssss+- + .ossssssssssssssssssd$2MMMNy$1sssso. + /sssssssssss$2hdmmNNmmyNMMMMh$1ssssss/ + +sssssssss$2hmydMMMMMMMNddddy$1ssssssss+ + /ssssssss$2hNMMMyhhyyyyhmNMMMNh$1ssssssss/ +.ssssssss$2dMMMNh$1ssssssssss$2hNMMMd$1ssssssss. ++ssss$2hhhyNMMNy$1ssssssssssss$2yNMMMy$1sssssss+ +oss$2yNMMMNyMMh$1ssssssssssssss$2hmmmh$1ssssssso +oss$2yNMMMNyMMh$1ssssssssssssss$2hmmmh$1ssssssso ++ssss$2hhhyNMMNy$1ssssssssssss$2yNMMMy$1sssssss+ +.ssssssss$2dMMMNh$1ssssssssss$2hNMMMd$1ssssssss. + /ssssssss$2hNMMMyhhyyyyhdNMMMNh$1ssssssss/ + +sssssssss$2dmydMMMMMMMMddddy$1ssssssss+ + /sssssssssss$2hdmNNNNmyNMMMMh$1ssssss/ + .ossssssssssssssssss$2dMMMNy$1sssso. + -+sssssssssssssssss$2yyy$1ssss+- + `:+ssssssssssssssssss+:` + .-/+oossssoo+/-. \ No newline at end of file diff --git a/src/logo/ascii/ubuntu_small.txt b/src/logo/ascii/ubuntu_small.txt new file mode 100644 index 0000000000..491b534a6d --- /dev/null +++ b/src/logo/ascii/ubuntu_small.txt @@ -0,0 +1,6 @@ + _ + ---(_) + _/ --- \ +(_) | | + \ --- _/ + ---(_) \ No newline at end of file diff --git a/src/logo/ascii/ubuntu_studio.txt b/src/logo/ascii/ubuntu_studio.txt new file mode 100644 index 0000000000..16d5c4866c --- /dev/null +++ b/src/logo/ascii/ubuntu_studio.txt @@ -0,0 +1,20 @@ + ..-::::::-.` + `.:+++++++++++${c2}ooo${c1}++:.` + ./+++++++++++++${c2}sMMMNdyo${c1}+/. + .++++++++++++++++${c2}oyhmMMMMms${c1}++. + `/+++++++++${c2}osyhddddhys${c1}+${c2}osdMMMh${c1}++/` + `+++++++++${c2}ydMMMMNNNMMMMNds${c1}+${c2}oyyo${c1}++++` + +++++++++${c2}dMMNhso${c1}++++${c2}oydNMMmo${c1}++++++++` + :+${c2}odmy${c1}+++${c2}ooysoohmNMMNmyoohMMNs${c1}+++++++: + ++${c2}dMMm${c1}+${c2}oNMd${c1}++${c2}yMMMmhhmMMNs+yMMNo${c1}+++++++ +`++${c2}NMMy${c1}+${c2}hMMd${c1}+${c2}oMMMs${c1}++++${c2}sMMN${c1}++${c2}NMMs${c1}+++++++. +`++${c2}NMMy${c1}+${c2}hMMd${c1}+${c2}oMMMo${c1}++++${c2}sMMN${c1}++${c2}mMMs${c1}+++++++. + ++${c2}dMMd${c1}+${c2}oNMm${c1}++${c2}yMMNdhhdMMMs${c1}+y${c2}MMNo${c1}+++++++ + :+${c2}odmy${c1}++${c2}oo${c1}+${c2}ss${c1}+${c2}ohNMMMMmho${c1}+${c2}yMMMs${c1}+++++++: + +++++++++${c2}hMMmhs+ooo+oshNMMms${c1}++++++++ + `++++++++${c2}oymMMMMNmmNMMMMmy+oys${c1}+++++` + `/+++++++++${c2}oyhdmmmmdhso+sdMMMs${c1}++/ + ./+++++++++++++++${c2}oyhdNMMMms${c1}++. + ./+++++++++++++${c2}hMMMNdyo${c1}+/. + `.:+++++++++++${c2}sso${c1}++:. + ..-::::::-.. diff --git a/src/logo/ascii/ubuntu_sway.txt b/src/logo/ascii/ubuntu_sway.txt new file mode 100644 index 0000000000..bbc2cc4edc --- /dev/null +++ b/src/logo/ascii/ubuntu_sway.txt @@ -0,0 +1,20 @@ + .-/+oossssoo+\-. + ´:+ssssssssssssssssss+:` + -+ssssssssssssssssss${c2}yy${c1}ssss+- + .ossssssssssssssssss${c2}dMMMNyy${c1}ssso. + /sssssssssss${c2}hdmmNNmmyNMMMMh${c1}ssssss\ + +sssssssss${c2}hm${c1}ydMMMMMMMNdd${c2}ddy${c1}ssssssss+ + /ssssssss${c2}hN${c1}MM${c2}M${c1}yh${c2}hyyyyhmNM${c1}MM${c2}Nh${c1}ssssssss\ +.ssssssss${c2}dM${c1}MM${c2}Nh${c1}ssssssssss${c2}hN${c1}MM${c2}Md${c1}ssssssss. ++sss${c2}yyyyyN${c1}MM${c2}Ny${c1}ssssssssssss${c2}yN${c1}MM${c2}My${c1}sssssss+ +ossy${c2}NMMMNy${c1}MM${c2}h${c1}ssssssssssssss${c2}hm${c1}mm${c2}h${c1}ssssssso +ossy${c2}NMMMNy${c1}MM${c2}h${c1}sssssssssssssshmmmh${c1}ssssssso ++sss${c2}yyyyyN${c1}MM${c2}Ny${c1}ssssssssssss${c2}yN${c1}MM${c2}My${c1}sssssss+ +.ssssssss${c2}dM${c1}MM${c2}Nh${c1}ssssssssss${c2}hN${c1}MM${c2}Md${c1}ssssssss. + \ssssssss${c2}hN${c1}MM${c2}M${c1}yh${c2}hyyyyhdNM${c1}M${c2}MNh${c1}ssssssss/ + +sssssssss${c2}dm${c1}ydMMMMMMMMdd${c2}ddy${c1}ssssssss+ + \sssssssssss${c2}hdmNNNNmyNMMMMh${c1}ssssss/ + .ossssssssssssssssss${c2}dMMMNyy${c1}ssso. + -+sssssssssssssssss${c2}yy${c1}sss+- + `:+ssssssssssssssssss+:` + .-\+oossssoo+/-. diff --git a/src/logo/ascii/ubuntu_touch.txt b/src/logo/ascii/ubuntu_touch.txt new file mode 100644 index 0000000000..4801edb086 --- /dev/null +++ b/src/logo/ascii/ubuntu_touch.txt @@ -0,0 +1,7 @@ + ############### + ## ## +## ${c2}##${c1} ${c2}##${c1} ## +## ${c2}##${c1} ${c2}#${c1} ${c2}#${c1} ${c2}##${c1} ## +## ${c2}###${c1} ## + ## ## + ############### diff --git a/src/logo/ascii/ubuntu_unity.txt b/src/logo/ascii/ubuntu_unity.txt new file mode 100644 index 0000000000..2de1ead726 --- /dev/null +++ b/src/logo/ascii/ubuntu_unity.txt @@ -0,0 +1,25 @@ + .-/+ooosssssssooo+\-. + ,:+sssssssssssssssssssss+:. + -+ssssssssssssssssssss${c2}.....${c1}ssss+- + .ssssss${c2},${c1}ss${c2}:cloooooo:${c1}ss${c2}.:loooo.${c1}ssssss. + .ssssssss${c2}loo${c1}ss${c2}oooooooc${c1}ss${c2}.ooooooooo${c1}ssssss. + .ssssss${c2}.;looooool:,''.${c1}ss${c2}:ooooooooooc${c1}ssssss. + +ssssss${c2};loooool;.${c1}ssssssssss${c2}ooooooooo${c1}ssssssss+ + /ssssss${c2};clool'${c1}sssssssssssssss${c2}ooooooc${c1}ssss${c2},,${c1}sssss. +.sssssssssssssssssssssssssssssssssssss${c2}.:oo,${c1}sssss. +.sssss${c2}.;clol:,.${c1}ssssssssssssssssssssss${c2}.loooo'${c1}ssss. ++ssss${c2}:ooooooooo,${c1}ssssssssssssssssssssss${c2}'ooool${c1}ssss+ +osss${c2}'ooooooooooo.${c1}ssssssssssssssssssssss${c2}loooo.${c1}ssso +osss${c2}'ooooooooool${c1}sssssssssssssssssssssss${c2}co${c1}ssssssso +ossss${c2},looooooc.${c1}sssssssssssssssssssssss${c2}.loooo.${c1}ssso ++ssssss${c2}.,;;;'.${c1}ssssssssssssssssssssssss${c2};ooooc${c1}ssss+ +.ssssssssssssssssssssssssssssssssssss${c2},ooool.${c1}ssss. +.sssssss${c2}.cooooc.${c1}sssssssssssss${c2}.,,,,.${c1}ss${c2}.cooo.${c1}sssss. + `sssssss${c2}ooooo:.${c1}ssssssssssss${c2}oooooooc.${c1}ss${c2}:l.${c1}sssss' + +ssssss${c2}.coooooc,..${c1}sssssss${c2}cooooooooo.${c1}ssssssss+ + `sssssss${c2}.:oo${c1}s${c2}ooooolc:.${c1}s${c2}.ooooooooooo'${c1}ssssss' + .sssssss${c2}.o${c1}ss${c2}`:loooo;${c1}sss${c2},ooooooooc${c1}sssssss. + `sssssssss${c2};oooo';:c'${c1}ssss${c2}`:ooo:'${c1}sssssss' + -+sssssssssssssssssssssssssssssss+- + `:+sssssssssssssssssssssss+:' + `-\+ooosssssssooo+/-' diff --git a/src/logo/ascii/ultramarine.txt b/src/logo/ascii/ultramarine.txt new file mode 100644 index 0000000000..ef40337203 --- /dev/null +++ b/src/logo/ascii/ultramarine.txt @@ -0,0 +1,20 @@ + .cd0NNNNNNNXOdc. + .:xKNNNNNNNNNNNNNNNNKd;. + ,dXNNNNNNNNNNNNNNNNNNNNNNNd, + 'ONNNNNNNNNNNNNNNNNNNNNNNNNNNNO' + .xNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNk. + .0NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN0. +.0NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN0. +dNNNNNNNNNNNNWWWWWWWWNNNNNNNNNNNNNNNNNNd +NNNNNNNNNNNNNW${c2}MMMMMMMM${c1}WWNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNW${c2}MMMMMMMMM${c1}WWNNNNNNNNNNNNNN +NNNNNNNNNNNNNNW${c2}MMMMMMMMMMMM${c1}WNNNNNNNNNNNN +NNNNNNNNNNWWW${c2}MMMMMMMMMMMMMMMM${c1}WWWNNNNNNNX +oNWWWW${c2}MMMMMMMMMMMMMMMMMMMMMMMMMMMM${c1}WWWNNo + OW${c2}MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM${c1}WO + .OW${c2}MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM${c1}WO. + lNW${c2}MMMMMMMMMMMMMMMMMMMMMMMMMMMM${c1}WNl + .dNW${c2}MMMMMMMMMMMMMMMMMMMMMMMM${c1}WNd. + .cKW${c2}MMMMMMMMMMMMMMMMMMMM${c1}WKc. + 'oOXWWW${c2}MMMMMMMM${c1}WWWXOl. + ;lkXNNNNNNXkl' diff --git a/src/logo/ascii/univalent.txt b/src/logo/ascii/univalent.txt new file mode 100644 index 0000000000..8a398745f7 --- /dev/null +++ b/src/logo/ascii/univalent.txt @@ -0,0 +1,18 @@ +UUUUUUU UUUUUUU +UUUUUUU UUUUUUU +UUUUUUU A UUUUUUU +UUUUUUU A|A UUUUUUU +UUUUUUU A | A UUUUUUU +UUUUUUU A | A UUUUUUU +UUUUUUU A| | |A UUUUUUU +UUUUUUU A | | | A UUUUUUU +UUUUUUU A | | | A UUUUUUU +UUUUUUU A | | | A UUUUUUU +UUUUUUU A | | | A UUUUUUU +UUUUUUU A | | | A UUUUUUU +UUUUUUU A | | | A UUUUUUU + UUUUUUU A | | | A UUUUUUU + UUUUUUU A | | | A UUUUUUU + UUUUUUUAAAAAAAAAAAUUUUUUU + UUUUUUUUUUUUUUUUUUU + UUUUUUUUUUUUU diff --git a/src/logo/ascii/univention.txt b/src/logo/ascii/univention.txt new file mode 100644 index 0000000000..0d5221dba3 --- /dev/null +++ b/src/logo/ascii/univention.txt @@ -0,0 +1,20 @@ + ./osssssssssssssssssssssso+- + `ohhhhhhhhhhhhhhhhhhhhhhhhhhhhy: + shhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh- + `-//${c2}sssss${c1}/hhhhhhhhhhhhhh+${c2}s${c1}.hhhhhhhhh+ + .ohhhy${c2}sssss${c1}.hhhhhhhhhhhhhh.${c2}sss${c1}+hhhhhhh+ +.yhhhhy${c2}sssss${c1}.hhhhhhhhhhhhhh.${c2}ssss${c1}:hhhhhh+ ++hhhhhy${c2}sssss${c1}.hhhhhhhhhhhhhh.${c2}sssss${c1}yhhhhh+ ++hhhhhy${c2}sssss${c1}.hhhhhhhhhhhhhh.${c2}sssss${c1}yhhhhh+ ++hhhhhy${c2}sssss${c1}.hhhhhhhhhhhhhh.${c2}sssss${c1}yhhhhh+ ++hhhhhy${c2}sssss${c1}.hhhhhhhhhhhhhh.${c2}sssss${c1}yhhhhh+ ++hhhhhy${c2}sssss${c1}.hhhhhhhhhhhhhh.${c2}sssss${c1}yhhhhh+ ++hhhhhy${c2}sssss${c1}.hhhhhhhhhhhhhh.${c2}sssss${c1}yhhhhh+ ++hhhhhy${c2}sssss${c1}.hhhhhhhhhhhhhh.${c2}sssss${c1}yhhhhh+ ++hhhhhy${c2}ssssss${c1}+yhhhhhhhhhhy/${c2}ssssss${c1}yhhhhh+ ++hhhhhh:${c2}sssssss${c1}:hhhhhhh+${c2}.ssssssss${c1}yhhhhy. ++hhhhhhh+`${c2}ssssssssssssssss${c1}hh${c2}sssss${c1}yhhho` ++hhhhhhhhhs+${c2}ssssssssssss${c1}+hh+${c2}sssss${c1}/:-` +-hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhho + :yhhhhhhhhhhhhhhhhhhhhhhhhhhhh+` + -+ossssssssssssssssssssss+:` diff --git a/src/logo/ascii/unknown.txt b/src/logo/ascii/unknown.txt new file mode 100644 index 0000000000..ed7418eaae --- /dev/null +++ b/src/logo/ascii/unknown.txt @@ -0,0 +1,18 @@ + ________ + _jgN########Ngg_ + _N##N@@"" ""9NN##Np_ +d###P N####p +"^^" T#### + d###P + _g###@F + _gN##@P + gN###F" + d###F + 0###F + 0###F + 0###F + "NN@' + + ___ + q###r + "" \ No newline at end of file diff --git a/src/logo/ascii/uos.txt b/src/logo/ascii/uos.txt new file mode 100644 index 0000000000..82d9688668 --- /dev/null +++ b/src/logo/ascii/uos.txt @@ -0,0 +1,20 @@ + ....... + .............. + ...................... + ............................. +uuuuuu uuuuuu ooooooooooo ssssssssss +u::::u u::::u oo:::::::::::oo ss::::::::::s +u::::u u::::u o:::::::::::::::oss:::::::::::::s +u::::u u::::u o:::::ooooo:::::os::::::ssss:::::s +u::::u u::::u o::::o o::::o s:::::s ssssss +u::::u u::::u o::::o o::::o s::::::s +u::::u u::::u o::::o o::::o s::::::s +u:::::uuuu:::::u o::::o o::::ossssss s:::::s +u:::::::::::::::uuo:::::ooooo:::::os:::::ssss::::::s +u:::::::::::::::uo:::::::::::::::os::::::::::::::s +uu::::::::uu:::u oo:::::::::::oo s:::::::::::ss + uuuuuuuu uuuu ooooooooooo sssssssssss + ............................. + ..................... + ............. + ...... \ No newline at end of file diff --git a/src/logo/ascii/urukos.txt b/src/logo/ascii/urukos.txt new file mode 100644 index 0000000000..8b42721cee --- /dev/null +++ b/src/logo/ascii/urukos.txt @@ -0,0 +1,20 @@ + ${c3}:${c4}:::::::::::::: ${c5}. + ${c3}=#${c4}*============. ${c5}:#: + ${c3}=##%${c4}+----------. ${c5}.###: + ${c3}=####. ${c5}.####: + ${c3}=####. ${c5}.####: + ${c3}=###*. .=${c4}--------. ${c5}####: + ${c3}=####. .*#+${c4}======- ${c5}####: + ${c3}=###*. .*###+${c4}====- ${c5}####: + ${c3}=###*. .*#####+${c4}==- ${c5}####: +${c3}=###*. .*#######+${c4}: ${c5}####: +${c3}=###*. .*#######+${c4}: ${c5}####: + ${c3}=###*. .*#####+${c4}==- ${c5}####: + ${c3}=###*. .*###+${c4}====- ${c5}####: + ${c3}=####. .*#+${c4}======- ${c5}####: + ${c3}=###*. .=${c4}--------. ${c5}.####: + ${c3}=####. ${c5}.####: + ${c3}=####. ${c5}.####: + ${c3}=###+${c4}--------------${c5}####: + ${c3}=#+${c4}=================-${c5}: + ${c3}:${c4}::::::::::::::::::. diff --git a/src/logo/ascii/uwuntu.txt b/src/logo/ascii/uwuntu.txt new file mode 100644 index 0000000000..e5246fa736 --- /dev/null +++ b/src/logo/ascii/uwuntu.txt @@ -0,0 +1,20 @@ + && + &&&&&&&& + , *&&&&&& &&&&&&&&( + &%%%%&&&& &&&&&&&&&&&& ,&&&&& + %%${c2}%%%%&&${c1}&&& ,&&&&&&&&&&&&&, %&&&$&&&%%$%%%. + &%%%${c2}%&&&&&${c1}&&# &, &&&&&&${c2}&&&&&&&%%%${c1}%% + &%%&&${c2}&&&&${c1}&&&( &&&${c2}&&&&&&%${c1}%%% + &&&&&${c2}&&&${c1}&% *&&${c2}&&&&&${c1}&&% + &&&/ &&&&${c3}\${c1}& ,${c3}/${c1}*.** + %&&&&&&&& &&&${c3}⟩${c1}., *.${c3}⟨${c1} + %&&&&&&&& &&${c3}/${c1}.. ${c3}/ \${c1} ..${c3}\${c1}(&&&&&& + #&&&#%%%%.%%%( ${c3}\_/\_/${c1} (%%%.%%%%/ + /%%%%%%%&&* ,&&&%%%%%%& + &&&&&&&& &&&&&&&&&&& + (&&&&& &&&&&&&&&&& + ${c2}%%${c1} & &&&&&&&&&&&& &&&&&&& + ${c2}%%%${c1} #&&&&&&# &&&&&&&&& + ${c2}%%%%% %%${c1} #&&&&&( +${c2}&%. %%%${c1} + ${c2}%%%%%%% diff --git a/src/logo/ascii/vanilla.txt b/src/logo/ascii/vanilla.txt new file mode 100644 index 0000000000..ab5631ca7e --- /dev/null +++ b/src/logo/ascii/vanilla.txt @@ -0,0 +1,18 @@ + .----: + .-------. + :---::----: + .----::-----. + ......... :----::-----: ..:::-::::.. +.-----------------::------------------: + ----::-----------::----------::::---: + -----:::--------::-------:::------- + :------::::--::...:::::---------: + .---------::.. ..:---------. + .::-----::.. .::----::. + .:------:.......:-------: + .--------::::::::-:::-------. + .-------::-----.:-----::------. + -----::------: :------::----- + :--::--------: .-------::---: + :----------:: .:---------- + :--------: :--------: \ No newline at end of file diff --git a/src/logo/ascii/venom.txt b/src/logo/ascii/venom.txt new file mode 100644 index 0000000000..680c12f94a --- /dev/null +++ b/src/logo/ascii/venom.txt @@ -0,0 +1,15 @@ +::::::: ::::::: +mMMMMMMm dMMMMMMm +/MMMMMMMo +MMMMMMM/ + yMMMMMMN mMMMMMMy + NMMMMMMs oMMMMMMm + +MMMMMMN: NMMMMMM+ + hMMMMMMy sMMMMMMy + :NMMMMMM::NMMMMMN: + oMMMMMMyyMMMMMM+ + dMMMMMMMMMMMMh + /MMMMMMMMMMMN: + sMMMMMMMMMMo + mMMMMMMMMd + +MMMMMMMN: + :::::: diff --git a/src/logo/ascii/vnux.txt b/src/logo/ascii/vnux.txt new file mode 100644 index 0000000000..ade7e29f2c --- /dev/null +++ b/src/logo/ascii/vnux.txt @@ -0,0 +1,20 @@ + ` + ^[XOx~. + ^_nwdbbkp0ti' + +${c2} _j>!vC1,, + ${c4},${c2} ,CY${c3}O${c2}t${c3}O${c2}1(l;" +`${c4}~-{r(1I${c2} ^${c1}/zmwJuc:${c2}I^ +'${c4}?)|${c1}U${c4}/}-${c2} ^${c3}f${c1}OCLLOw${c3}_${c2},; + ,${c4}i,``. ${c2}",${c3}k%ooW@$d"${c2}I,' + ' ;^${c3}u$$$$$$$$$$$$$$$$^<${c2}:^ + ` .>>${c3}($$$$${c5}$@@@@$$$$${c3}$nl${c2}[:: + `!}?${c3}B$$${c5}%&WMMW&%$$${c3}$1}-${c2}}": + ^?j${c3}Z$$${c5}WMMWWWWMMW$$${c3}ofc${c2};;` + <~x&${c3}$$${c5}&MWWWWWWWWp${c3}-${c5}l>[< +${c1} 'ljmwn${c2}~tk8${c5}MWWWWM8O${c2}X${c1}r${c2}+]nC${c1}[ +!JZqwwdX${c2}:^C8${c5}#MMMM@${c2}X${c1}Odpdpq0< + ^x00J(" + ^" diff --git a/src/logo/ascii/void.txt b/src/logo/ascii/void.txt new file mode 100644 index 0000000000..4b1ad9a5df --- /dev/null +++ b/src/logo/ascii/void.txt @@ -0,0 +1,18 @@ + __.;=====;.__ + _.=+==++=++=+=+===;. + -=+++=+===+=+=+++++=_ + . -=:`` `--==+=++==. + _vi, ` --+=++++: + .uvnvi. _._ -==+==+. + .vvnvnI` .;==|==;. :|=||=|. +$2+QmQQm$1pvvnv;$2 _yYsyQQWUUQQQm #QmQ#$1:$2QQQWUV$QQm. + $2-QQWQW$1pvvo$2wZ?.wQQQE$1==<$2QWWQ/QWQW.QQWW$1(:$2 jQWQE + $2-$QQQQmmU' jQQQ$1@+=<$2QWQQ)mQQQ.mQQQC$1+;$2jWQQ@' + $2-$WQ8Y$1nI:$2 QWQQwgQQWV$1`$2mWQQ.jQWQQgyyWW@! + $1-1vvnvv. `~+++` ++|+++ + +vnvnnv, `-|=== + +vnvnvns. . :=- + -Invnvvnsi..___..=sv=. ` + +Invnvnvnnnnnnnnvvnn;. + ~|Invnvnvvnvvvnnv}+` + -~|{*l}*|~ \ No newline at end of file diff --git a/src/logo/ascii/void_small.txt b/src/logo/ascii/void_small.txt new file mode 100644 index 0000000000..e9602b027a --- /dev/null +++ b/src/logo/ascii/void_small.txt @@ -0,0 +1,7 @@ + _______ + _ \______ - +| \ ___ \ | +| | / \ | | +| | \___/ | | +| \______ \_| + -_______\ \ No newline at end of file diff --git a/src/logo/ascii/vzlinux.txt b/src/logo/ascii/vzlinux.txt new file mode 100644 index 0000000000..334177f3ce --- /dev/null +++ b/src/logo/ascii/vzlinux.txt @@ -0,0 +1,20 @@ + ${c1}.::::::::.${c2} +`/////` ${c1}:zzzzzzzz${c2} ://///- + VVVVVu` ${c1}-zzz`${c2} /VVVVV. + `dVVVVV ${c1}.zzz`${c2} :VVVVV: + `VVVVVo ${c1}zzz${c2} -VVVVV/ + .VVVVV\ ${c1}zzz/${c2} .VVVVV+ + -VVVVV: ${c1}zzzzzzzzz${c2} .dVVVVs + \VVVVV- ${c1}`````````${c2} VVVVVV + +VVVVV. sVVVVu` + oVVVVd` +VVVVd` + VVVVVV /VVVVV. + `uVVVVs -VVVVV- + `dVVVV+ .VVVVV/ + .VVVVV\ `dVVVV+ + -VVVVV-`uVVVVo + :VVVVVVVVVVV + \VVVVVVVVu + oVVVVVVd` + sVVVVV. + ----. diff --git a/src/logo/ascii/wii_linux_ngx.txt b/src/logo/ascii/wii_linux_ngx.txt new file mode 100644 index 0000000000..daafdc208d --- /dev/null +++ b/src/logo/ascii/wii_linux_ngx.txt @@ -0,0 +1,16 @@ +''''''' `~;:` -'''''' ~kQ@@g\ ,EQ@@g/ +h@@@@@@' o@@@@@9` `@@@@@@D `@@@@@@@= @@@@@@@? +'@@@@@@X o@@@@@@@D v@@@@@@: R@@@@@@, D@@@@@@_ + t@@@@@@' _@@@@@@@@@; `Q@@@@@U ;fmo/- ;fmo/- + `Q@@@@@m d@@@@@@@@@N 7@@@@@@' + L@@@@@@' :@@@@@&@@@@@| `Q@@@@@Z :]]]]]v :]]]]]v + Q@@@@@X R@@@@Q`g@@@@Q f@@@@@Q- z@@@@@Q v@@@@@Q + r@@@@@@~ ;@@@@@/ ;@@@@@L `@@@@@@/ z@@@@@Q v@@@@@Q + d@@@@@q M@@@@# H@@@@Q ]@@@@@Q z@@@@@Q v@@@@@Q + ,@@@@@@, >@@@@@; _@@@@@c `@@@@@@> z@@@@@Q v@@@@@Q + X@@@@@U Q@@@@R Z@@@@Q`{@@@@@N z@@@@@Q v@@@@@Q + .@@@@@@S@@@@@: -@@@@@e@@@@@@: z@@@@@Q v@@@@@Q + {@@@@@@@@@@U t@@@@@@@@@@e z@@@@@Q v@@@@@Q + `Q@@@@@@@@@' `Q@@@@@@@@@- z@@@@@Q v@@@@@Q + :@@@@@@@@| ;@@@@@@@@= z@@@@@Q v@@@@@Q + '2#@@Q6: ,eQ@@QZ~ /QQQQQg \QQQQQN diff --git a/src/logo/ascii/windows.txt b/src/logo/ascii/windows.txt new file mode 100644 index 0000000000..ffe0410ef6 --- /dev/null +++ b/src/logo/ascii/windows.txt @@ -0,0 +1,16 @@ +$1 ,.=:!!t3Z3z., + :tt:::tt333EE3 +$1 Et:::ztt33EEEL$2 @Ee., .., +$1 ;tt:::tt333EE7$2 ;EEEEEEttttt33# +$1 :Et:::zt333EEQ.$2 $EEEEEttttt33QL +$1 it::::tt333EEF$2 @EEEEEEttttt33F +$1 ;3=*^```"*4EEV$2 :EEEEEEttttt33@. +$3 ,.=::::!t=., $1`$2 @EEEEEEtttz33QF +$3 ;::::::::zt33)$2 "4EEEtttji3P* +$3 :t::::::::tt33.$4:Z3z..$2 ``$4 ,..g. +$3 i::::::::zt33F$4 AEEEtttt::::ztF +$3 ;:::::::::t33V$4 ;EEEttttt::::t3 +$3 E::::::::zt33L$4 @EEEtttt::::z3F +$3{3=*^```"*4E3)$4 ;EEEtttt:::::tZ` +$3 `$4 :EEEEtttt::::z7 + "VEzjt:;;z>*` \ No newline at end of file diff --git a/src/logo/ascii/windows_11.txt b/src/logo/ascii/windows_11.txt new file mode 100644 index 0000000000..1fd966753a --- /dev/null +++ b/src/logo/ascii/windows_11.txt @@ -0,0 +1,17 @@ +$1///////////////// $2///////////////// +$1///////////////// $2///////////////// +$1///////////////// $2///////////////// +$1///////////////// $2///////////////// +$1///////////////// $2///////////////// +$1///////////////// $2///////////////// +$1///////////////// $2///////////////// +$1///////////////// $2///////////////// + +$3///////////////// $4///////////////// +$3///////////////// $4///////////////// +$3///////////////// $4///////////////// +$3///////////////// $4///////////////// +$3///////////////// $4///////////////// +$3///////////////// $4///////////////// +$3///////////////// $4///////////////// +$3///////////////// $4///////////////// \ No newline at end of file diff --git a/src/logo/ascii/windows_11_small.txt b/src/logo/ascii/windows_11_small.txt new file mode 100644 index 0000000000..c04184f246 --- /dev/null +++ b/src/logo/ascii/windows_11_small.txt @@ -0,0 +1,9 @@ +$1lllllllll $2lllllllll +$1lllllllll $2lllllllll +$1lllllllll $2lllllllll +$1lllllllll $2lllllllll + +$3lllllllll $4lllllllll +$3lllllllll $4lllllllll +$3lllllllll $4lllllllll +$3lllllllll $4lllllllll diff --git a/src/logo/ascii/windows_8.txt b/src/logo/ascii/windows_8.txt new file mode 100644 index 0000000000..a357dda2fa --- /dev/null +++ b/src/logo/ascii/windows_8.txt @@ -0,0 +1,19 @@ + $2.., + ....,,:;+ccllll +$1 ...,,+:; $2cllllllllllllllllll +$1,cclllllllllll $2lllllllllllllllllll +$1llllllllllllll $2lllllllllllllllllll +$1llllllllllllll $2lllllllllllllllllll +$1llllllllllllll $2lllllllllllllllllll +$1llllllllllllll $2lllllllllllllllllll +$1llllllllllllll $2lllllllllllllllllll + +$3llllllllllllll $4lllllllllllllllllll +$3llllllllllllll $4lllllllllllllllllll +$3llllllllllllll $4lllllllllllllllllll +$3llllllllllllll $4lllllllllllllllllll +$3llllllllllllll $4lllllllllllllllllll +$3`'ccllllllllll $4lllllllllllllllllll +$3 `' \*:: $4:ccllllllllllllllll + ````''*::cll + `` \ No newline at end of file diff --git a/src/logo/ascii/windows_95.txt b/src/logo/ascii/windows_95.txt new file mode 100644 index 0000000000..7cb886ccf9 --- /dev/null +++ b/src/logo/ascii/windows_95.txt @@ -0,0 +1,18 @@ +$6 ___ + .--=+++++=-:. +. _ *%@@@@@@@@@@@@@@* + *:+:.__ :+* @@@ @"$5_*&%$6@@$4%&&&*$6"@@@ + "+.-#+ +%* " _ $5++&&&%$6@@$4%&&&&&#$6@@ +$5" , $6%@@ $5&&&&&%$6@@$4%&&&&&#$6@@ +$5 * oo *# $6" _ $5&&&&&%$6@@$4%&&&&&#$6@@ +$5" , $6%@@ $5&&&&"$6@@@@#*$4"&&&$6@@ +.$5 * oo *# $6" _ %@@@@@@@@@@@@@@@@ + *:+:.__ :=* %@@ @"$1**&%$6@@$3%&&&*$6"@@@ + "+.-#+ +%* " _ $1&&&&&%$6@@$3%&&&&&#$6@@ +$1" , $6%@@ $1&&&&&%$6@@$3%&&&&&#$6@@ +$1 * oo *# $6" _ $1&&&&&%$6@@$3%&&&&&#$6@@ +$1" , $6%@@ $1&&*"$6%@@@@@@$3"*%&$6@@ +.$1 * oo *# $6" _ @@@@@@@@@@@@@@@@@ + *:+:.__ :+# @@@ @%#=+""""""+==%#@ + "+.-#+ +%* %+" " ":@ + " " \ No newline at end of file diff --git a/src/logo/ascii/xferience.txt b/src/logo/ascii/xferience.txt new file mode 100644 index 0000000000..96b1b4e5cd --- /dev/null +++ b/src/logo/ascii/xferience.txt @@ -0,0 +1,19 @@ + ``--:::::::-.` + .-/+++ooooooooo+++:-` + `-/+oooooooooooooooooo++:. + -/+oooooo/+ooooooooo+/ooo++:` + `/+oo++oo. .+oooooo+.-: +:-o+- + `/+o/. -o. :oooooo+ ```:.+oo+- +`:+oo- -/` :oooooo+ .`-`+oooo/. +.+ooo+. .` `://///+-+..oooooo+:` +-+ooo:` ``.-+oooooo+/` +-+oo/` :+oooo/. +.+oo: ..-/. . -+oo+/` +`/++- -:::++::/. -+oo+- + ./o: `:///+- `./ooo+:` + .++- `` /-` -:/+oooo+:` + .:+/:`` `-:ooooooo++- + ./+o+//:...../+oooooooo++:` + `:/++ooooooooooooo++/-` + `.-//++++++//:-.` + `````` diff --git a/src/logo/ascii/yiffos.txt b/src/logo/ascii/yiffos.txt new file mode 100644 index 0000000000..6a07889296 --- /dev/null +++ b/src/logo/ascii/yiffos.txt @@ -0,0 +1,19 @@ + NK + NxKXW + WOlcoXW + 0olccloxNW + XxllllllloxOKNW + Nklllllllllllodk0XWW + N0dllllllllllllllodxOKNW + WKxlllllllllllllllllllooxOKN + WKdllllllllllllllooooooooooooo + Nxllllllllllllllloooooooooo${c2}oooo +${c1} XXNOolllllllllllloooooooooo${c2}oooooo +${c1} WX0xolllllllllllooooooooooo${c2}oooooooo +${c1}XWN0xolllllllllloooooooo${c2}ooooooooooooo +${c1} Kkdolllllllooooddddd${c2}doooooooooooddo +${c1} K00XNW${c2} WX0xdooooooddddddd + WXOxdoooooodddd + WXOxdddddddd + NX0ddd + WN0d diff --git a/src/logo/ascii/zorin.txt b/src/logo/ascii/zorin.txt new file mode 100644 index 0000000000..886f74b234 --- /dev/null +++ b/src/logo/ascii/zorin.txt @@ -0,0 +1,17 @@ + `osssssssssssssssssssso` + .osssssssssssssssssssssso. + .+oooooooooooooooooooooooo+. + + + `::::::::::::::::::::::. .:` + `+ssssssssssssssssss+:.` `.:+ssso` +.ossssssssssssssso/. `-+ossssssso. +ssssssssssssso/-` `-/osssssssssssss +.ossssssso/-` .-/ossssssssssssssso. + `+sss+:. `.:+ssssssssssssssssss+` + `:. .::::::::::::::::::::::` + + + .+oooooooooooooooooooooooo+. + -osssssssssssssssssssssso- + `osssssssssssssssssssso` \ No newline at end of file diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 4962331e3d..8e1438d5be 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1,2697 +1,4074 @@ #include "logo.h" - -#define FF_LOGO_INIT static FFlogo logo; static bool init = false; if(init) return &logo; init = true; -#define FF_LOGO_NAMES(...) static const char* names[] = (const char*[]) { __VA_ARGS__, NULL }; logo.names = names; -#define FF_LOGO_LINES(x) logo.data = x; -#define FF_LOGO_COLORS(...) static const char* colors[] = (const char*[]) { __VA_ARGS__, NULL }; logo.builtinColors = colors; -#define FF_LOGO_COLOR_KEYS(x) logo.colorKeys = x; -#define FF_LOGO_COLOR_TITLE(x) logo.colorTitle = x; -#define FF_LOGO_RETURN return &logo; - -const FFlogo* ffLogoBuiltinGetUnknown() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("unknown", "question mark", "?") - FF_LOGO_LINES( - " ________\n" - " _jgN########Ngg_\n" - " _N##N@@\"\" \"\"9NN##Np_\n" - "d###P N####p\n" - "\"^^\" T####\n" - " d###P\n" - " _g###@F\n" - " _gN##@P\n" - " gN###F\"\n" - " d###F\n" - " 0###F\n" - " 0###F\n" - " 0###F\n" - " \"NN@'\n" - "\n" - " ___\n" - " q###r\n" - " \"\"" - ) - FF_LOGO_COLORS("") - FF_LOGO_COLOR_KEYS("") - FF_LOGO_COLOR_TITLE("") - FF_LOGO_RETURN -} - -static const FFlogo* getLogoAlmaLinux() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("almalinux") - FF_LOGO_LINES( - "$1 'c:.\n" - "$1 lkkkx, .. $2.. ,cc,\n" - "$1 okkkk:ckkx' $2.lxkkx.okkkkd\n" - "$1 .:llcokkx' $2:kkkxkko:xkkd,\n" - "$1 .xkkkkdood: $2;kx, .lkxlll;\n" - "$1 xkkx. $2xk' xkkkkk:\n" - "$1 'xkx. $2xd .....,.\n" - "$3 .. $1:xkl' $2:c ..''..\n" - "$3 .dkx' $1.:ldl:'. $2' $4':lollldkkxo;\n" - "$3 .''lkkko' $4ckkkx.\n" - "$3'xkkkd:kkd. .. $5;' $4:kkxo.\n" - "$3,xkkkd;kk' ,d; $5ld. $4':dkd::cc,\n" - "$3 .,,.;xkko'.';lxo. $5dx, $4:kkk'xkkkkc\n" - "$3 'dkkkkkxo:. $5;kx $4.kkk:;xkkd.\n" - "$3 ..... $5.;dk:. $5lkk. $4:;,\n" - " $5:kkkkkkkdoxkkx\n" - " ,c,,;;;:xkkd.\n" - " ;kkkkl...\n" - " ;kkkkl\n" - " ,od;"; - ) - FF_LOGO_COLORS( - "31", // red - "1;33", // yellow - "34", // blue - "1;32", // light green - "36" // cyan - ) - FF_LOGO_COLOR_KEYS("1;33"); //yellow - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoAlpine() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("alpine", "alpinelinux", "alpine-linux") - FF_LOGO_LINES( - " .hddddddddddddddddddddddh.\n" - " :dddddddddddddddddddddddddd:\n" - " /dddddddddddddddddddddddddddd/\n" - " +dddddddddddddddddddddddddddddd+\n" - " `sdddddddddddddddddddddddddddddddds`\n" - " `ydddddddddddd++hdddddddddddddddddddy`\n" - ".hddddddddddd+` `+ddddh:-sdddddddddddh.\n" - "hdddddddddd+` `+y: .sddddddddddh\n" - "ddddddddh+` `//` `.` -sddddddddd\n" - "ddddddh+` `/hddh/` `:s- -sddddddd\n" - "ddddh+` `/+/dddddh/` `+s- -sddddd\n" - "ddd+` `/o` :dddddddh/` `oy- .yddd\n" - "hdddyo+ohddyosdddddddddho+oydddy++ohdddh\n" - ".hddddddddddddddddddddddddddddddddddddh.\n" - " `yddddddddddddddddddddddddddddddddddy`\n" - " `sdddddddddddddddddddddddddddddddds`\n" - " +dddddddddddddddddddddddddddddd+\n" - " /dddddddddddddddddddddddddddd/\n" - " :dddddddddddddddddddddddddd:\n" - " .hddddddddddddddddddddddh."; - ) - FF_LOGO_COLORS( - "34" //blue - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoAlpineSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("alpine_small", "alpine-linux-small") - FF_LOGO_LINES( - " /\\ /\\\n" - " // \\ \\\n" - " // \\ \\\n" - "/// \\ \\\n" - "// \\ \\\n" - " \\" - ) - FF_LOGO_COLORS( - "34" //blue - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoAndroid() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("android") - FF_LOGO_LINES( - " -o o-\n" - " +hydNNNNdyh+\n" - " +mMMMMMMMMMMMMm+\n" - " `dMM$2m:$1NMMMMMMN$2:m$1MMd`\n" - " hMMMMMMMMMMMMMMMMMMh\n" - " .. yyyyyyyyyyyyyyyyyyyy ..\n" - ".mMMm`MMMMMMMMMMMMMMMMMMMM`mMMm.\n" - ":MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:\n" - ":MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:\n" - ":MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:\n" - ":MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM:\n" - "-MMMM-MMMMMMMMMMMMMMMMMMMM-MMMM-\n" - " +yy+ MMMMMMMMMMMMMMMMMMMM +yy+\n" - " mMMMMMMMMMMMMMMMMMMm\n" - " `/++MMMMh++hMMMM++/`\n" - " MMMMo oMMMM\n" - " MMMMo oMMMM\n" - " oNMm- -mMNs" - ) - FF_LOGO_COLORS( - "32", //green - "37" //white - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoAndroidSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("android-small", "android_small") - FF_LOGO_LINES( - " ;, ,;\n" - " ';,.-----.,;'\n" - " ,' ',\n" - " / O O \\\n" - "| |\n" - "'-----------------'" - ) - FF_LOGO_COLORS( - "32" //green - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoArch() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("arch", "archlinux", "arch-linux") - FF_LOGO_LINES( - "$1 -`\n" - " .o+`\n" - " `ooo/\n" - " `+oooo:\n" - " `+oooooo:\n" - " -+oooooo+:\n" - " `/:-:++oooo+:\n" - " `/++++/+++++++:\n" - " `/++++++++++++++:\n" - " `/+++o$2oooooooo$1oooo/`\n" - " ./$2ooosssso++osssssso$1+`\n" - "$2 .oossssso-````/ossssss+`\n" - " -osssssso. :ssssssso.\n" - " :osssssss/ osssso+++.\n" - " /ossssssss/ +ssssooo/-\n" - " `/ossssso+/:- -:/+osssso+-\n" - " `+sso+:-` `.-/+oso:\n" - "`++:. `-/+/\n" - ".` `/"; - ) - FF_LOGO_COLORS( - "36", //cyan - "36" //cyan - ) - FF_LOGO_COLOR_KEYS("36"); //cyan - FF_LOGO_COLOR_TITLE("36"); //cyan - FF_LOGO_RETURN -} - -static const FFlogo* getLogoArchSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("arch_small", "archlinux_small", "arch-linux-small") - FF_LOGO_LINES( - " /\\\n" - " / \\\n" - " / \\\n" - " / \\\n" - " / ,, \\\n" - " / | | \\\n" - "/_-'' ''-_\\" - ) - FF_LOGO_COLORS( - "36" //cyan - ) - FF_LOGO_COLOR_KEYS("36"); //cyan - FF_LOGO_COLOR_TITLE("36"); //cyan - FF_LOGO_RETURN -} - -static const FFlogo* getLogoArtix() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("artix", "artixlinux", "artix-linux") - FF_LOGO_LINES( - " '\n" - " 'o'\n" - " 'ooo'\n" - " 'ooxoo'\n" - " 'ooxxxoo'\n" - " 'oookkxxoo'\n" - " 'oiioxkkxxoo'\n" - " ':;:iiiioxxxoo'\n" - " `'.;::ioxxoo'\n" - " '-. `':;jiooo'\n" - " 'oooio-.. `'i:io'\n" - " 'ooooxxxxoio:,. `'-;'\n" - " 'ooooxxxxxkkxoooIi:-. `'\n" - " 'ooooxxxxxkkkkxoiiiiiji'\n" - " 'ooooxxxxxkxxoiiii:'` .i'\n" - " 'ooooxxxxxoi:::'` .;ioxo'\n" - " 'ooooxooi::'` .:iiixkxxo'\n" - " 'ooooi:'` `'';ioxxo'\n" - " 'i:'` '':io'\n" - "'` `'"; - ) - FF_LOGO_COLORS( - "36" //cyan - ) - FF_LOGO_COLOR_KEYS("36"); //cyan - FF_LOGO_COLOR_TITLE("36"); //cyan - FF_LOGO_RETURN -} - -static const FFlogo* getLogoArtixSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("artix_small", "artixlinux_small", "artix-linux-small") - FF_LOGO_LINES( - " /\\\n" - " / \\\n" - " /`'.,\\\n" - " / ',\n" - " / ,`\\\n" - " / ,.'`. \\\n" - "/.,'` `'.\\" - ) - FF_LOGO_COLORS( - "36" //cyan - ) - FF_LOGO_COLOR_KEYS("36"); //cyan - FF_LOGO_COLOR_TITLE("36"); //cyan - FF_LOGO_RETURN -} - -static const FFlogo* getLogoArcoLinux() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("arco", "arcolinux", "arco-linux") - FF_LOGO_LINES( - " /-\n" - " ooo:\n" - " yoooo/\n" - " yooooooo\n" - " yooooooooo\n" - " yooooooooooo\n" - " .yooooooooooooo\n" - " .oooooooooooooooo\n" - " .oooooooarcoooooooo\n" - " .ooooooooo-oooooooooo\n" - " .ooooooooo- oooooooooo\n" - " :ooooooooo. :ooooooooo\n" - " :ooooooooo. :ooooooooo\n" - " :oooarcooo .oooarcooo\n" - " :ooooooooy .ooooooooo\n" - " $1:ooooooooo $2/ooooooooooooooooooo\n" - " $1:ooooooooo $2.-ooooooooooooooooo.\n" - " $1ooooooooo- $2-ooooooooooooo.\n" - " $1ooooooooo- $2.-oooooooooo.\n" - "$1ooooooooo. $2-ooooooooo"; - ) - FF_LOGO_COLORS( - "34", //blue - "32" //green - ) - FF_LOGO_COLOR_KEYS("34"); //green - FF_LOGO_COLOR_TITLE("34"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoBSD() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("bsd") - FF_LOGO_LINES( -"$1 , ,\n" -" /( )`\n" -" \\ \\___ / |\n" -" /- _ `-/ '\n" -" ($2/\\/ \\ $1\\ /\\\n" -" $2/ / | ` $1\\\n" -" $3O O $2) $1/ |\n" -" $2`-^--'$1`< '\n" -" (_.) _ ) /\n" -" `.___/` /\n" -" `-----' /\n" -"$4<----. __ / __ \\\n" -"$4<----|====$1O)))$4==$1) \\) /$4====|\n" -"<----' $1`--' `.__,' \\\n" -" | |\n" -" \\ / /\\\n" -" $5______$1( (_ / \\______/\n" -" $5,' ,-----' |\n" -" `--{__________)\n" - ) - FF_LOGO_COLORS( - "31", - "37", - "34", - "33", - "36" - ) - FF_LOGO_COLOR_KEYS("31"); - FF_LOGO_COLOR_TITLE("37"); - FF_LOGO_RETURN -} - -static const FFlogo* getLogoBedrock() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("bedrock", "bedrocklinux", "bedrock-linux") - FF_LOGO_LINES( - "--------------------------------------\n" - "--------------------------------------\n" - "--------------------------------------\n" - "---$2\\\\\\\\\\\\\\\\\\\\\\\\$1-----------------------\n" - "----$2\\\\\\ \\\\\\$1----------------------\n" - "-----$2\\\\\\ \\\\\\$1---------------------\n" - "------$2\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\$1------\n" - "-------$2\\\\\\ \\\\\\$1-----\n" - "--------$2\\\\\\ \\\\\\$1----\n" - "---------$2\\\\\\ ______ \\\\\\$1---\n" - "----------$2\\\\\\ ///$1---\n" - "-----------$2\\\\\\ ///$1----\n" - "------------$2\\\\\\ ///$1-----\n" - "-------------$2\\\\\\////////////////$1------\n" - "--------------------------------------\n" - "--------------------------------------\n" - "--------------------------------------" - ) - FF_LOGO_COLORS( - "90", //grey - "37" //white - ) - FF_LOGO_COLOR_KEYS("90"); //grey - FF_LOGO_COLOR_TITLE("37"); //white - FF_LOGO_RETURN -} - -static const FFlogo* getLogoCachyOS() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("cachy", "cachyos", "cachy-linux", "cachyos-linux") - FF_LOGO_LINES( - " $3.$1-------------------------:\n" - " .$2+=$1========================.\n" - " :$2++$1===$2++===$1===============- :$2++$1-\n" - " :$2*++$1====$2+++++==$1===========- .==:\n" - " -$2*+++$1=====$2+***++=$1=========:\n" - " =$2*++++=$1=======------------:\n" - " =$2*+++++=$1====- $3...$1\n" - " .$2+*+++++$1=-===: .$2=+++=$1:\n" - " :$2++++$1=====-==: -***$2**$1+\n" - " :$2++=$1=======-=. .=+**+$3.$1\n" - ".$2+$1==========-. $3.$1\n" - " :$2+++++++$1====- $3.$1--==-$3.$1\n" - " :$2++$1==========. $3:$2+++++++$1$3:\n" - " $1.-===========. =*****+*+\n" - " $1.-===========: .+*****+:\n" - " $1-=======$2++++$1:::::::::::::::::::::::::-: $3.$1---:\n" - " :======$2++++$1====$2+++******************=.\n" - " $1:=====$2+++$1==========$2++++++++++++++*-\n" - " $1.====$2++$1==============$2++++++++++*-\n" - " $1.===$2+$1==================$2+++++++:\n" - " $1.-=======================$2+++:\n" - " $3.........................." - ) - FF_LOGO_COLORS( - "36", //cyan - "32", //green - "30" //black - ) - FF_LOGO_COLOR_KEYS("36"); //cyan - FF_LOGO_COLOR_TITLE("36"); //cyan - FF_LOGO_RETURN -} - -static const FFlogo* getLogoCachyOSSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("cachy_small", "cachyos_small", "cachy-linux-small", "cachyos-linux-small") - FF_LOGO_LINES( - " /''''''''''''/\n" - " /''''''''''''/\n" - " /''''''/\n" - "/''''''/\n" - "\\......\\\n" - " \\......\\\n" - " \\.............../\n" - " \\............./\n" - ) - FF_LOGO_COLORS( - "36" //cyan - ) - FF_LOGO_COLOR_KEYS("36"); //cyan - FF_LOGO_COLOR_TITLE("36"); //cyan - FF_LOGO_RETURN -} - - -static const FFlogo* getLogoCelOS() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("cel", "celos", "cel-linux", "celos-linux") - FF_LOGO_LINES( - " `-:/++++/:-`\n" - " -/syyyyyyyyyyyyy+-\n" - " :ssssyyyyyyyyyyyyyyyy/\n" - " .osy$2mmmmmmmmmmmmmmmNNNNNmmhy+\n" - " $1.sssshhhhhhhddddddddddddddds-\n" - " $1`osssssssyyyyyyyyyyyyyyyyyyhy`\n" - " $1:ssssssyyyyyyyyyyyyyyyyyyyyhh/\n" - "$2sMMMMMMMMMMMMMMMMMMMMMMMh$1yyyyyyhho\n" - " :sssssssyyyyyyyyyyyyyyyyyyyhh/\n" - " `ssssssssyyyyyyyyyyyyyyyyyyhy.\n" - " -sssssyddddddddddddddddddddy\n" - " -ssss$2hmmmmmmmmmmmmmmmmmmmyssss-\n" - " $1`/ssssyyyyyyyyyyyyyyyy+`\n" - " $1`:osyyyyyyyyyyyyys/`\n" - " $1`.:/+ooooo+:-`" - ) - FF_LOGO_COLORS( - "35", //magenta - "30" //black - ) - FF_LOGO_COLOR_KEYS("36"); //cyan - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoCentOS() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("cent", "centos", "cent-linux", "centos-linux") - FF_LOGO_LINES( - " ..\n" - " .PLTJ.\n" - " <><><><>\n" - " $2KKSSV' 4KKK $1LJ$4 KKKL.'VSSKK\n" - " $2KKV' 4KKKKK $1LJ$4 KKKKAL 'VKK\n" - " $2V' ' 'VKKKK $1LJ$4 KKKKV' ' 'V\n" - " $2.4MA.' 'VKK $1LJ$4 KKV' '.4Mb.\n" - " $4. $2KKKKKA.' 'V $1LJ$4 V' '.4KKKKK $3.\n" - " $4.4D $2KKKKKKKA.'' $1LJ$4 ''.4KKKKKKK $3FA.\n" - "$4\n" - " '$4VD $3KKKKKKKK'.. $2LJ $1..'KKKKKKKK $3FV\n" - " $4' $3VKKKKK'. .4 $2LJ $1K. .'KKKKKV $3'\n" - " $3'VK'. .4KK $2LJ $1KKA. .'KV'\n" - " $3A. . .4KKKK $2LJ $1KKKKA. . .4\n" - " $3KKA. 'KKKKK $2LJ $1KKKKK' .4KK\n" - " $3KKSSA. VKKK $2LJ $1KKKV .4SSKK\n" - " $2<><><><>\n" - " $2'MKKM'\n" - " $2''" - ) - FF_LOGO_COLORS( - "33", //yellow - "32", //green - "34", //blue - "35", //magenta - "37" //white - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("33"); //yellow - FF_LOGO_RETURN -} - -static const FFlogo* getLogoCentOSSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("cent_small", "centos_small", "cent-linux_small", "cent-linux-small", "centos-linux-small") - FF_LOGO_LINES( - " $2____$1^$4____\n" - " $2|\\ $1|$4 /|\n" - " $2| \\ $1|$4 / |\n" - "$4<---- $3---->\n" - " $3| / $2|$1 \\ |\n" - " $3|/__$2|$1__\\|\n" - " $2v" - ) - FF_LOGO_COLORS( - "33", //yellow - "32", //green - "34", //blue - "35" //magenta - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("33"); //yellow - FF_LOGO_RETURN -} - -static const FFlogo* getLogoCRUX() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("CRUX", "crux") - FF_LOGO_LINES( - " $1odddd\n" - " oddxkkkxxdoo\n" - " ddcoddxxxdoool\n" - " xdclodod olol\n" - " xoc xdd olol\n" - " xdc $2k00$1Okdlol\n" - " xxd$2kOKKKOkd$1ldd\n" - " xdco$2xOkdlo$1dldd\n" - " ddc:cl$2lll$1oooodo\n" - " odxxdd$3xkO000kx$1ooxdo\n" - " oxddx$30NMMMMMMWW0o$1dkkxo\n" - " oooxd$30WMMMMMMMMMW0o$1dxkx\n" - "docldkXW$3MMMMMMMWWN$1Odolco\n" - "xx$2dx$1kxxOKN$3WMMWN$10xdoxo::c\n" - "$2xOkkO$10oo$3odOW$2WW$1XkdodOxc:l\n" - "$2dkkkxkkk$3OKX$2NNNX0Oxx$1xc:cd\n" - " $2odxxdx$3xllo$2dddooxx$1dc:ldo\n" - " $2lodd$1dolccc$2ccox$1xoloo\n" - ) - FF_LOGO_COLORS( - "34", //blue - "35", //magenta - "37" //white - ) - FF_LOGO_COLOR_KEYS("35"); - FF_LOGO_COLOR_TITLE("34"); - FF_LOGO_RETURN -} - -static const FFlogo* getLogoCrystalLinux() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("crystal", "Crystal", "crystal-linux", "Crystal-Linux") - FF_LOGO_LINES( - " mysssym\n" - " mysssym\n" - " mysssym\n" - " mysssym\n" - " mysssyd\n" - " mysssyd N\n" - " mysssyd mysym\n" - " mysssyd dysssym\n" - " mysssyd dysssym\n" - "mysssyd dysssym\n" - "mysssyd dysssym\n" - " mysssyd dysssym\n" - " mysssyd dysssym\n" - " mysym dysssym\n" - " N dysssym\n" - " dysssym\n" - " dysssym\n" - " dysssym\n" - " dysssym\n" - " dysssym"; - ) - FF_LOGO_COLORS( - "35" //magenta - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("35"); //magenta - FF_LOGO_RETURN -} - - - -static const FFlogo* getLogoDebian() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("debian", "debian-linux") - FF_LOGO_LINES( - " $2_,met$$$$$$$$$$gg.\n" - " ,g$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$P.\n" - " ,g$$$$P\" \"\"\"Y$$$$.\".\n" - " ,$$$$P' `$$$$$$.\n" - "',$$$$P ,ggs. `$$$$b:\n" - "`d$$$$' ,$P\"' $1.$2 $$$$$$\n" - " $$$$P d$' $1,$2 $$$$$$P\n" - " $$$$: $$. $1-$2 ,d$$$$'\n" - " $$$$; Y$b._ _,d$P'\n" - " Y$$$$. $1`.$2`\"Y$$$$$$$$P\"'\n" - " `$$$$b $1\"-.__\n" - " $2`Y$$$$\n" - " `Y$$$$.\n" - " `$$$$b.\n" - " `Y$$$$b.\n" - " `\"Y$$b._\n" - " `\"\"\"" - ) - FF_LOGO_COLORS( - "31", //red - "37" //white - ) - FF_LOGO_COLOR_KEYS("31"); //red - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoDebianSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("debian_small", "debian-linux-small") - FF_LOGO_LINES( - " _____\n" - " / __ \\\n" - "| / |\n" - "| \\___-\n" - "-_\n" - " --_" - ) - FF_LOGO_COLORS( - "31" //red - ) - FF_LOGO_COLOR_KEYS("31"); //red - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoDevuan() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("devuan", "devuan-linux") - FF_LOGO_LINES( - " ..,,;;;::;,..\n" - " `':ddd;:,.\n" - " `'dPPd:,.\n" - " `:b$$b`.\n" - " 'P$$$d`\n" - " .$$$$$`\n" - " ;$$$$$P\n" - " .:P$$$$$$`\n" - " .,:b$$$$$$$;'\n" - " .,:dP$$$$$$$$b:'\n" - " .,:;db$$$$$$$$$$Pd'`\n" - " ,db$$$$$$$$$$$$$$b:'`\n" - ":$$$$$$$$$$$$b:'`\n" - " `$$$$$bd:''`\n" - " `'''`\n" - ) - FF_LOGO_COLORS( - "35" //magenta - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("35"); //magenta - FF_LOGO_RETURN -} - -static const FFlogo* getLogoDevuanSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("devuan_small", "devuan-linux-small") - FF_LOGO_LINES( - " ..:::.\n" - " ..-==-\n" - " .+#:\n" - " =@@\n" - " :+%@#:\n" - ".:=+#@@%*:\n" - "#@@@#=:\n" - ) - FF_LOGO_COLORS( - "35" //magenta - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("35"); //magenta - FF_LOGO_RETURN -} - -static const FFlogo* getLogoDeepin() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("deepin", "deepin-linux") - FF_LOGO_LINES( - "$1 ............\n" - " .';;;;;. .,;,.\n" - " .,;;;;;;;. ';;;;;;;.\n" - " .;::::::::' .,::;;,''''',.\n" - " ,'.:::::::: .;;'. ';\n" - " ;' 'cccccc, ,' :: '.. .:\n" - " ,, :ccccc. ;: .c, '' :. ,;\n" - ".l. cllll' ., .lc :; .l' l.\n" - ".c :lllc ;cl: .l' .ll. :'\n" - ".l 'looc. . ,o: 'oo' c,\n" - ".o. .:ool::coc' .ooo' o.\n" - " :: ..... .;dddo ;c\n" - " l:... .';lddddo. ,o\n" - " lxxxxxdoolllodxxxxxxxxxc :l\n" - " ,dxxxxxxxxxxxxxxxxxxl. 'o,\n" - " ,dkkkkkkkkkkkkko;. .;o;\n" - " .;okkkkkdl;. .,cl:.\n" - " .,:cccccccc:,." - ) - FF_LOGO_COLORS( - "32" //green - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoEndeavour() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("endeavour", "endeavour-linux", "endeavouros", "endeavouros-linux") - FF_LOGO_LINES( - " $2./$1o$3.\n" - " $2./$1sssso$3-\n" - " $2`:$1osssssss+$3-\n" - " $2`:+$1sssssssssso$3/.\n" - " $2`-/o$1ssssssssssssso$3/.\n" - " $2`-/+$1sssssssssssssssso$3+:`\n" - " $2`-:/+$1sssssssssssssssssso$3+/.\n" - " $2`.://o$1sssssssssssssssssssso$3++-\n" - " $2.://+$1ssssssssssssssssssssssso$3++:\n" - " $2.:///o$1ssssssssssssssssssssssssso$3++:\n" - " $2`:////$1ssssssssssssssssssssssssssso$3+++.\n" - "$2`-////+$1ssssssssssssssssssssssssssso$3++++-\n" - " $2`..-+$1oosssssssssssssssssssssssso$3+++++/`\n" - " $3./++++++++++++++++++++++++++++++/:.\n" - " `:::::::::::::::::::::::::------``" - ) - FF_LOGO_COLORS( - "35", //magenta - "31", //red - "34" //blue - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoEnso() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("enso", "uqc") - FF_LOGO_LINES( - " .:--==--:. \n" - " :=*#############*+-. \n" - " .+##################*##*: \n" - " .*##########+==-==++*####*##- \n" - " =########=: .-+**#***. \n" - " *#######- ++*#**. \n" - " +######+ -*+#** \n" - " :######* .*+**= \n" - " *######: --#*# \n" - " ####### +++#. \n" - " #######. ++=*. \n" - " *######+ .-+*+ \n" - " :#######- -:*+: \n" - " =#######*. :.*+- \n" - " +########*- :*=- \n" - " =###########+=: =+=: \n" - " .+#############. .-==: \n" - " .=###########= ..:--:. \n" - " .-+######+ \n" - ) - FF_LOGO_COLORS( - "37" //white - ) - FF_LOGO_COLOR_KEYS("37"); //white - FF_LOGO_COLOR_TITLE("37"); //white - FF_LOGO_RETURN -} - -static const FFlogo* getLogoFedora() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("fedora", "fedora-linux") - FF_LOGO_LINES( - " .',;::::;,'.\n" - " .';:cccccccccccc:;,.\n" - " .;cccccccccccccccccccccc;.\n" - " .:cccccccccccccccccccccccccc:.\n" - " .;ccccccccccccc;$2.:dddl:.$1;ccccccc;.\n" - " .:ccccccccccccc;$2OWMKOOXMWd$1;ccccccc:.\n" - ".:ccccccccccccc;$2KMMc$1;cc;$2xMMc$1;ccccccc:.\n" - ",cccccccccccccc;$2MMM.$1;cc;$2;WW:$1;cccccccc,\n" - ":cccccccccccccc;$2MMM.$1;cccccccccccccccc:\n" - ":ccccccc;$2oxOOOo$1;$2MMM000k.$1;cccccccccccc:\n" - "cccccc;$20MMKxdd:$1;$2MMMkddc.$1;cccccccccccc;\n" - "ccccc;$2XMO'$1;cccc;$2MMM.$1;cccccccccccccccc'\n" - "ccccc;$2MMo$1;ccccc;$2MMW.$1;ccccccccccccccc;\n" - "ccccc;$20MNc.$1ccc$2.xMMd$1;ccccccccccccccc;\n" - "cccccc;$2dNMWXXXWM0:$1;cccccccccccccc:,\n" - "cccccccc;$2.:odl:.$1;cccccccccccccc:,.\n" - "ccccccccccccccccccccccccccccc:'.\n" - ":ccccccccccccccccccccccc:;,..\n" - " ':cccccccccccccccc::;,." - ) - FF_LOGO_COLORS( - "34", //blue - "37" //white - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoFedoraSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("fedora_small", "fedora-linux-small") - FF_LOGO_LINES( - " ,'''''.\n" - " | ,. |\n" - " | | '_'\n" - " ,....| |..\n" - ".' ,_;| ..'\n" - "| | | |\n" - "| ',_,' |\n" - " '. ,'\n" - " '''''" - ) - FF_LOGO_COLORS( - "34" //blue - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoFedoraOld() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("fedora_old", "fedora-old", "fedora-linux-old", "fedora-linux_old") - FF_LOGO_LINES( - " /:-------------:\\\n" - " :-------------------::\n" - " :-----------$2/shhOHbmp$1---:\\\n" - " /-----------$2omMMMNNNMMD$1 ---:\n" - " :-----------$2sMMMMNMNMP$1. ---:\n" - " :-----------$2:MMMdP$1------- ---\\\n" - ",------------$2:MMMd$1-------- ---:\n" - ":------------$2:MMMd$1------- .---:\n" - ":---- $2oNMMMMMMMMMNho$1 .----:\n" - ":-- .$2+shhhMMMmhhy++$1 .------/\n" - ":- -------$2:MMMd$1--------------:\n" - ":- --------$2/MMMd$1-------------;\n" - ":- ------$2/hMMMy$1------------:\n" - ":--$2 :dMNdhhdNMMNo$1------------;\n" - ":---$2:sdNMMMMNds:$1------------:\n" - ":------$2:://:$1-------------::\n" - ":---------------------://" - ) - FF_LOGO_COLORS( - "34", //blue - "37" //white - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoFreeBSD() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("freebsd") - FF_LOGO_LINES( - "``` $2`\n" - " $1` `.....---...$2....--.``` -/\n" - " $1+o .--` $2/y:` +.\n" - " $1yo`:. $2:o `+-\n" - " $1y/ $2-/` -o/\n" - " $1.- $2::/sy+:.\n" - " $1/ $2`-- /\n" - " $1`: $2:`\n" - " $1`: $2:`\n" - " $1/ $2/\n" - " $1.- $2-.\n" - " $1-- $2-.\n" - " $1`:` $2`:`\n" - " .-- `--.\n" - " .---.....----." - ) - FF_LOGO_COLORS( - "37", //white - "31" //red - ) - FF_LOGO_COLOR_KEYS("31") //red - FF_LOGO_COLOR_TITLE("31") //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoFreeBSDSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("freebsd_small") - FF_LOGO_LINES( - "$1/\\,-'''''-,/\\\n" - "\\_) (_/\n" - "| |\n" - "| |\n" - " ; ;\n" - " '-_____-'" - ) - FF_LOGO_COLORS( - "31" //red - ) - FF_LOGO_COLOR_KEYS("31") //red - FF_LOGO_COLOR_TITLE("31") //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoGaruda() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("garuda", "garuda-linux") - FF_LOGO_LINES( - " .%;888:8898898:\n" - " x;XxXB%89b8:b8%b88:\n" - " .8Xxd 8X:.\n" - " .8Xx; 8x:.\n" - " .tt8x .d x88;\n" - " .@8x8; .db: xx@;\n" - " ,tSXX° .bbbbbbbbbbbbbbbbbbbB8x@;\n" - " .SXxx bBBBBBBBBBBBBBBBBBBBbSBX8;\n" - " ,888S pd!\n" - "8X88/ q\n" - "8X88/\n" - "GBB.\n" - " x%88 d888@8@X@X@X88X@@XX@@X@8@X.\n" - " dxXd dB8b8b8B8B08bB88b998888b88x.\n" - " dxx8o .@@;.\n" - " dx88 .t@x.\n" - " d:SS@8ba89aa67a853Sxxad.\n" - " .d988999889889899dd." - ) - FF_LOGO_COLORS( - "31" //red - ) - FF_LOGO_COLOR_KEYS("31"); //red - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoGarudaSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("garuda_small", "garudalinux_small", "garuda-linux-small") - FF_LOGO_LINES( - " .----.\n" - " .' , '.\n" - " .' '-----|\n" - "'. -----,\n" - " '.____.'" - ) - FF_LOGO_COLORS( - "31" //red - ) - FF_LOGO_COLOR_KEYS("31"); //red - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoGentoo() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("gentoo", "gentoo-linux") - FF_LOGO_LINES( - " -/oyddmdhs+:.\n" - " -o$2dNMMMMMMMMNNmhy+$1-`\n" - " -y$2NMMMMMMMMMMMNNNmmdhy$1+-\n" - " `o$2mMMMMMMMMMMMMNmdmmmmddhhy$1/`\n" - " om$2MMMMMMMMMMMN$1hhyyyo$2hmdddhhhd$1o`\n" - ".y$2dMMMMMMMMMMd$1hs++so/s$2mdddhhhhdm$1+`\n" - " oy$2hdmNMMMMMMMN$1dyooy$2dmddddhhhhyhN$1d.\n" - " :o$2yhhdNNMMMMMMMNNNmmdddhhhhhyym$1Mh\n" - " .:$2+sydNMMMMMNNNmmmdddhhhhhhmM$1my\n" - " /m$2MMMMMMNNNmmmdddhhhhhmMNh$1s:\n" - " `o$2NMMMMMMMNNNmmmddddhhdmMNhs$1+`\n" - " `s$2NMMMMMMMMNNNmmmdddddmNMmhs$1/.\n" - " /N$2MMMMMMMMNNNNmmmdddmNMNdso$1:`\n" - "+M$2MMMMMMNNNNNmmmmdmNMNdso$1/-\n" - "yM$2MNNNNNNNmmmmmNNMmhs+/$1-`\n" - "/h$2MMNNNNNNNNMNdhs++/$1-`\n" - "`/$2ohdmmddhys+++/:$1.`\n" - " `-//////:--." - ) - FF_LOGO_COLORS( - "35", //magenta - "37" //white - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("35"); //magenta - FF_LOGO_RETURN -} - -static const FFlogo* getLogoGentooSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("gentoo_small", "gentoo-linux-small") - FF_LOGO_LINES( - " _-----_\n" - "( \\\n" - "\\ 0 \\\n" - " $2\\ )\n" - " / _/\n" - "( _-\n" - "\\____-" - ) - FF_LOGO_COLORS( - "35", //magenta - "37" //white - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("35"); //magenta - FF_LOGO_RETURN -} - -#define FF_RAW_STRING(x) #x - -static const FFlogo* getLogoGhostBSD() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("ghostbsd") - FF_LOGO_LINES( - "$1 ,gggggg.\n" - " ,agg9* .g)\n" - " .agg* ._.,gg*\n" - " ,gga* (ggg*'\n" - " ,ga* ,ga*\n" - " ,ga' .ag*\n" - " ,ga' .agga'\n" - " 9g' .agg'g*,a\n" - " 'gggg*',gga'\n" - " .gg*'\n" - " .gga*\n" - " .gga*\n" - " (ga*" - ) - FF_LOGO_COLORS( - "34" //blue - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoKDENeon() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("kde", "kde-neon", "neon") - FF_LOGO_LINES( - " `..---+/---..`\n" - " `---.`` `` `.---.`\n" - " .--.` `` `-:-.\n" - " `:/: `.----//----.` :/-\n" - " .:. `---` `--.` .:`\n" - " .:` `--` .:- `:.\n" - " `/ `:. `.-::-.` -:` `/`\n" - " /. /. `:++++++++:` .: .:\n" - "`/ .: `+++++++++++/ /` `+`\n" - "/+` -- .++++++++++++` :. .+:\n" - "`/ .: `+++++++++++/ /` `+`\n" - " /` /. `:++++++++:` .: .:\n" - " ./ `:. `.:::-.` -:` `/`\n" - " .:` `--` .:- `:.\n" - " .:. `---` `--.` .:`\n" - " `:/: `.----//----.` :/-\n" - " .-:.` `` `-:-.\n" - " `---.`` `` `.---.`\n" - " `..---+/---..`" - ) - FF_LOGO_COLORS( - "32" //green - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoKISSLinux() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("kiss", "kiss-linux", "kisslinux") - FF_LOGO_LINES( - " $3 ___ \n" - " ($2.· $3| \n" - " ($1<> $3| \n" - " / $2__$3 \\ \n" - " ( $1/ \\ $3/| \n" - "$1_$3/\\ $2__)$3/$1_$3) \n" - "$1\\/$3-____$1\\/$2 \n" - ) - FF_LOGO_COLORS( - "35", //magenta - "37", //white - "34" //blue - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoKubuntu() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("kubuntu", "kubuntu-linux", "kde-ubuntu", "ubuntu-kde", "ubuntu-plasma") - FF_LOGO_LINES( - "$1 `.:/ossyyyysso/:.\n" - " .:oyyyyyyyyyyyyyyyyyyo:`\n" - " -oyyyyyyyo$2dMMy$1yyyyyyysyyyyo-\n" - " -syyyyyyyyyy$2dMMy$1oyyyy$2dmMMy$1yyyys-\n" - " oyyys$2dMy$1syyyy$2dMMMMMMMMMMMMMy$1yyyyyyo\n" - " `oyyyy$2dMMMMy$1syysoooooo$2dMMMMy$1yyyyyyyyo`\n" - " oyyyyyy$2dMMMMy$1yyyyyyyyyyys$2dMMy$1sssssyyyo\n" - "-yyyyyyyy$2dMy$1syyyyyyyyyyyyyys$2dMMMMMy$1syyy-\n" - "oyyyysoo$2dMy$1yyyyyyyyyyyyyyyyyy$2dMMMMy$1syyyo\n" - "yyys$2dMMMMMy$1yyyyyyyyyyyyyyyyyysosyyyyyyyy\n" - "yyys$2dMMMMMy$1yyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n" - "oyyyyysos$2dy$1yyyyyyyyyyyyyyyyyy$2dMMMMy$1syyyo\n" - "-yyyyyyyy$2dMy$1syyyyyyyyyyyyyys$2dMMMMMy$1syyy-\n" - " oyyyyyy$2dMMMy$1syyyyyyyyyyys$2dMMy$1oyyyoyyyo\n" - " `oyyyy$2dMMMy$1syyyoooooo$2dMMMMy$1oyyyyyyyyo\n" - " oyyysyyoyyyys$2dMMMMMMMMMMMy$1yyyyyyyo\n" - " -syyyyyyyyy$2dMMMy$1syyy$2dMMMy$1syyyys-\n" - " -oyyyyyyy$2dMMy$1yyyyyysosyyyyo-\n" - " ./oyyyyyyyyyyyyyyyyyyo/.\n" - " `.:/oosyyyysso/:.`" - ) - FF_LOGO_COLORS( - "34", //blue - "37" //white - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoLangitKetujuh() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("l7", "langitketujuh", "LangitKetujuh") - FF_LOGO_LINES( - "\n" - "\n" - " $2. '7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7\n" - " $2L7. '7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7\n" - " $2L7L7L 7L7L7L7L7L7L7L7L7L7L7L7L7L7\n" - " $2L7L7L7 L7L7L7\n" - " $2L7L7L7 'L7L7L7L7L7L7L7L7L7L7\n" - " $2L7L7L7 'L7L7L7L7L7L7L7L7\n" - " $2L7L7L7 'L7L7L7L7L7L7\n" - " $2L7L7L7 L7L7L7\n" - " $2L7L7L7L7L7L7L7L7L7L7LL7L7L7. '7L7L7\n" - " $2L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L. 'L7\n" - " $2L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7L7. '\n" - ) - FF_LOGO_COLORS( - "34", //blue - "37" //white - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoLinux() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("linux", "linux-generic") - FF_LOGO_LINES( - " $2#####\n" - " $2#######\n" - " $2##$1O$2#$1O$2##\n" - " $2#$3#####$2#\n" - " $2##$1##$3###$1##$2##\n" - " $2#$1##########$2##\n" - " $2#$1############$2##\n" - " $2#$1############$2###\n" - " $3##$2#$1###########$2##$3#\n" - "$3######$2#$1#######$2#$3######\n" - "$3#######$2#$1#####$2#$3#######\n" - " $3#####$2#######$3#####" - ) - FF_LOGO_COLORS( - "37", //white - "30", //black - "33" //yellow - ) - FF_LOGO_COLOR_KEYS("37"); //white - FF_LOGO_COLOR_TITLE("37"); //white - FF_LOGO_RETURN -} - -static const FFlogo* getLogoMacOS() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("macos", "mac", "apple", "darwin", "osx") - FF_LOGO_LINES( - " $1c.'\n" - " ,xNMM.\n" - " .OMMMMo\n" - " lMM\"\n" - " .;loddo:. .olloddol;.\n" - " cKMMMMMMMMMMNWMMMMMMMMMM0:\n" - " $2.KMMMMMMMMMMMMMMMMMMMMMMMWd.\n" - " XMMMMMMMMMMMMMMMMMMMMMMMX.\n" - "$3;MMMMMMMMMMMMMMMMMMMMMMMM:\n" - ":MMMMMMMMMMMMMMMMMMMMMMMM:\n" - ".MMMMMMMMMMMMMMMMMMMMMMMMX.\n" - " kMMMMMMMMMMMMMMMMMMMMMMMMWd.\n" - " $4'XMMMMMMMMMMMMMMMMMMMMMMMMMMk\n" - " 'XMMMMMMMMMMMMMMMMMMMMMMMMK.\n" - " $5kMMMMMMMMMMMMMMMMMMMMMMd\n" - " ;KMMMMMMMWXXWMMMMMMMk.\n" - " \"cooc*\" \"*coo'\"" - ) - FF_LOGO_COLORS( - "32", //green - "33", //yellow - "31", //red - "35", //magenta - "34" //blue - ) - FF_LOGO_COLOR_KEYS("33"); //yellow - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoMacOSSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("macos_small", "mac_small", "apple_small", "darwin_small", "osx_small") - FF_LOGO_LINES( - "$1 .:'\n" - " __ :'__\n" - "$2 .'`__`-'__``.\n" - "$3:__________.-'\n" - "$4:_________:\n" - " :_________`-;\n" - "$5 `.__.-.__.'" - ) - FF_LOGO_COLORS( - "32", //green - "33", //yellow - "31", //red - "35", //magenta - "34" //blue - ) - FF_LOGO_COLOR_KEYS("33"); //yellow - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoMacOSSmall2() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("macos_small2", "mac_small2", "apple_small2", "darwin_small2", "osx_small2") - FF_LOGO_LINES( - "$1 .:'\n" - " __ :'__\n" - "$2 .'` `-' ``.\n" - "$3: .-'\n" - "$4: :\n" - " : `-;\n" - "$5 `.__.-.__.'" - ) - FF_LOGO_COLORS( - "32", //green - "33", //yellow - "31", //red - "35", //magenta - "34" //blue - ) - FF_LOGO_COLOR_KEYS("33"); //yellow - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoManjaro() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("manjaro", "manjaro-linux") - FF_LOGO_LINES( - "██████████████████ ████████\n" - "██████████████████ ████████\n" - "██████████████████ ████████\n" - "██████████████████ ████████\n" - "████████ ████████\n" - "████████ ████████ ████████\n" - "████████ ████████ ████████\n" - "████████ ████████ ████████\n" - "████████ ████████ ████████\n" - "████████ ████████ ████████\n" - "████████ ████████ ████████\n" - "████████ ████████ ████████\n" - "████████ ████████ ████████\n" - "████████ ████████ ████████" - ) - FF_LOGO_COLORS( - "32" //green - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoManjaroSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("manjaro_small", "manjaro-linux-small") - FF_LOGO_LINES( - "||||||||| ||||\n" - "||||||||| ||||\n" - "|||| ||||\n" - "|||| |||| ||||\n" - "|||| |||| ||||\n" - "|||| |||| ||||\n" - "|||| |||| ||||" - ) - FF_LOGO_COLORS( - "32" //green - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoMint() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("mint", "linuxmint", "mint-linux", "linux-mint") - FF_LOGO_LINES( - " $2...-:::::-...\n" - " .-MMMMMMMMMMMMMMM-.\n" - " .-MMMM$1`..-:::::::-..`$2MMMM-.\n" - " .:MMMM$1.:MMMMMMMMMMMMMMM:.$2MMMM:.\n" - " -MMM$1-M---MMMMMMMMMMMMMMMMMMM.$2MMM-\n" - " `:MMM$1:MM` :MMMM:....::-...-MMMM:$2MMM:`\n" - " :MMM$1:MMM` :MM:` `` `` `:MMM:$2MMM:\n" - ".MMM$1.MMMM` :MM. -MM. .MM- `MMMM.$2MMM.\n" - ":MMM$1:MMMM` :MM. -MM- .MM: `MMMM-$2MMM:\n" - ":MMM$1:MMMM` :MM. -MM- .MM: `MMMM:$2MMM:\n" - ":MMM$1:MMMM` :MM. -MM- .MM: `MMMM-$2MMM:\n" - ".MMM$1.MMMM` :MM:--:MM:--:MM: `MMMM.$2MMM.\n" - " :MMM$1:MMM- `-MMMMMMMMMMMM-` -MMM-$2MMM:\n" - " :MMM$1:MMM:` `:MMM:$2MMM:\n" - " .MMM$1.MMMM:--------------:MMMM.$2MMM.\n" - " '-MMMM$1.-MMMMMMMMMMMMMMM-.$2MMMM-'\n" - " '.-MMMM$1``--:::::--``$2MMMM-.'\n" - " '-MMMMMMMMMMMMM-'\n" - " ``-:::::-``" - ) - FF_LOGO_COLORS( - "32", //green - "37" //white - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoMintSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("mint_small", "linuxmint_small", "mint-linux-small") - FF_LOGO_LINES( - " __________\n" - "|_ \\\n" - " | $2| _____ $1|\n" - " | $2| | | | $1|\n" - " | $2| | | | $1|\n" - " | $2\\__$2___/ $1|\n" - " \\_________/" - ) - FF_LOGO_COLORS( - "32", //green - "37" //white - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoMintOld() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("mint_old", "mint-old", "mint-linux_old", "mint-linux-old", "linux-mint_old", "linux-mint-old") - FF_LOGO_LINES( - "MMMMMMMMMMMMMMMMMMMMMMMMMmds+.\n" - "MMm----::-://////////////oymNMd+`\n" - "MMd $2/++ $1-sNMd:\n" - "MMNso/` $2dMM `.::-. .-::.` $1.hMN:\n" - "ddddMMh $2dMM :hNMNMNhNMNMNh: $1`NMm\n" - " NMm $2dMM .NMN/-+MMM+-/NMN` $1dMM\n" - " NMm $2dMM -MMm `MMM dMM. $1dMM\n" - " NMm $2dMM -MMm `MMM dMM. $1dMM\n" - " NMm $2dMM .mmd `mmm yMM. $1dMM\n" - " NMm $2dMM` ..` ... ydm. $1dMM\n" - " hMM- $2+MMd/-------...-:sdds $1dMM\n" - " -NMm- $2:hNMNNNmdddddddddy/` $1dMM\n" - " -dMNs-$2``-::::-------.`` $1dMM\n" - " `/dMNmy+/:-------------:/yMMM\n" - " ./ydNMMMMMMMMMMMMMMMMMMMMM\n" - " .MMMMMMMMMMMMMMMMMMM" - ) - FF_LOGO_COLORS( - "32", //green - "37" //white - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoMsys2() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("msys2") - FF_LOGO_LINES( - "$2 ...\n" - " 5GB###GJ. !YPGGGG\n" - " 7@@@@@@@B. :G@@@@@@@\n" - " 7@@@@@@@@Y ~&@@@@@@@@$3YJYY5YY?L\n" - " $2!@@@@@@@@@@^ ^&@@@@@@@$3#PP555555PBY\n" - " $2~&@@@@@@@@@@? ^&@@@@@@$3#5YY5YYYYYYYY#7\n" - " $2^&@@@@@@@@@@@B :#@@@@@@@$3G5BBYGPYYYYYY#J\n" - " $2^#@@@&J#@@@@@@@~ .B@@@@@@@@@@@P $3?#YYYYYPB.\n" - " $2:#@@@@7 G@@@@@@@J P@@@#!&@@@@@@G$3.GGYYYYGB^\n" - " $2:#@@@@J Y@@@@@@@B 5@@@&:.&@@@@@@&$3BBYYY5B5.\n" - " $2:#@@@@Y !@@@@@@@@!Y@@@&~ .#@@@@@@$3GYYYYYBP JP~\n" - " $2:#@@@@P :&@@@@@@@@@@@&~ B@@@@@$3#5YYYYYPGPGPGG\n" - " $2^#@@@@G. P@@@@@@@@@@@! P@@@@$3GYYYYYYYYYYYYBY\n" - " $2^#@@@@B: ^@@@@@@@@@@7 !@@@$3#GGGGGGGPPPP5GB:\n" - " $2!&@@@@B: Y@@@@@@@@? P@@@@@@@@@&? $3^PY:\n" - " $27&@@@@5. P@@@@@@? P@@@@@@@@@B\n" - " Y@@@&P! 5@@@@7 7G@@@@@&P~\n" - ".JJ?~: ^JY~ ^!5J!^:\n" - " $1:@P5#B. #G 7&^ :@P5#B.\n" - " !&P^. ?@~ #P !&P^. \n" - " .?BG! #G5@~ .?BG! \n" - " :.B@. 7@@5 :.B@.\n" - " !PYY5Y :&@^ !PYY5Y \n" - " ~@Y\n" - " !5:" - ) - FF_LOGO_COLORS( - "35", //magenta - "37", //white - "31" //red - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoWindows11() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("Windows 11", "Windows Server 2022") - FF_LOGO_LINES( - "$1///////////////// $2/////////////////\n" - "$1///////////////// $2/////////////////\n" - "$1///////////////// $2/////////////////\n" - "$1///////////////// $2/////////////////\n" - "$1///////////////// $2/////////////////\n" - "$1///////////////// $2/////////////////\n" - "$1///////////////// $2/////////////////\n" - "$1///////////////// $2/////////////////\n" - "\n" - "$3///////////////// $4/////////////////\n" - "$3///////////////// $4/////////////////\n" - "$3///////////////// $4/////////////////\n" - "$3///////////////// $4/////////////////\n" - "$3///////////////// $4/////////////////\n" - "$3///////////////// $4/////////////////\n" - "$3///////////////// $4/////////////////\n" - "$3///////////////// $4/////////////////" - ) - FF_LOGO_COLORS( - "34", //blue - "34", //blue - "34", //blue - "34" //blue - ) - FF_LOGO_COLOR_KEYS("33"); //yellow - FF_LOGO_COLOR_TITLE("36"); //cyan - FF_LOGO_RETURN -} - -static const FFlogo* getLogoWindows11Small() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("Windows 11_small", "Windows 11-small") - FF_LOGO_LINES( - "$1lllllllll lllllllll\n" - "lllllllll lllllllll\n" - "lllllllll lllllllll\n" - "lllllllll lllllllll\n" - "\n" - "lllllllll lllllllll\n" - "lllllllll lllllllll\n" - "lllllllll lllllllll\n" - "lllllllll lllllllll\n" - ) - FF_LOGO_COLORS( - "34" //blue - ) - FF_LOGO_COLOR_KEYS("33"); //yellow - FF_LOGO_COLOR_TITLE("36"); //cyan - FF_LOGO_RETURN -} - -static const FFlogo* getLogoWindows8() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("Windows 8", "Windows 8.1", "Windows 10", "Windows Server 2012", "Windows Server 2012 R2", "Windows Server 2016", "Windows Server 2019") - FF_LOGO_LINES( - " $2..,\n" - " ....,,:;+ccllll\n" - "$1 ...,,+:; $2cllllllllllllllllll\n" - "$1,cclllllllllll $2lllllllllllllllllll\n" - "$1llllllllllllll $2lllllllllllllllllll\n" - "$1llllllllllllll $2lllllllllllllllllll\n" - "$1llllllllllllll $2lllllllllllllllllll\n" - "$1llllllllllllll $2lllllllllllllllllll\n" - "$1llllllllllllll $2lllllllllllllllllll\n" - "\n" - "$3llllllllllllll $4lllllllllllllllllll\n" - "$3llllllllllllll $4lllllllllllllllllll\n" - "$3llllllllllllll $4lllllllllllllllllll\n" - "$3llllllllllllll $4lllllllllllllllllll\n" - "$3llllllllllllll $4lllllllllllllllllll\n" - "$3`'ccllllllllll $4lllllllllllllllllll\n" - "$3 `' \\*:: $4:ccllllllllllllllll\n" - " ````''*::cll\n" - " ``" - ) - FF_LOGO_COLORS( - "36", //cyan - "36", //cyan - "36", //cyan - "36" //cyan - ) - FF_LOGO_COLOR_KEYS("33"); //yellow - FF_LOGO_COLOR_TITLE("37"); //white - FF_LOGO_RETURN -} - -static const FFlogo* getLogoWindows() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("Windows", "Windows 7", "Windows Server 2008", "Windows Server 2008 R2") - FF_LOGO_LINES( - "$1 ,.=:!!t3Z3z.,\n" - " :tt:::tt333EE3\n" - "$1 Et:::ztt33EEEL$2 @Ee., ..,\n" - "$1 ;tt:::tt333EE7$2 ;EEEEEEttttt33#\n" - "$1 :Et:::zt333EEQ.$2 $EEEEEttttt33QL\n" - "$1 it::::tt333EEF$2 @EEEEEEttttt33F\n" - "$1 ;3=*^```\"*4EEV$2 :EEEEEEttttt33@.\n" - "$3 ,.=::::!t=., $1`$2 @EEEEEEtttz33QF\n" - "$3 ;::::::::zt33)$2 \"4EEEtttji3P*\n" - "$3 :t::::::::tt33.$4:Z3z..$2 ``$4 ,..g.\n" - "$3 i::::::::zt33F$4 AEEEtttt::::ztF\n" - "$3 ;:::::::::t33V$4 ;EEEttttt::::t3\n" - "$3 E::::::::zt33L$4 @EEEtttt::::z3F\n" - "$3{3=*^```\"*4E3)$4 ;EEEtttt:::::tZ`\n" - "$3 `$4 :EEEEtttt::::z7\n" - " \"VEzjt:;;z>*`" - ) - FF_LOGO_COLORS( - "31", //red - "32", //green - "34", //blue - "33" //yellow - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoNixOS() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("nixos", "nix", "nixos-linux", "nix-linux", "nix-os", "nix_os", "nix_os_linux") - FF_LOGO_LINES( - "$1 ▗▄▄▄ $2▗▄▄▄▄ ▄▄▄▖\n" - "$1 ▜███▙ $2▜███▙ ▟███▛\n" - "$1 ▜███▙ $2▜███▙▟███▛\n" - "$1 ▜███▙ $2▜██████▛\n" - "$1 ▟█████████████████▙ $2▜████▛ $1▟▙\n" - "$1 ▟███████████████████▙ $2▜███▙ $1▟██▙\n" - "$2 ▄▄▄▄▖ ▜███▙ $1▟███▛\n" - "$2 ▟███▛ ▜██▛ $1▟███▛\n" - "$2 ▟███▛ ▜▛ $1▟███▛\n" - "$2▟███████████▛ $1▟██████████▙\n" - "$2▜██████████▛ $1▟███████████▛\n" - "$2 ▟███▛ $1▟▙ ▟███▛\n" - "$2 ▟███▛ $1▟██▙ ▟███▛\n" - "$2 ▟███▛ $1▜███▙ ▝▀▀▀▀\n" - "$2 ▜██▛ $1▜███▙ $2▜██████████████████▛\n" - "$2 ▜▛ $1▟████▙ $2▜████████████████▛\n" - "$1 ▟██████▙ $2▜███▙\n" - "$1 ▟███▛▜███▙ $2▜███▙\n" - "$1 ▟███▛ ▜███▙ $2▜███▙\n" - "$1 ▝▀▀▀ ▀▀▀▀▘ $2▀▀▀▘" - ) - FF_LOGO_COLORS( - "34", //blue - "36" //cyan - ) - FF_LOGO_COLOR_KEYS("36"); //cyan - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoNixOsOld() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("nixos_old", "nix-old", "nixos-old", "nix_old", "nix-os-old", "nix_os_old") - FF_LOGO_LINES( - "$1 ____ $2_______ ____\n" - "$1 /####\\ $2\\######\\ /####\\\n" - "$1 ######\\ $2\\######\\ /#####/\n" - "$1 \\######\\ $2\\######\\ /#####/\n" - "$1 \\######\\ $2\\######\\/#####/ $1/\\\n" - "$1 \\######\\ $2\\###########/ $1/##\\\n" - "$1 ________\\######\\______$2\\#########/ $1/####\\\n" - "$1 /#######################$2\\#######/ $1/######\n" - "$1 /#########################$2\\######\\ $1/######/\n" - "$1 /###########################$2\\######\\ $1/######/\n" - "$1 ¯¯¯¯¯¯¯¯¯¯¯¯$2/######/$1¯¯¯¯¯¯¯¯¯$2\\######$1/######/\n" - "$2 /######/ $2\\####$1/######/________\n" - "$2 _____________/######/ $2\\##$1/################\\\n" - "$2 /###################/ $2\\$1/##################\\\n" - "$2 \\##################/$1\\ /###################/\n" - "$2 \\################/$1##\\ /######/¯¯¯¯¯¯¯¯¯¯¯¯¯\n" - "$2 ¯¯¯¯¯¯¯¯/######/$1####\\ /######/\n" - "$2 /######/$1######\\$2_________$1/######/$2____________\n" - "$2 /######/ $1\\######\\$2###########################/\n" - "$2 /######/ $1\\######\\$2#########################/\n" - "$2 ######/ $1/#######\\$2#######################/\n" - "$2 \\####/ $1/#########\\$2¯¯¯¯¯¯\\######\\¯¯¯¯¯¯¯¯\n" - "$2 \\##/ $1/###########\\$2 \\######\\\n" - "$2 \\/ $1/#####/\\######\\$2 \\######\\\n" - "$1 $1/#####/ \\######\\$2 \\######\\\n" - "$1 $1/#####/ \\######\\$2 \\######\n" - "$1 $1\\####/ \\######\\$2 \\####/\n" - "$1 $1¯¯¯¯ ¯¯¯¯¯¯¯$2 ¯¯¯¯" - ) - FF_LOGO_COLORS( - "34", //blue - "36" //cyan - ) - FF_LOGO_COLOR_KEYS("36"); //cyan - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoNixOsSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("nixos_small", "nix-small", "nixos-small", "nix_small", "nix-os-small", "nix_os_small") - FF_LOGO_LINES( - "$1 \\\\ \\\\ //\n" - " ==\\\\__\\\\/ //\n" - " // \\\\//\n" - "==// //==\n" - " //\\\\___//\n" - "// /\\\\ \\\\==\n" - " // \\\\ \\\\" - ) - FF_LOGO_COLORS( - "34" //blue - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoNobara() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("nobara", "nobara-linux"); - FF_LOGO_LINES( - "⢀⣤⣴⣶⣶⣶⣦⣤⡀⠀⣀⣠⣤⣴⣶⣶⣶⣶⣶⣶⣶⣶⣤⣤⣀⡀\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⡀\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⠉⠁⠀⠀⠉⠉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⢀⣀⣀⡀⠀⠀⠀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠀⢠⣾⣿⣿⣿⣿⣷⡄⠀⠀⠀⠻⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⣀⣀⣬⣽⣿⣿⣿⣿⣿⣿\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠈⠻⢿⣿⣿⡿⠟⠁⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⣤⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n" - "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠛⠉⠉⠛⠛⢿⣿⣿⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿\n" - "⠘⢿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⠟⠁\n" - " ⠈⠙⠛⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠛⠛⠛⠉⠁\n" - ) - FF_LOGO_COLORS( - "37" // white - ) - FF_LOGO_COLOR_KEYS("37"); // white - FF_LOGO_COLOR_TITLE("37"); // white - FF_LOGO_RETURN -} - -static const FFlogo* getLogoOpenSuse() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("suse", "opensuse", "open_suse", "open-suse", "suse-linux") - FF_LOGO_LINES( - " $2.;ldkO0000Okdl;.\n" - " .;d00xl:^''''''^:ok00d;.\n" - " .d00l' 'o00d.\n" - " .d0Kd'$1 Okxol:;,. $2:O0d\n" - " .OK$1KKK0kOKKKKKKKKKKOxo:, $2lKO.\n" - " ,0K$1KKKKKKKKKKKKKKK0P^$2,,,$1^dx:$2 ;00,\n" - ".OK$1KKKKKKKKKKKKKKKk'$2.oOPPb.$1'0k.$2 cKO.\n" - ":KK$1KKKKKKKKKKKKKKK: $2kKx..dd $1lKd$2 'OK:\n" - "dKK$1KKKKKKKKKOx0KKKd $2^0KKKO' $1kKKc$2 dKd\n" - "dKK$1KKKKKKKKKK;.;oOKx,..$2^$1..;kKKK0.$2 dKd\n" - ":KK$1KKKKKKKKKK0o;...^cdxxOK0O/^^' $2.0K:\n" - " kKK$1KKKKKKKKKKKKK0x;,,......,;od $2lKk\n" - " '0K$1KKKKKKKKKKKKKKKKKKKK00KKOo^ $2c00'\n" - " 'kK$1KKOxddxkOO00000Okxoc;'' $2.dKk'\n" - " l0Ko. .c00l'\n" - " 'l0Kk:. .;xK0l'\n" - " 'lkK0xl:;,,,,;:ldO0kl'\n" - " '^:ldxkkkkxdl:^'" - ) - FF_LOGO_COLORS( - "32", //green - "37" //white - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoOpenSuseSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("suse_small", "opensuse_small", "open_suse_small", "open-suse_small") - FF_LOGO_LINES( - " _______\n" - "__| __ \\\n" - " / .\\ \\\n" - " \\__/ |\n" - " _______|\n" - " \\_______\n" - "__________/" - ) - FF_LOGO_COLORS( - "32" //green - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoOpenSuseLeap() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("opensuse_leap", "open_suse_leap", "opensuse-leap", "open-suse-leap", "suse_leap", "suse-leap", "opensuseleap") - FF_LOGO_LINES( - " .-++:.\n" - " ./oooooo/-\n" - " `:oooooooooooo:.\n" - " -+oooooooooooooooo+-`\n" - " ./oooooooooooooooooooooo/-\n" - " :oooooooooooooooooooooooooo:\n" - " ` `-+oooooooooooooooooooo/- `\n" - " `:oo/- .:ooooooooooooooo+:` `-+oo/.\n" - "`/oooooo:. -/oooooooooo/. ./oooooo/.\n" - " `:+ooooo+-` `:+oooo+- `:oooooo+:`\n" - " .:oooooo/. .::` -+oooooo/.\n" - " -/oooooo:. ./oooooo+-\n" - " `:+ooooo+-:+oooooo:`\n" - " ./oooooooooo/.\n" - " -/oooo+:`\n" - " `:/." - ) - FF_LOGO_COLORS( - "37" //white - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoOpenSuseTumbleweed() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("opensuse_tumbleweed", "open_suse_tumbleweed", "opensuse-tumbleweed", "open-suse-tumbleweed", "suse_tumbleweed", "suse-tumbleweed", "opensusetumbleweed") - FF_LOGO_LINES( - " ......\n" - " .,cdxxxoc,. .:kKMMMNWMMMNk:.\n" - " cKMMN0OOOKWMMXo. ; ;0MWk:. .:OMMk.\n" - " ;WMK;. .lKMMNM, :NMK, .OMW;\n" - " cMW; 'WMMMN ,XMK, oMM'\n" - ".MMc ..;l. xMN: KM0\n" - "'MM. 'NMO oMM\n" - ".MM, .kMMl xMN\n" - " KM0 .kMM0. .dl:,.. .WMd\n" - " .XM0. ,OMMK, OMMMK. .XMK\n" - " oWMO:. .;xNMMk, NNNMKl. .xWMx\n" - " :ONMMNXMMMKx; . ,xNMWKkxllox0NMWk,\n" - " ..... .:dOOXXKOxl," - ) - FF_LOGO_COLORS( - "37" //white - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoOpenMandriva() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("openmandriva", "open-mandriva", "open_mandriva") - FF_LOGO_LINES( - " ``````\n" - " `-:/+++++++//:-.`\n" - " .:+++oooo+/:.`` ``\n" - " `:+ooooooo+:. `-:/++++++/:.`\n" - " -+oooooooo:` `-++o+/::::://+o+/-\n" - " `/ooooooooo- -+oo/.` `-/oo+.\n" - " `+ooooooooo. :os/` .+so:\n" - " +sssssssss/ :ss/ `+ss-\n" - " :ssssssssss` sss` .sso\n" - " ossssssssss `yyo sys\n" - "`sssssssssss` `yys `yys\n" - "`sssssssssss: +yy/ +yy:\n" - " oyyyyyyyyyys. `oyy/` `+yy+\n" - " :yyyyyyyyyyyo. `+yhs:. `./shy/\n" - " oyyyyyyyyyyys:` .oyhys+:----/+syhy+. `\n" - " `syyyyyyyyyyyyo-` .:osyhhhhhyys+:``.:`\n" - " `oyyyyyyyyyyyyys+-`` `.----.```./oo.\n" - " /yhhhhhhhhhhhhhhyso+//://+osyhy/`\n" - " `/yhhhhhhhhhhhhhhhhhhhhhhhhy/`\n" - " `:oyhhhhhhhhhhhhhhhhhhyo:`\n" - " .:+syhhhhhhhhys+:-`\n" - " ``....``" - - - - ) - FF_LOGO_COLORS( - "34" //blue - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoPop() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("pop", "popos", "pop_os", "pop-linux") - FF_LOGO_LINES( - " /////////////\n" - " /////////////////////\n" - " ///////$2*767$1////////////////\n" - " //////$27676767676*$1//////////////\n" - " /////$276767$1//$27676767$1//////////////\n" - " /////$2767676$1///$2*76767$1///////////////\n" - " ///////$2767676$1///$276767$1.///$27676*$1///////\n" - "/////////$2767676$1//$276767$1///$2767676$1////////\n" - "//////////$276767676767$1////$276767$1/////////\n" - "///////////$276767676$1//////$27676$1//////////\n" - "////////////,$27676$1,///////$2767$1///////////\n" - "/////////////*$27676$1///////$276$1////////////\n" - "///////////////$27676$1////////////////////\n" - " ///////////////$27676$1///$2767$1////////////\n" - " //////////////////////$2'$1////////////\n" - " //////$2.7676767676767676767,$1//////\n" - " /////$2767676767676767676767$1/////\n" - " ///////////////////////////\n" - " /////////////////////\n" - " /////////////" - ) - FF_LOGO_COLORS( - "36", //cyan - "37" //white - ) - FF_LOGO_COLOR_KEYS("36"); //cyan - FF_LOGO_COLOR_TITLE("36"); //cyan - FF_LOGO_RETURN -} - -static const FFlogo* getLogoParabola() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("parabola", "parabola-gnulinux") - FF_LOGO_LINES( - " `.-. `.\n" - " `.` `:++. `-+o+.\n" - " `` `:+/. `:+/. `-+oooo+\n" - " ``-::-.:+/. `:+/. `-+oooooo+\n" - " `.-:///- ..` .-. `-+oooooooo-\n" - " `..-..` `+ooooooooo:\n" - "`` :oooooooo/\n" - " `ooooooo:\n" - " `oooooo:\n" - " -oooo+.\n" - " +ooo/`\n" - " -ooo-\n" - " `+o/.\n" - " /+-\n" - " //`\n" - " -." - ) - FF_LOGO_COLORS( - "35" //magenta - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("35"); //magenta - FF_LOGO_RETURN -} - -static const FFlogo* getLogoParabolaSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("parabola_small", "parabola-gnulinux_small") - FF_LOGO_LINES( - " __ __ __ _\n" - ".`_//_//_/ / `.\n" - " / .`\n" - " / .`\n" - " /.`\n" - " /`" - ) - FF_LOGO_COLORS( - "35" //magenta - ) - FF_LOGO_COLOR_KEYS("35"); //magenta - FF_LOGO_COLOR_TITLE("35"); //magenta - FF_LOGO_RETURN -} - -static const FFlogo* getLogoPopSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("pop_small", "popos_small", "pop_os_small", "pop-linux-small") - FF_LOGO_LINES( - "______\n" - "\\ _ \\ __\n" - " \\ \\ \\ \\ / /\n" - " \\ \\_\\ \\ / /\n" - " \\ ___\\ /_/\n" - " \\ \\ _\n" - " __\\_\\__(_)_\n" - " (___________)`" - ) - FF_LOGO_COLORS( - "36" //cyan - ) - FF_LOGO_COLOR_KEYS("36"); //cyan - FF_LOGO_COLOR_TITLE("36"); //cyan - FF_LOGO_RETURN -} -static const FFlogo* getLogoRaspbian() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("raspbian", "raspi", "raspberrypi" "raspberrypios" "pios") - FF_LOGO_LINES( - " $2`.::///+:/-. --///+//-:`\n" - " `+oooooooooooo: `+oooooooooooo:\n" - " /oooo++//ooooo: ooooo+//+ooooo.\n" - " `+ooooooo:-:oo- +o+::/ooooooo:\n" - " `:oooooooo+`` `.oooooooo+-\n" - " `:++ooo/. :+ooo+/.`$1\n" - " ...` `.----.` ``..\n" - " .::::-``:::::::::.`-:::-`\n" - " -:::-` .:::::::-` `-:::-\n" - " `::. `.--.` `` `.---.``.::`\n" - " .::::::::` -::::::::` `\n" - " .::` .:::::::::- `::::::::::``::.\n" - "-:::` ::::::::::. ::::::::::.`:::-\n" - ":::: -::::::::. `-:::::::: ::::\n" - "-::- .-:::-.``....``.-::-. -::-\n" - " .. `` .::::::::. `..`..\n" - " -:::-` -::::::::::` .:::::`\n" - " :::::::` -::::::::::` :::::::.\n" - " .::::::: -::::::::. ::::::::\n" - " `-:::::` ..--.` ::::::.\n" - " `...` `...--..` `...`\n" - " .::::::::::\n" - " `.-::::-`" - ) - FF_LOGO_COLORS( - "31", //red - "32" //green - ) - FF_LOGO_COLOR_KEYS("31"); //red - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoRaspbianSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("raspbian_small", "raspi_small", "raspberrypi_small" "raspberrypios_small" "pios_small") - FF_LOGO_LINES( - " $2.~~. .~~.\n" - " '. \\ ' ' / .'$1\n" - " .~ .~~~..~.\n" - " : .~.'~'.~. :\n" - " ~ ( ) ( ) ~\n" - "( : '~'.~.'~' : )\n" - " ~ .~ ( ) ~. ~\n" - " ( : '~' : )\n" - " '~ .~~~. ~'\n" - " '~'" - ) - FF_LOGO_COLORS( - "31", //red - "32" //green - ) - FF_LOGO_COLOR_KEYS("31"); //red - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoReborn() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("reborn", "reborn-os", "rebornos", "rebornos-linux", "reborn-os-linux") - FF_LOGO_LINES( - " :::::::::::::::::::::::\n" - " .:^!!!!!!!!!^.^!!!!!!!!!^:.\n" - " .:~!!!!!!!!!!^.^!!!!!!!!!!~:.\n" - " .:~!!!!!~~~~~~^.^~~~~~~!!!!!~:.\n" - " .^!!!!!~::$2=====:.:=====$1::~!!!!!^.\n" - " .::^~~!!~:$2^77777?~.~?77777^$1:~!!~~^::.\n" - " .:~~^:::^.$2^77777!!^.^7!77777^$1.^:::^~~:.\n" - " .:~!!!!~::::$2^~!!::^^^^^::!!~^$1::::~!!!!~:.\n" - " .^!!!!!~::$2!7!~^:.^?JJJJJ?^.:^~!7!$1::~!!!!!^.\n" - ".:^!!!!!~:$2^77777~.~JJJJJJJJJ~.~77777^$1:~!!!!!^:.\n" - ".:^!!!!!~:$2^77777~.~JJJJJJJJJ~.~77777^$1:~!!!!!^:.\n" - " .^!!!!!~::$2!7!~^:.^?JJJJJ?^.:^~!7!$1::~!!!!!^.\n" - " .:~!!!!~::$2::^~!!::^^^^^::!!~^::$1::~!!!!~:.\n" - " .:~~^:::^.$2^77777!!^.^7!77777^.$1^:::^~~:.\n" - " .::^~~!!~:$2^77777?~.~?77777^$1:~!!~~^::.\n" - " .^!!!!!~::$2=====:.:=====$1::~!!!!!^.\n" - " .:~!!!!!~~~~~~^.^~~~~~~!!!!!~:.\n" - " .:~!!!!!!!!!!^.^!!!!!!!!!!~:.\n" - " .:^!!!!!!!!!^.^!!!!!!!!!^:.\n" - " :::::::::::::::::::::::\n" - ) - FF_LOGO_COLORS( - "34", //blue - "36" //cyan - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoRebornSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("reborn_small", "reborn-os-small", "rebornos_small", "rebornos-linux-small", "reborn-os-linux-small") - FF_LOGO_LINES( - " _______________\n" - " / \\ / \\\n" - " / \\_______/ \\\n" - " / / \\ / \\ \\\n" - " / / \\___/ \\ \\\n" - "/____/____/ \\____\\____\\\n" - "\\ \\ \\___/ / /\n" - " \\ \\ / \\ / /\n" - " \\ \\/_______\\/ /\n" - " \\ / \\ /\n" - " \\_/___________\\_/\n" - ) - FF_LOGO_COLORS( - "34" //blue - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoRedHatEnterpriseLinux() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("rhel", "redhat", "redhat-linux") - FF_LOGO_LINES( - " .MMM..:MMMMMMM\n" - " MMMMMMMMMMMMMMMMMM\n" - " MMMMMMMMMMMMMMMMMMMM.\n" - " MMMMMMMMMMMMMMMMMMMMMM\n" - " ,MMMMMMMMMMMMMMMMMMMMMM:\n" - " MMMMMMMMMMMMMMMMMMMMMMMM\n" - " .MMMM' MMMMMMMMMMMMMMMMMMMMMM\n" - " MMMMMM `MMMMMMMMMMMMMMMMMMMM.\n" - "MMMMMMMM MMMMMMMMMMMMMMMMMM .\n" - "MMMMMMMMM. `MMMMMMMMMMMMM' MM.\n" - "MMMMMMMMMMM. MMMM\n" - "`MMMMMMMMMMMMM. ,MMMMM.\n" - " `MMMMMMMMMMMMMMMMM. ,MMMMMMMM.\n" - " MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" - " MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM:\n" - " MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" - " `MMMMMMMMMMMMMMMMMMMMMMMM:\n" - " ``MMMMMMMMMMMMMMMMM'" - ) - FF_LOGO_COLORS( - "31" //red - ) - FF_LOGO_COLOR_KEYS("31"); //red - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoRedstarOS() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("redstar", "redstar-os", "redstaros", "redstaros-linux", "redstar-os-linux") - FF_LOGO_LINES( - "$1 ..\n" - " .oK0l\n" - " :0KKKKd.\n" - " .xKO0KKKKd\n" - " ,Od' .d0000l\n" - " .c;. .'''... ..'.\n" - ".,:cloddxxxkkkkOOOOkkkkkkkkxxxxxxxxxkkkx:\n" - ";kOOOOOOOkxOkc'...',;;;;,,,'',;;:cllc:,.\n" - " .okkkkd,.lko .......',;:cllc:;,,'''''.\n" - " .cdo. :xd' cd:. ..';'',,,'',,;;;,'.\n" - " . .ddl.;doooc'..;oc;'..';::;,'.\n" - " coo;.oooolllllllcccc:'. .\n" - " .ool''lllllccccccc:::::;.\n" - " ;lll. .':cccc:::::::;;;;'\n" - " :lcc:'',..';::::;;;;;;;,,.\n" - " :cccc::::;...';;;;;,,,,,,.\n" - " ,::::::;;;,'. ..',,,,'''.\n" - " ........ ......" - ) - FF_LOGO_COLORS( - "31" //red - ) - FF_LOGO_COLOR_KEYS("31"); //red - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoRockyLinux() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("rocky", "rocky-linux", "rockylinux") - FF_LOGO_LINES( - " __wgliliiligw_,\n" - " _williiiiiiliilililw,\n" - " _%iiiiiilililiiiiiiiiiii_\n" - " .Qliiiililiiiiiiililililiilm.\n" - " _iiiiiliiiiiililiiiiiiiiiiliil,\n" - " .lililiiilililiiiilililililiiiii,\n" - "_liiiiiiliiiiiiiliiiiiF{iiiiiilili,\n" - "jliililiiilililiiili@` ~ililiiiiiL\n" - "iiiliiiiliiiiiiili>` ~liililii\n" - "liliiiliiilililii` -9liiiil\n" - "iiiiiliiliiiiii~ \"4lili\n" - "4ililiiiiilil~| -w, )4lf\n" - "-liiiiililiF' _liig, )'\n" - " )iiiliii@` _QIililig,\n" - " )iiii>` .Qliliiiililw\n" - " )<>~ .mliiiiiliiiiiil,\n" - " _gllilililiililii~\n" - " giliiiiiiiiiiiiT`\n" - " -^~$ililili@~~'" - ) - FF_LOGO_COLORS( - "32" //green - ) - FF_LOGO_COLOR_KEYS("32"); //green - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoRosaLinux() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("rosa", "rosa-linux", "rosalinux") - FF_LOGO_LINES( - " ROSAROSAROSAROSAR\n" - " ROSA AROS\n" - " ROS SAROSAROSAROSAR AROS\n" - " RO ROSAROSAROSAROSAROSAR RO\n" - " ARO AROSAROSAROSARO AROS ROS\n" - " ARO ROSAROS OSAR ROSA ROS\n" - " RO AROSA ROSAROSAROSA ROSAR RO\n" - "RO ROSAR ROSAROSAROSAR R ROSARO RO\n" - "RO ROSA AROSAROSAROSA AR ROSARO AR\n" - "RO AROS ROSAROSAROSA ROS AROSARO AR\n" - "RO AROS ROSAROSARO ROSARO ROSARO AR\n" - "RO ROS AROSAROS ROSAROSA AROSAR AR\n" - "RO ROSA ROS ROSAROSAR ROSARO RO\n" - " RO ROS AROSAROSAROSA ROSARO AR\n" - " ARO ROSA ROSAROSAROS AROSAR ARO\n" - " ARO OROSA R ROSAROS ROS\n" - " RO AROSAROS AROSAROSAR RO\n" - " AROS AROSAROSAROSARO AROS\n" - " ROSA SARO\n" - " ROSAROSAROSAROSAR" - ) - FF_LOGO_COLORS( - "34" //blue - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoSlackware() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("slackware", "slackware-linux", "slackwarelinux") - FF_LOGO_LINES( - " :::::::::\n" - " :::::::::::::::::::\n" - " :::::::::::::::::::::::::\n" - " ::::::::$2cllcccccllllllll$1::::::\n" - " :::::::::$2lc dc$1:::::::\n" - " ::::::::$2cl clllccllll oc$1:::::::::\n" - " :::::::::$2o lc$1::::::::$2co oc$1::::::::::\n" - " ::::::::::$2o cccclc$1:::::$2clcc$1::::::::::::\n" - " :::::::::::$2lc cclccclc$1:::::::::::::\n" - "::::::::::::::$2lcclcc lc$1::::::::::::\n" - "::::::::::$2cclcc$1:::::$2lccclc oc$1:::::::::::\n" - "::::::::::$2o l$1::::::::::$2l lc$1:::::::::::\n" - " :::::$2cll$1:$2o clcllcccll o$1:::::::::::\n" - " :::::$2occ$1:$2o clc$1:::::::::::\n" - " ::::$2ocl$1:$2ccslclccclclccclclc$1:::::::::::::\n" - " :::$2oclcccccccccccccllllllllllllll$1:::::\n" - " ::$2lcc1lcccccccccccccccccccccccco$1::::\n" - " ::::::::::::::::::::::::::::::::\n" - " ::::::::::::::::::::::::::::\n" - " ::::::::::::::::::::::\n" - " ::::::::::::" - ) - FF_LOGO_COLORS( - "34", //blue - "37" //white - ) - FF_LOGO_COLOR_KEYS("34") //blue - FF_LOGO_COLOR_TITLE("34") //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoSlackwareSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("slackware-small", "slackware-linux-small", "slackware_small", "slackwarelinux_small") - FF_LOGO_LINES( - " ________\n" - " / ______|\n" - " | |______\n" - " \\______ \\\n" - " ______| |\n" - "| |________/\n" - "|____________" - ) - FF_LOGO_COLORS( - "34" //blue - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoSolus() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("solus", "solus-linux") - FF_LOGO_LINES( -"$2 -```````````\n" -" `-+/------------.`\n" -" .---:mNo---------------.\n" -" .-----yMMMy:---------------.\n" -" `------oMMMMMm/----------------`\n" -" .------/MMMMMMMN+----------------.\n" -" .------/NMMMMMMMMm-+/--------------.\n" -"`------/NMMMMMMMMMN-:mh/-------------`\n" -".-----/NMMMMMMMMMMM:-+MMd//oso/:-----.\n" -"-----/NMMMMMMMMMMMM+--mMMMh::smMmyo:--\n" -"----+NMMMMMMMMMMMMMo--yMMMMNo-:yMMMMd/.\n" -".--oMMMMMMMMMMMMMMMy--yMMMMMMh:-yMMMy-`\n" -"`-sMMMMMMMMMMMMMMMMh--dMMMMMMMd:/Ny+y.\n" -"`-/+osyhhdmmNNMMMMMm-/MMMMMMMmh+/ohm+\n" -" .------------:://+-/++++++$1oshddys:\n" -" -hhhhyyyyyyyyyyyhhhhddddhysssso-\n" -" `:ossssssyysssssssssssssssso:`\n" -" `:+ssssssssssssssssssss+-\n" -" `-/+ssssssssssso+/-`\n" -" `.-----..`\n" - ) - FF_LOGO_COLORS( - "34", //blue - "37" //white - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("37"); //white - FF_LOGO_RETURN -} - -static const FFlogo* getLogoSteamOS() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("steamos") - FF_LOGO_LINES( - "$1 .,,,,.\n" - " .,'onNMMMMMNNnn',.\n" - " .'oNMANKMMMMMMMMMMMNNn'.\n" - " .'ANMMMMMMMXKNNWWWPFFWNNMNn.\n" - " ;NNMMMMMMMMMMNWW'' ,.., 'WMMM,\n" - " ;NMMMMV+##+VNWWW' .+;'':+, 'WMW,\n" - ",VNNWP+$2######$1+WW, $2+: $1:+, +MMM,\n" - "'$2+#############, +. ,+' $1+NMMM\n" - "$2 '*#########*' '*,,*' $1.+NMMMM.\n" - "$2 `'*###*' ,.,;###$1+WNM,\n" - "$2 .,;;, .;##########$1+W\n" - "$2,',. '; ,+##############'\n" - " '###+. :,. .,; ,###############'\n" - " '####.. `'' .,###############'\n" - " '#####+++################'\n" - " '*##################*'\n" - " ''*##########*''\n" - " ''''''\n" - ) - FF_LOGO_COLORS( - "34", //blue - "37" //white - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -static const FFlogo* getLogoUbuntu() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("ubuntu", "ubuntu-linux") - FF_LOGO_LINES( - " ....\n" - " .',:clooo: .:looooo:.\n" - " .;looooooooc .oooooooooo'\n" - " .;looooool:,''. :ooooooooooc\n" - " ;looool;. 'oooooooooo,\n" - " ;clool' .cooooooc. ,,\n" - " ... ...... .:oo,\n" - " .;clol:,. .loooo'\n" - " :ooooooooo, 'ooool\n" - "'ooooooooooo. loooo.\n" - "'ooooooooool coooo.\n" - " ,loooooooc. .loooo.\n" - " .,;;;'. ;ooooc\n" - " ... ,ooool.\n" - " .cooooc. ..',,'. .cooo.\n" - " ;ooooo:. ;oooooooc. :l.\n" - " .coooooc,.. coooooooooo.\n" - " .:ooooooolc:. .ooooooooooo'\n" - " .':loooooo; ,oooooooooc\n" - " ..';::c' .;loooo:'\n" - " ." - ) - FF_LOGO_COLORS( - "31", //red - "37" //white - ) - FF_LOGO_COLOR_KEYS("31"); //red - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoUbuntuOld() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("ubuntu_old", "ubuntu-linux_old") - FF_LOGO_LINES( - " .-/+oossssoo+/-.\n" - " `:+ssssssssssssssssss+:`\n" - " -+ssssssssssssssssssyyssss+-\n" - " .ossssssssssssssssssd$2MMMNy$1sssso.\n" - " /sssssssssss$2hdmmNNmmyNMMMMh$1ssssss/\n" - " +sssssssss$2hmydMMMMMMMNddddy$1ssssssss+\n" - " /ssssssss$2hNMMMyhhyyyyhmNMMMNh$1ssssssss/\n" - ".ssssssss$2dMMMNh$1ssssssssss$2hNMMMd$1ssssssss.\n" - "+ssss$2hhhyNMMNy$1ssssssssssss$2yNMMMy$1sssssss+\n" - "oss$2yNMMMNyMMh$1ssssssssssssss$2hmmmh$1ssssssso\n" - "oss$2yNMMMNyMMh$1ssssssssssssss$2hmmmh$1ssssssso\n" - "+ssss$2hhhyNMMNy$1ssssssssssss$2yNMMMy$1sssssss+\n" - ".ssssssss$2dMMMNh$1ssssssssss$2hNMMMd$1ssssssss.\n" - " /ssssssss$2hNMMMyhhyyyyhdNMMMNh$1ssssssss/\n" - " +sssssssss$2dmydMMMMMMMMddddy$1ssssssss+\n" - " /sssssssssss$2hdmNNNNmyNMMMMh$1ssssss/\n" - " .ossssssssssssssssss$2dMMMNy$1sssso.\n" - " -+sssssssssssssssss$2yyy$1ssss+-\n" - " `:+ssssssssssssssssss+:`\n" - " .-/+oossssoo+/-." - ) - FF_LOGO_COLORS( - "31", //red - "37" //white - ) - FF_LOGO_COLOR_KEYS("31"); //red - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoUbuntuSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("ubuntu_small", "ubuntu-linux-small") - FF_LOGO_LINES( - " _\n" - " ---(_)\n" - " _/ --- \\\n" - "(_) | |\n" - " \\ --- _/\n" - " ---(_)" - ) - FF_LOGO_COLORS( - "31" //red - ) - FF_LOGO_COLOR_KEYS("31"); //red - FF_LOGO_COLOR_TITLE("31"); //red - FF_LOGO_RETURN -} - -static const FFlogo* getLogoVanilla() -{ - - FF_LOGO_INIT - FF_LOGO_NAMES("vanilla", "vanilla-os","vanilla-linux"); - FF_LOGO_LINES( -" .----: \n" -" .-------.\n" -" :---::----:\n" -" .----::-----.\n" -" ......... :----::-----: ..:::-::::..\n" -".-----------------::------------------:\n" -" ----::-----------::----------::::---:\n" -" -----:::--------::-------:::-------\n" -" :------::::--::...:::::---------:\n" -" .---------::.. ..:---------.\n" -" .::-----::.. .::----::.\n" -" .:------:.......:-------:\n" -" .--------::::::::-:::-------.\n" -" .-------::-----.:-----::------.\n" -" -----::------: :------::-----\n" -" :--::--------: .-------::---:\n" -" :----------:: .:----------\n" -" :--------: :--------:" - ) - FF_LOGO_COLORS( - "33" //yellow - ) - FF_LOGO_COLOR_KEYS("33"); // yellow - FF_LOGO_COLOR_TITLE("33"); // yellow - FF_LOGO_RETURN -} - -static const FFlogo* getLogoVoid() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("void", "void-linux") - FF_LOGO_LINES( - " __.;=====;.__\n" - " _.=+==++=++=+=+===;.\n" - " -=+++=+===+=+=+++++=_\n" - " . -=:`` `--==+=++==.\n" - " _vi, ` --+=++++:\n" - " .uvnvi. _._ -==+==+.\n" - " .vvnvnI` .;==|==;. :|=||=|.\n" - "$2+QmQQm$1pvvnv;$2 _yYsyQQWUUQQQm #QmQ#$1:$2QQQWUV$QQm.\n" - " $2-QQWQW$1pvvo$2wZ?.wQQQE$1==<$2QWWQ/QWQW.QQWW$1(:$2 jQWQE\n" - " $2-$QQQQmmU' jQQQ$1@+=<$2QWQQ)mQQQ.mQQQC$1+;$2jWQQ@'\n" - " $2-$WQ8Y$1nI:$2 QWQQwgQQWV$1`$2mWQQ.jQWQQgyyWW@!\n" - " $1-1vvnvv. `~+++` ++|+++\n" - " +vnvnnv, `-|===\n" - " +vnvnvns. . :=-\n" - " -Invnvvnsi..___..=sv=. `\n" - " +Invnvnvnnnnnnnnvvnn;.\n" - " ~|Invnvnvvnvvvnnv}+`\n" - " -~|{*l}*|~" - ) - FF_LOGO_COLORS( - "32", //green - "30" //black - ) - FF_LOGO_COLOR_KEYS("37"); //white - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoVoidSmall() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("void_small", "void-linux-small") - FF_LOGO_LINES( - " _______\n" - " _ \\______ -\n" - "| \\ ___ \\ |\n" - "| | / \\ | |\n" - "| | \\___/ | |\n" - "| \\______ \\_|\n" - " -_______\\" - ) - FF_LOGO_COLORS( - "32" //green - ) - FF_LOGO_COLOR_KEYS("37"); //white - FF_LOGO_COLOR_TITLE("32"); //green - FF_LOGO_RETURN -} - -static const FFlogo* getLogoZorin() -{ - FF_LOGO_INIT - FF_LOGO_NAMES("zorin", "zorin-linux", "zorinos", "zorinos-linux") - FF_LOGO_LINES( - " `osssssssssssssssssssso`\n" - " .osssssssssssssssssssssso.\n" - " .+oooooooooooooooooooooooo+.\n" - "\n" - "\n" - " `::::::::::::::::::::::. .:`\n" - " `+ssssssssssssssssss+:.` `.:+ssso`\n" - ".ossssssssssssssso/. `-+ossssssso.\n" - "ssssssssssssso/-` `-/osssssssssssss\n" - ".ossssssso/-` .-/ossssssssssssssso.\n" - " `+sss+:. `.:+ssssssssssssssssss+`\n" - " `:. .::::::::::::::::::::::`\n" - "\n" - "\n" - " .+oooooooooooooooooooooooo+.\n" - " -osssssssssssssssssssssso-\n" - " `osssssssssssssssssssso`" - ) - FF_LOGO_COLORS( - "34" //blue - ) - FF_LOGO_COLOR_KEYS("34"); //blue - FF_LOGO_COLOR_TITLE("34"); //blue - FF_LOGO_RETURN -} - -GetLogoMethod* ffLogoBuiltinGetAll() -{ - static GetLogoMethod logoMethods[] = { - ffLogoBuiltinGetUnknown, - getLogoAlmaLinux, - getLogoAlpine, - getLogoAlpineSmall, - getLogoAndroid, - getLogoAndroidSmall, - getLogoArch, - getLogoArchSmall, - getLogoArcoLinux, - getLogoArtix, - getLogoArtixSmall, - getLogoBedrock, - getLogoBSD, - getLogoCachyOS, - getLogoCachyOSSmall, - getLogoCelOS, - getLogoCentOS, - getLogoCentOSSmall, - getLogoCRUX, - getLogoCrystalLinux, - getLogoDebian, - getLogoDevuan, - getLogoDevuanSmall, - getLogoDebianSmall, - getLogoDeepin, - getLogoEndeavour, - getLogoEnso, - getLogoFedora, - getLogoFedoraSmall, - getLogoFedoraOld, - getLogoFreeBSD, - getLogoFreeBSDSmall, - getLogoGaruda, - getLogoGarudaSmall, - getLogoGentoo, - getLogoGentooSmall, - getLogoGhostBSD, - getLogoKDENeon, - getLogoKISSLinux, - getLogoKubuntu, - getLogoLangitKetujuh, - getLogoLinux, - getLogoMacOS, - getLogoMacOSSmall, - getLogoMacOSSmall2, - getLogoManjaro, - getLogoManjaroSmall, - getLogoMint, - getLogoMintSmall, - getLogoMintOld, - getLogoMsys2, - getLogoWindows11, - getLogoWindows11Small, - getLogoWindows8, - getLogoWindows, - getLogoNixOS, - getLogoNixOsOld, - getLogoNixOsSmall, - getLogoNobara, - getLogoOpenSuse, - getLogoOpenSuseSmall, - getLogoOpenSuseLeap, - getLogoOpenSuseTumbleweed, - getLogoOpenMandriva, - getLogoPop, - getLogoPopSmall, - getLogoParabola, - getLogoParabolaSmall, - getLogoRaspbian, - getLogoRaspbianSmall, - getLogoReborn, - getLogoRebornSmall, - getLogoRedHatEnterpriseLinux, - getLogoRedstarOS, - getLogoRockyLinux, - getLogoRosaLinux, - getLogoSlackware, - getLogoSlackwareSmall, - getLogoSolus, - getLogoSteamOS, - getLogoUbuntu, - getLogoUbuntuOld, - getLogoUbuntuSmall, - getLogoVanilla, - getLogoVoid, - getLogoVoidSmall, - getLogoZorin, - NULL - }; - - return logoMethods; -} +#include "logo_builtin.h" +#include "common/color.h" + +const FFlogo ffLogoUnknown = { + .names = {"unknown"}, + .lines = FASTFETCH_DATATEXT_LOGO_UNKNOWN, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = "", + .colorTitle = "", +}; + +static const FFlogo A[] = { + // AIX + { + .names = {"aix"}, + .lines = FASTFETCH_DATATEXT_LOGO_AIX, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // AlmaLinux + { + .names = {"almalinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ALMALINUX, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_LIGHT_YELLOW, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_LIGHT_GREEN, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_RED, + }, + // Alpine + { + .names = {"alpine", "alpinelinux", "alpine-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ALPINE, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // AlpineSmall + { + .names = {"alpine_small", "alpine-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ALPINE_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Alpine2Small + { + .names = {"alpine2_small", "alpine-linux2-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ALPINE2_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Alter + { + .names = {"Alter"}, + .lines = FASTFETCH_DATATEXT_LOGO_ALTER, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Amazon + { + .names = {"Amazon"}, + .lines = FASTFETCH_DATATEXT_LOGO_AMAZON, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // AmogOS + { + .names = {"AmogOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_AMOGOS, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Anarchy + { + .names = {"Anarchy"}, + .lines = FASTFETCH_DATATEXT_LOGO_ANARCHY, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Android + { + .names = {"android"}, + .lines = FASTFETCH_DATATEXT_LOGO_ANDROID, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // AndroidSmall + { + .names = {"android-small", "android_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ANDROID_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Antergos + { + .names = {"Antergos"}, + .lines = FASTFETCH_DATATEXT_LOGO_ANTERGOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Antix + { + .names = {"antiX"}, + .lines = FASTFETCH_DATATEXT_LOGO_ANTIX, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // AoscOsRetro + { + .names = {"Aosc OS/Retro", "aoscosretro"}, + .lines = FASTFETCH_DATATEXT_LOGO_AOSCOSRETRO, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // AoscOsRetro_small + { + .names = {"Aosc OS/Retro_small", "aoscosretro_small"}, + .lines = FASTFETCH_DATATEXT_LOGO_AOSCOSRETRO_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // AoscOS + { + .names = {"Aosc OS", "aoscos"}, + .lines = FASTFETCH_DATATEXT_LOGO_AOSCOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Aperture + { + .names = {"Aperture"}, + .lines = FASTFETCH_DATATEXT_LOGO_APERTURE, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Apple + { + .names = {"Apple"}, + .lines = FASTFETCH_DATATEXT_LOGO_MACOS, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_RED, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // AppleSmall + { + .names = {"Apple_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_MACOS_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_RED, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Apricity + { + .names = {"Apricity"}, + .lines = FASTFETCH_DATATEXT_LOGO_APRICITY, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // ArchBox + { + .names = {"ArchBox"}, + .lines = FASTFETCH_DATATEXT_LOGO_ARCHBOX, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Archcraft + { + .names = {"Archcraft"}, + .lines = FASTFETCH_DATATEXT_LOGO_ARCHCRAFT, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_RED, + }, + // Archcraft2 + { + .names = {"Archcraft2"}, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ARCHCRAFT2, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_RED, + }, + // Arch + { + .names = {"arch", "archlinux", "arch-linux", "archmerge"}, + .lines = FASTFETCH_DATATEXT_LOGO_ARCH, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Arch2 + { + .names = {"arch2", "archlinux2", "arch-linux2"}, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ARCH2, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // ArchSmall + { + .names = {"arch_small", "archlinux_small", "arch-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ARCH_SMALL, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Archlabs + { + .names = {"ARCHlabs"}, + .lines = FASTFETCH_DATATEXT_LOGO_ARCHLABS, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_RED, + }, + // ArchStrike + { + .names = {"ArchStrike"}, + .lines = FASTFETCH_DATATEXT_LOGO_ARCHSTRIKE, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_BLACK, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Artix + { + .names = {"artix", "artixlinux", "artix-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ARTIX, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // ArtixSmall + { + .names = {"artix_small", "artixlinux_small", "artix-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ARTIX_SMALL, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Artix2Small + { + .names = {"artix2_small", "artixlinux2_small", "artix-linux2-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ARTIX2_SMALL, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // ArcoLinux + { + .names = {"arco", "arcolinux", "arco-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ARCO, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // ArcoLinuxSmall + { + .names = {"arco_small", "arcolinux_small", "arco-linux_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ARCO_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // ArseLinux + { + .names = {"arse", "arselinux", "arse-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ARSELINUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Arya + { + .names = {"Arya"}, + .lines = FASTFETCH_DATATEXT_LOGO_ARYA, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_RED, + }, + // Asahi + { + .names = {"asahi", "asahi-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ASAHI, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_GREEN, + FF_COLOR_FG_RED, + "38", //cyan + FF_COLOR_FG_WHITE, + FF_COLOR_FG_CYAN, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Aster + { + .names = {"aster"}, + .lines = FASTFETCH_DATATEXT_LOGO_ASTER, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // AsteroidOS + { + .names = {"AsteroidOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_ASTEROIDOS, + .colors = { + FF_COLOR_FG_256 "160", + FF_COLOR_FG_256 "208", + FF_COLOR_FG_256 "202", + FF_COLOR_FG_256 "214" + }, + .colorKeys = FF_COLOR_FG_256 "160", + .colorTitle = FF_COLOR_FG_256 "208", + }, + // AstOS + { + .names = {"astOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_ASTOS, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Astra + { + .names = {"Astra", "Astra Linux", "astralinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ASTRA_LINUX, + .colors = { + FF_COLOR_FG_LIGHT_RED, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Ataraxia + { + .names = {"Ataraxia Linux", "Ataraxia"}, + .lines = FASTFETCH_DATATEXT_LOGO_JANUSLINUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // Athena + { + .names = {"Athena"}, + .lines = FASTFETCH_DATATEXT_LOGO_ATHENA, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LAST + {}, +}; + +static const FFlogo B[] = { + // Bedrock + { + .names = {"bedrock", "bedrocklinux", "bedrock-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_BEDROCK, + .colors = { + FF_COLOR_FG_LIGHT_BLACK, //grey + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_LIGHT_BLACK, //grey + .colorTitle = FF_COLOR_FG_WHITE, + }, + // BigLinux + { + .names = {"BigLinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_BIGLINUX, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Bitrig + { + .names = {"Bitrig"}, + .lines = FASTFETCH_DATATEXT_LOGO_BITRIG, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // BlackArch + { + .names = {"Blackarch"}, + .lines = FASTFETCH_DATATEXT_LOGO_BLACKARCH, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_LIGHT_RED, + FF_COLOR_FG_BLACK, + }, + .colorKeys = FF_COLOR_FG_LIGHT_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // BlackPanther + { + .names = {"BlackPanther"}, + .lines = FASTFETCH_DATATEXT_LOGO_BLACKPANTHER, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_LIGHT_BLUE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // BLAG + { + .names = {"BLAG"}, + .lines = FASTFETCH_DATATEXT_LOGO_BLAG, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // BlankOn + { + .names = {"BlankOn"}, + .lines = FASTFETCH_DATATEXT_LOGO_BLANKON, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // BlueLight + { + .names = {"BlueLight"}, + .lines = FASTFETCH_DATATEXT_LOGO_BLUELIGHT, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Bodhi + { + .names = {"Bodhi"}, + .lines = FASTFETCH_DATATEXT_LOGO_BODHI, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_LIGHT_YELLOW, + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Bonsai + { + .names = {"Bonsai"}, + .lines = FASTFETCH_DATATEXT_LOGO_BONSAI, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // BSD + { + .names = {"BSD"}, + .lines = FASTFETCH_DATATEXT_LOGO_BSD, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // BunsenLabs + { + .names = {"BunsenLabs"}, + .lines = FASTFETCH_DATATEXT_LOGO_BUNSENLABS, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LAST + {}, +}; + +static const FFlogo C[] = { + // CachyOS + { + .names = {"Cachy", "cachyos", "cachy-linux", "cachyos-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_CACHYOS, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_GREEN, + FF_COLOR_FG_BLACK, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // CachyOSSmall + { + .names = {"Cachy_small", "cachyos_small", "cachy-linux-small", "cachyos-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_CACHYOS_SMALL, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Calculate + { + .names = {"Calculate"}, + .lines = FASTFETCH_DATATEXT_LOGO_CALCULATE, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // CalinixOS + { + .names = {"Calinix", "calinixos"}, + .lines = FASTFETCH_DATATEXT_LOGO_CALINIXOS, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // CalinixOSSmall + { + .names = {"Calinix_small", "calinixos_small"}, + .lines = FASTFETCH_DATATEXT_LOGO_CALINIXOS_SMALL, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Carbs + { + .names = {"Carbs"}, + .lines = FASTFETCH_DATATEXT_LOGO_CARBS, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // CBL-Mariner + { + .names = {"CBL-Mariner"}, + .lines = FASTFETCH_DATATEXT_LOGO_CBL_MARINER, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // CelOS + { + .names = {"Cel", "celos", "cel-linux", "celos-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_CELOS, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLACK, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Center + { + .names = {"Center"}, + .lines = FASTFETCH_DATATEXT_LOGO_CENTER, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // CentOS + { + .names = {"Cent", "centos", "cent-linux", "centos-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_CENTOS, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_GREEN, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // CentOSSmall + { + .names = {"Cent_small", "centos_small", "cent-linux_small", "cent-linux-small", "centos-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_CENTOS_SMALL, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_GREEN, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // Chakra + { + .names = {"Chakra"}, + .lines = FASTFETCH_DATATEXT_LOGO_CHAKRA, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // ChaletOS + { + .names = {"ChaletOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_CHALETOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Chapeau + { + .names = {"Chapeau"}, + .lines = FASTFETCH_DATATEXT_LOGO_CHAPEAU, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // ChonkySealOS + { + .names = {"ChonkySealOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_CHONKYSEALOS, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Chrom + { + .names = {"Chrom", "ChromeOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_CHROM, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_RED, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_RED, + }, + // Cleanjaro + { + .names = {"Cleanjaro"}, + .lines = FASTFETCH_DATATEXT_LOGO_CLEANJARO, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // CleanjaroSmall + { + .names = {"Cleanjaro_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_CLEANJARO_SMALL, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // ClearLinux + { + .names = {"Clear Linux", "clearlinux", "Clear Linux OS"}, + .lines = FASTFETCH_DATATEXT_LOGO_CLEAR_LINUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // ClearOS + { + .names = {"ClearOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_CLEAROS, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Clover + { + .names = {"Clover"}, + .lines = FASTFETCH_DATATEXT_LOGO_CLOVER, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Cobalt + { + .names = {"Cobalt"}, + .lines = FASTFETCH_DATATEXT_LOGO_COBALT, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_LIGHT_BLACK, + FF_COLOR_FG_LIGHT_BLUE, + FF_COLOR_FG_BLACK, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Condres + { + .names = {"Condres"}, + .lines = FASTFETCH_DATATEXT_LOGO_CONDRES, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_CYAN + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // ContainerLinux + { + .names = {"ContainerLinux", "Container Linux", "Container Linux by CoreOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_CONTAINER_LINUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // CRUX + { + .names = {"CRUX"}, + .lines = FASTFETCH_DATATEXT_LOGO_CRUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // CRUXSmall + { + .names = {"CRUX_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_CRUX_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // CrystalLinux + { + .names = {"Crystal", "Crystal", "crystal-linux", "Crystal-Linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_CRYSTAL, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // Cucumber + { + .names = {"Cucumber", "CucumberOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_CUCUMBER, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // CutefishOS + { + .names = {"CutefishOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_CUTEFISHOS, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_BLUE, + }, + }, + // CuteOS + { + .names = {"CuteOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_CUTEOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_CYAN, + FF_COLOR_FG_256 "57", + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // CyberOS + { + .names = {"CyberOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_CYBEROS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_CYAN, + FF_COLOR_FG_256 "57", + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // LAST + {}, +}; + +static const FFlogo D[] = { + // Dahlia + { + .names = {"dahlia"}, + .lines = FASTFETCH_DATATEXT_LOGO_DAHLIA, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // DarkOS + { + .names = {"DarkOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_DARKOS, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_CYAN, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Debian + { + .names = {"Debian", "debian-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_DEBIAN, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // DebianSmall + { + .names = {"Debian_small", "debian-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_DEBIAN_SMALL, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // Deepin + { + .names = {"Deepin", "deepin-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_DEEPIN, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // DesaOS + { + .names = {"DesaOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_DESAOS, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Devuan + { + .names = {"Devuan", "devuan-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_DEVUAN, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // DevuanSmall + { + .names = {"Devuan_small", "devuan-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_DEVUAN_SMALL, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // DietPi + { + .names = {"DietPi"}, + .lines = FASTFETCH_DATATEXT_LOGO_DIETPI, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_BLACK, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // DracOS + { + .names = {"DracOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_DRACOS, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // DragonFly + { + .names = {"DragonFly", "DragonFly-BSD"}, + .lines = FASTFETCH_DATATEXT_LOGO_DRAGONFLY, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // DragonFlySmall + { + .names = {"DragonFly_small", "DragonFly-BSD_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_DRAGONFLY_SMALL, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // DragonFlyOld + { + .names = {"DragonFly_old", "DragonFly-BSD_old"}, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_DRAGONFLY_OLD, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Drauger + { + .names = {"Drauger"}, + .lines = FASTFETCH_DATATEXT_LOGO_DRAUGER, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Droidian + { + .names = {"Droidian"}, + .lines = FASTFETCH_DATATEXT_LOGO_DROIDIAN, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_LIGHT_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_LIGHT_GREEN, + }, + // LAST + {}, +}; + +static const FFlogo E[] = { + // Elementary + { + .names = {"Elementary"}, + .lines = FASTFETCH_DATATEXT_LOGO_ELEMENTARY, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // ElementarySmall + { + .names = {"Elementary_small", "elementary-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ELEMENTARY_SMALL, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Elive + { + .names = {"Elive"}, + .lines = FASTFETCH_DATATEXT_LOGO_ELIVE, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_LIGHT_CYAN, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // EncryptOS + { + .names = {"EncryptOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_ENCRYPTOS, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Endeavour + { + .names = {"Endeavour", "endeavour-linux", "endeavouros", "endeavouros-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ENDEAVOUR, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_RED, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_RED, + }, + // Endless + { + .names = {"Endless"}, + .lines = FASTFETCH_DATATEXT_LOGO_ENDLESS, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Enso + { + .names = {"Enso"}, + .lines = FASTFETCH_DATATEXT_LOGO_ENSO, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // EuroLinux + { + .names = {"EuroLinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_EUROLINUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // EvolutionOS + { + .names = {"EvolutionOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_EVOLUTIONOS, + .colors = { + FF_COLOR_FG_LIGHT_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // Exherbo + { + .names = {"Exherbo", "exherbo-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_EXHERBO, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // ExodiaPredator + { + .names = {"Exodia Predator", "exodia-predator", "Exodia Predator OS"}, + .lines = FASTFETCH_DATATEXT_LOGO_EXODIA_PREDATOR, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // LAST + {}, +}; + +static const FFlogo F[] = { + // Fedora + { + .names = {"Fedora", "fedora-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_FEDORA, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // FedoraSmall + { + .names = {"Fedora_small", "fedora-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_FEDORA_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // FedoraOld + { + .names = {"Fedora_old", "fedora-old", "fedora-linux-old", "fedora-linux_old"}, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_FEDORA_OLD, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // FemboyOS + { + .names = {"FemboyOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_FEMBOYOS, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Feren + { + .names = {"Feren"}, + .lines = FASTFETCH_DATATEXT_LOGO_FEREN, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Finnix + { + .names = {"Finnix"}, + .lines = FASTFETCH_DATATEXT_LOGO_FINNIX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Floflis + { + .names = {"Floflis"}, + .lines = FASTFETCH_DATATEXT_LOGO_FLOFLIS, + .colors = { + FF_COLOR_FG_LIGHT_CYAN, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // FreeBSD + { + .names = {"Freebsd"}, + .lines = FASTFETCH_DATATEXT_LOGO_FREEBSD, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // FreeBSDSmall + { + .names = {"freebsd_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_FREEBSD_SMALL, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // FreeMiNT + { + .names = {"FreeMiNT"}, + .lines = FASTFETCH_DATATEXT_LOGO_FREEMINT, + .colors = { + FF_COLOR_FG_WHITE + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Frugalware + { + .names = {"Frugalware", "frugalware-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_FRUGALWARE, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Funtoo + { + .names = {"Funtoo"}, + .lines = FASTFETCH_DATATEXT_LOGO_FUNTOO, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LAST + {}, +}; + +static const FFlogo G[] = { + // GalliumOS + { + .names = {"GalliumOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_GALLIUMOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Garuda + { + .names = {"Garuda", "garuda-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_GARUDA, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // GarudaDragon + { + .names = {"GarudaDragon", "garuda-dragon", "garuda-linux-dragon"}, + .lines = FASTFETCH_DATATEXT_LOGO_GARUDA_DRAGON, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // GarudaSmall + { + .names = {"Garuda_small", "garudalinux_small", "garuda-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_GARUDA_SMALL, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // Gentoo + { + .names = {"Gentoo", "gentoo-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_GENTOO, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // GentooSmall + { + .names = {"Gentoo_small", "gentoo-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_GENTOO_SMALL, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // GhostBSD + { + .names = {"GhostBSD"}, + .lines = FASTFETCH_DATATEXT_LOGO_GHOSTBSD, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_RED, + }, + // Glaucus + { + .names = {"Glaucus"}, + .lines = FASTFETCH_DATATEXT_LOGO_GLAUCUS, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // GNewSense + { + .names = {"gNewSense"}, + .lines = FASTFETCH_DATATEXT_LOGO_GNEWSENSE, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Gnome + { + .names = {"Gnome"}, + .lines = FASTFETCH_DATATEXT_LOGO_GNOME, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_RED, + }, + // GNU + { + .names = {"GNU"}, + .lines = FASTFETCH_DATATEXT_LOGO_GNU, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_RED, + }, + // GoboLinux + { + .names = {"GoboLinux", "Gobo"}, + .lines = FASTFETCH_DATATEXT_LOGO_GOBOLINUX, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // GrapheneOS + { + .names = {"GrapheneOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_GRAPHENEOS, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Grombyang + { + .names = {"Grombyang"}, + .lines = FASTFETCH_DATATEXT_LOGO_GROMBYANG, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_GREEN, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Guix + { + .names = {"Guix"}, + .lines = FASTFETCH_DATATEXT_LOGO_GUIX, + .colors = { + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // GuixSmall + { + .names = {"Guix_small"}, + .lines = FASTFETCH_DATATEXT_LOGO_GUIX_SMALL, + .colors = { + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LAST + {}, +}; + +static const FFlogo H[] = { + // Haiku + { + .names = {"Haiku"}, + .lines = FASTFETCH_DATATEXT_LOGO_HAIKU, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // HaikuSmall + { + .names = {"Haiku-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_HAIKU_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // HamoniKR + { + .names = {"HamoniKR"}, + .lines = FASTFETCH_DATATEXT_LOGO_HAMONIKR, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_256 "99" + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // HarDClanZ + { + .names = {"HarDClanZ"}, + .lines = FASTFETCH_DATATEXT_LOGO_HARDCLANZ, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // HardenedBSD + { + .names = {"HardenedBSD"}, + .lines = FASTFETCH_DATATEXT_LOGO_FREEBSD, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // Hash + { + .names = {"Hash"}, + .lines = FASTFETCH_DATATEXT_LOGO_HASH, + .colors = { + FF_COLOR_FG_256 "123", + FF_COLOR_FG_256 "123", + }, + }, + // Huayra + { + .names = {"Huayra"}, + .lines = FASTFETCH_DATATEXT_LOGO_HUAYRA, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Hybrid + { + .names = {"Hybrid"}, + .lines = FASTFETCH_DATATEXT_LOGO_HYBRID, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_LIGHT_BLUE, + }, + .colorKeys = FF_COLOR_FG_LIGHT_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // HydroOS + { + .names = {"HydroOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_HYDROOS, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Hyperbola + { + .names = {"Hyperbola"}, + .lines = FASTFETCH_DATATEXT_LOGO_HYPERBOLA, + .colors = { + FF_COLOR_FG_LIGHT_BLACK, + }, + .colorKeys = FF_COLOR_FG_LIGHT_BLACK, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // HyperbolaSmall + { + .names = {"Hyperbola_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_HYPERBOLA_SMALL, + .colors = { + FF_COLOR_FG_LIGHT_BLACK, + }, + .colorKeys = FF_COLOR_FG_LIGHT_BLACK, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LAST + {}, +}; + +static const FFlogo I[] = { + // Iglunix + { + .names = {"Iglunix", "Iglu"}, + .lines = FASTFETCH_DATATEXT_LOGO_IGLUNIX, + .colors = { + FF_COLOR_FG_LIGHT_BLACK, + }, + .colorKeys = FF_COLOR_FG_LIGHT_BLACK, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // InstantOS + { + .names = {"InstantOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_INSTANTOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // IRIX + { + .names = {"IRIX"}, + .lines = FASTFETCH_DATATEXT_LOGO_IRIX, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Itc + { + .names = {"Itc"}, + .lines = FASTFETCH_DATATEXT_LOGO_ITC, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_RED, + }, + // LAST + {}, +}; + +static const FFlogo J[] = { + // Januslinux + { + .names = {"januslinux", "janus"}, + .lines = FASTFETCH_DATATEXT_LOGO_JANUSLINUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // LAST + {}, +}; + +static const FFlogo K[] = { + // Kaisen + { + .names = {"Kaisen"}, + .lines = FASTFETCH_DATATEXT_LOGO_KAISEN, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Kali + { + .names = {"Kali", "Kalilinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_KALI, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_LIGHT_BLACK, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // KaliSmall + { + .names = {"Kali_small", "Kalilinux_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_KALI_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_LIGHT_BLACK, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // KaOS + { + .names = {"KaOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_KAOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // KDENeon + { + .names = {"KDE", "kde-neon"}, + .lines = FASTFETCH_DATATEXT_LOGO_KDE, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Kibojoe + { + .names = {"Kibojoe"}, + .lines = FASTFETCH_DATATEXT_LOGO_KIBOJOE, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // KISSLinux + { + .names = {"KISS", "kiss-linux", "kisslinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_KISS, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Kogaion + { + .names = {"Kogaion"}, + .lines = FASTFETCH_DATATEXT_LOGO_KOGAION, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Korora + { + .names = {"Korora"}, + .lines = FASTFETCH_DATATEXT_LOGO_KORORA, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // KrassOS + { + .names = {"KrassOS", "Krass"}, + .lines = FASTFETCH_DATATEXT_LOGO_KRASSOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // KSLinux + { + .names = {"KSLinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_KSLINUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Kubuntu + { + .names = {"Kubuntu", "kubuntu-linux", "kde-ubuntu"}, + .lines = FASTFETCH_DATATEXT_LOGO_KUBUNTU, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // LAST + {}, +}; + +static const FFlogo L[] = { + // LangitKetujuh + { + .names = {"langitketujuh", "l7"}, + .lines = FASTFETCH_DATATEXT_LOGO_LANGITKETUJUH, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Laxeros + { + .names = {"Laxeros"}, + .lines = FASTFETCH_DATATEXT_LOGO_LAXEROS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LEDE + { + .names = {"LEDE"}, + .lines = FASTFETCH_DATATEXT_LOGO_LEDE, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LibreELEC + { + .names = {"LibreELEC"}, + .lines = FASTFETCH_DATATEXT_LOGO_LIBREELEC, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_CYAN, + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // Linspire + { + .names = {"Linspire", "Lindows"}, + .lines = FASTFETCH_DATATEXT_LOGO_LINSPIRE, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Linux + { + .names = {"Linux", "linux-generic"}, + .lines = FASTFETCH_DATATEXT_LOGO_LINUX, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_BLACK, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LinuxSmall + { + .names = {"Linux_small", "linux-generic_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_LINUX_SMALL, + .colors = { + FF_COLOR_FG_BLACK, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LinuxLight + { + .names = {"LinuxLite", "Linux Lite", "linux_lite"}, + .lines = FASTFETCH_DATATEXT_LOGO_LINUXLITE, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LinuxLightSmall + { + .names = {"LinuxLite_small", "Linux Lite_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_LINUXLITE_SMALL, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LinuxMint + { + .names = {"linuxmint", "linux-mint"}, + .lines = FASTFETCH_DATATEXT_LOGO_MINT, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // LinuxMintSmall + { + .names = {"linuxmint_small", "linux-mint_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_MINT_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // LinuxMintOld + { + .names = {"linux-mint_old", "linux-mint-old"}, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_MINT_OLD, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Live_Raizo + { + .names = {"Live Raizo", "Live_Raizo"}, + .lines = FASTFETCH_DATATEXT_LOGO_LIVE_RAIZO, + .colors = { + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LMDE + { + .names = {"LMDE"}, + .lines = FASTFETCH_DATATEXT_LOGO_LMDE, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Lunar + { + .names = {"Lunar"}, + .lines = FASTFETCH_DATATEXT_LOGO_LUNAR, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // LAST + {}, +}; + +static const FFlogo M[] = { + // MacOS + { + .names = {"macos", "mac"}, + .lines = FASTFETCH_DATATEXT_LOGO_MACOS, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_RED, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // MacOSSmall + { + .names = {"macos_small", "mac_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_MACOS_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_RED, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // MacOS2 + { + .names = {"macos2", "mac2"}, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_MACOS2, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_RED, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // MacOS2Small + { + .names = {"macos2_small", "mac2_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_MACOS2_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_RED, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Mageia + { + .names = {"Mageia"}, + .lines = FASTFETCH_DATATEXT_LOGO_MAGEIA, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // MageiaSmall + { + .names = {"Mageia_small"}, + .lines = FASTFETCH_DATATEXT_LOGO_MAGEIA_SMALL, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // MagpieOS + { + .names = {"MagpieOS", "Magpie"}, + .lines = FASTFETCH_DATATEXT_LOGO_MAGPIEOS, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_RED, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_RED, + }, + // Mandriva + { + .names = {"mandriva", "mandrake"}, + .lines = FASTFETCH_DATATEXT_LOGO_MANDRIVA, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // Manjaro + { + .names = {"manjaro", "manjaro-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_MANJARO, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // ManjaroSmall + { + .names = {"manjaro_small", "manjaro-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_MANJARO_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // MassOS + { + .names = {"MassOS", "mass"}, + .lines = FASTFETCH_DATATEXT_LOGO_MASSOS, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // MatuusOS + { + .names = {"MatuusOS", "Matuus"}, + .lines = FASTFETCH_DATATEXT_LOGO_MATUUSOS, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_RED, + }, + // MaUI + { + .names = {"MaUI"}, + .lines = FASTFETCH_DATATEXT_LOGO_MAUI, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Meowix + { + .names = {"Meowix"}, + .lines = FASTFETCH_DATATEXT_LOGO_MEOWIX, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // Mer + { + .names = {"Mer"}, + .lines = FASTFETCH_DATATEXT_LOGO_MER, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Mint + { + .names = {"mint", "mint-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_MINT, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // MintSmall + { + .names = {"mint_small", "mint-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_MINT_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // MintOld + { + .names = {"mint_old", "mint-old", "mint-linux_old", "mint-linux-old"}, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_MINT_OLD, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Minix + { + .names = {"Minix"}, + .lines = FASTFETCH_DATATEXT_LOGO_MINIX, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // MiracleLinux + { + .names = {"MIRACLE LINUX", "miracle_linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_MIRACLE_LINUX, + .colors = { + FF_COLOR_FG_256 "29", + }, + .colorKeys = FF_COLOR_FG_256 "29", + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Msys2 + { + .names = {"Msys2"}, + .lines = FASTFETCH_DATATEXT_LOGO_MSYS2, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_RED, + }, + // MX + { + .names = {"MX"}, + .lines = FASTFETCH_DATATEXT_LOGO_MX, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // MXSmall + { + .names = {"MX_small", "mx-small"}, + .lines = FASTFETCH_DATATEXT_LOGO_MX_SMALL, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // LAST + {}, +}; + +static const FFlogo N[] = { + // Namib + { + .names = {"Namib"}, + .lines = FASTFETCH_DATATEXT_LOGO_NAMIB, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // Nekos + { + .names = {"Nekos"}, + .lines = FASTFETCH_DATATEXT_LOGO_NEKOS, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_RED, + }, + }, + // Neptune + { + .names = {"Neptune"}, + .lines = FASTFETCH_DATATEXT_LOGO_NEPTUNE, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_WHITE, + }, + }, + // NetRunner + { + .names = {"NetRunner"}, + .lines = FASTFETCH_DATATEXT_LOGO_NETRUNNER, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // Nitrux + { + .names = {"Nitrux"}, + .lines = FASTFETCH_DATATEXT_LOGO_NITRUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // NixOS + { + .names = {"NixOS", "nix", "nixos-linux", "nix-linux", "nix-os", "nix_os", "nix_os_linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_NIXOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // NixOS_small + { + .names = {"NixOS_small", "nix_small"}, + .lines = FASTFETCH_DATATEXT_LOGO_NIXOS_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // NixOsOld + { + .names = {"nixos_old", "nix-old", "nixos-old", "nix_old", "nix-os-old", "nix_os_old"}, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_NIXOS_OLD, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // NixOsSmall + { + .names = {"nixos_small", "nix-small", "nixos-small", "nix_small", "nix-os-small", "nix_os_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_NIXOS_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // NetBSD + { + .names = {"netbsd"}, + .lines = FASTFETCH_DATATEXT_LOGO_NETBSD, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Nobara + { + .names = {"nobara", "nobara-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_NOBARA, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // NomadBSD + { + .names = {"nomadbsd"}, + .lines = FASTFETCH_DATATEXT_LOGO_NOMADBSD, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Nurunner + { + .names = {"Nurunner"}, + .lines = FASTFETCH_DATATEXT_LOGO_NURUNNER, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // NuTyX + { + .names = {"NuTyX"}, + .lines = FASTFETCH_DATATEXT_LOGO_NUTYX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_RED, + }, + }, + // LAST + {}, +}; + +static const FFlogo O[] = { + // Obarun + { + .names = {"Obarun"}, + .lines = FASTFETCH_DATATEXT_LOGO_OBARUN, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + }, + // OBRevenge + { + .names = {"OBRevenge"}, + .lines = FASTFETCH_DATATEXT_LOGO_OBREVENGE, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // OmniOS + { + .names = {"OmniOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_OMNIOS, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_LIGHT_BLACK, + } + }, + // OpenKylin + { + .names = {"openkylin", "open-kylin"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPENKYLIN, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // OpenBSD + { + .names = {"openbsd"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPENBSD, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_CYAN, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // OpenBSDSmall + { + .names = {"openbsd_small", "openbsd-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_OPENBSD_SMALL, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // OpenEuler + { + .names = {"OpenEuler"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPENEULER, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // OpenIndiana + { + .names = {"OpenIndiana"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPENINDIANA, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // OpenMamba + { + .names = {"OpenMamba"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPENMAMBA, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_GREEN, + }, + }, + // OpenStage + { + .names = {"OpenStage"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPENSTAGE, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + }, + // OpenSuse + { + .names = {"opensuse", "open_suse", "open-suse"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // OpenSuseSmall + { + .names = {"opensuse_small", "open_suse_small", "open-suse_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // OpenSuseLeap + { + .names = {"opensuse_leap", "open_suse_leap", "opensuse-leap", "open-suse-leap", "suse_leap", "suse-leap", "opensuseleap"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_LEAP, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // OpenSuseTumbleweed + { + .names = {"opensuse_tumbleweed", "open_suse_tumbleweed", "opensuse-tumbleweed", "open-suse-tumbleweed", "suse_tumbleweed", "suse-tumbleweed", "opensusetumbleweed"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_TUMBLEWEED, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // OpenMandriva + { + .names = {"openmandriva", "open-mandriva", "open_mandriva"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPENMANDRIVA, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // OpenWrt + { + .names = {"openwrt"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPENWRT, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // OPNsense + { + .names = {"OPNsense"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPNSENSE, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_256 "202", + }, + }, + // Oracle + { + .names = {"oracle", "oracle linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ORACLE, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Orchid + { + .names = {"orchid"}, + .lines = FASTFETCH_DATATEXT_LOGO_ORCHID, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // OrchidSmall + { + .names = {"orchid_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ORCHID_SMALL, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // OS_Elbrus + { + .names = {"OS Elbrus"}, + .lines = FASTFETCH_DATATEXT_LOGO_OS_ELBRUS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // OSMC + { + .names = {"OSMC", "Open Source Media Center"}, + .lines = FASTFETCH_DATATEXT_LOGO_OSMC, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // OSX + { + .names = {"OSX"}, + .lines = FASTFETCH_DATATEXT_LOGO_MACOS, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_RED, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // OSXSmall + { + .names = {"OSX_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_MACOS_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_RED, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // LAST + {}, +}; + +static const FFlogo P[] = { + // PacBSD + { + .names = {"PacBSD"}, + .lines = FASTFETCH_DATATEXT_LOGO_PACBSD, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // Panwah + { + .names = {"Panwah"}, + .lines = FASTFETCH_DATATEXT_LOGO_PANWAH, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_RED, + FF_COLOR_FG_BLACK, + }, + }, + // Parabola + { + .names = {"parabola", "parabola-gnulinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_PARABOLA, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // ParabolaSmall + { + .names = {"parabola_small", "parabola-gnulinux_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_PARABOLA_SMALL, + .colors = { + FF_COLOR_FG_MAGENTA, + }, + .colorKeys = FF_COLOR_FG_MAGENTA, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // Parch + { + .names = {"Parch"}, + .lines = FASTFETCH_DATATEXT_LOGO_PARCH, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_CYAN, + }, + }, + // Pardus + { + .names = {"Pardus"}, + .lines = FASTFETCH_DATATEXT_LOGO_PARDUS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_CYAN, + }, + }, + // Parrot + { + .names = {"Parrot"}, + .lines = FASTFETCH_DATATEXT_LOGO_PARROT, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + }, + // Parsix + { + .names = {"Parsix"}, + .lines = FASTFETCH_DATATEXT_LOGO_PARSIX, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_LIGHT_BLACK, + }, + }, + // PCBSD + { + .names = {"PCBSD", "TrueOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_PCBSD, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // PCLinuxOS + { + .names = {"PCLinuxOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_PCLINUXOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // PearOS + { + .names = {"PearOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_PEAROS, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_RED, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLUE, + }, + }, + // Pengwin + { + .names = {"Pengwin"}, + .lines = FASTFETCH_DATATEXT_LOGO_PENGWIN, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_LIGHT_MAGENTA, + FF_COLOR_FG_MAGENTA, + }, + }, + // Pentoo + { + .names = {"Pentoo"}, + .lines = FASTFETCH_DATATEXT_LOGO_PENTOO, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + }, + }, + // Peppermint + { + .names = {"Peppermint"}, + .lines = FASTFETCH_DATATEXT_LOGO_PEPPERMINT, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // PhyOS + { + .names = {"PhyOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_PHYOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // Pisi + { + .names = {"Pisi"}, + .lines = FASTFETCH_DATATEXT_LOGO_PISI, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // PNMLinux + { + .names = {"PNM Linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_PNM_LINUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_256 "202" + }, + }, + // Pop + { + .names = {"pop", "popos", "pop_os", "pop-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_POP, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // PopSmall + { + .names = {"pop_small", "popos_small", "pop_os_small", "pop-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_POP_SMALL, + .colors = { + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Porteus + { + .names = {"Porteus"}, + .lines = FASTFETCH_DATATEXT_LOGO_PORTEUS, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + }, + // PostMarketOS + { + .names = {"PostMarketOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_POSTMARKETOS, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + }, + // PostMarketOSSmall + { + .names = {"PostMarketOS_small"}, + .lines = FASTFETCH_DATATEXT_LOGO_POSTMARKETOS_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + }, + // PuffOS + { + .names = {"PuffOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_PUFFOS, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + }, + }, + // Puppy + { + .names = {"Puppy"}, + .lines = FASTFETCH_DATATEXT_LOGO_PUPPY, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // PureOS + { + .names = {"PureOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_PUREOS, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + }, + // PureOSSmall + { + .names = {"PureOS_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_PUREOS_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + }, + // LAST + {}, +}; + +static const FFlogo Q[] = { + // Q4OS + { + .names = {"Q4OS"}, + .lines = FASTFETCH_DATATEXT_LOGO_Q4OS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_RED, + }, + }, + // Qubes + { + .names = {"Qubes"}, + .lines = FASTFETCH_DATATEXT_LOGO_QUBES, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + }, + }, + // Qubyt + { + .names = {"Qubyt"}, + .lines = FASTFETCH_DATATEXT_LOGO_QUBYT, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_BLACK, + }, + }, + // Quibian + { + .names = {"Quibian"}, + .lines = FASTFETCH_DATATEXT_LOGO_QUIBIAN, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + }, + }, + // LAST + {}, +}; + +static const FFlogo R[] = { + // Radix + { + .names = {"Radix"}, + .lines = FASTFETCH_DATATEXT_LOGO_RADIX, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_RED, + }, + }, + // Raspbian + { + .names = {"raspbian", "raspi", "raspberrypi", "raspberrypios"}, + .lines = FASTFETCH_DATATEXT_LOGO_RASPBIAN, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // RaspbianSmall + { + .names = {"raspbian_small", "raspi_small", "raspberrypi_small", "raspberrypios_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_RASPBIAN_SMALL, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // RavynOS + { + .names = {"RavynOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_RAVYNOS, + .colors = { + FF_COLOR_FG_256 "15", + FF_COLOR_FG_WHITE, + }, + }, + // Reborn + { + .names = {"Reborn", "Reborn OS", "reborn-os", "rebornos", "rebornos-linux", "reborn-os-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_REBORN, + .colors = { + FF_COLOR_FG_BLACK, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // RebornSmall + { + .names = {"Reborn_small", "Reborn OS_small", "reborn-os-small", "rebornos_small", "rebornos-linux-small", "reborn-os-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_REBORN_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // RedCore + { + .names = {"RedCore"}, + .lines = FASTFETCH_DATATEXT_LOGO_REDCORE, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // RedHatEnterpriseLinux + { + .names = {"rhel", "redhat", "redhat-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_RHEL, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // RedHatEnterpriseLinux_old + { + .names = {"rhel_old", "redhat_old", "redhat-linux_old"}, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_RHEL_OLD, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // RedstarOS + { + .names = {"redstar", "redstar-os", "redstaros", "redstaros-linux", "redstar-os-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_REDSTAR, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // Refracted Devuan + { + .names = {"Refracted Devuan", "refracted-devuan"}, + .lines = FASTFETCH_DATATEXT_LOGO_REFRACTED_DEVUAN, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_LIGHT_BLACK, + }, + .colorKeys = FF_COLOR_FG_LIGHT_BLACK, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Regata + { + .names = {"Regata"}, + .lines = FASTFETCH_DATATEXT_LOGO_REGATA, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_RED, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_GREEN, + }, + }, + // Regolith + { + .names = {"Regolith"}, + .lines = FASTFETCH_DATATEXT_LOGO_REGOLITH, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // RhaymOS + { + .names = {"RhaymOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_RHAYMOS, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // RockyLinux + { + .names = {"rocky", "rocky-linux", "rockylinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ROCKY, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // RockyLinuxSmall + { + .names = {"rocky_small", "rocky-linux_small", "rockylinux_small"}, + .lines = FASTFETCH_DATATEXT_LOGO_ROCKY_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // RosaLinux + { + .names = {"rosa", "rosa-linux", "rosalinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ROSA, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Proxmox + { + .names = {"proxmox"}, + .lines = FASTFETCH_DATATEXT_LOGO_PROXMOX, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_256 "202" + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_256 "202", + }, + // LAST + {}, +}; + +static const FFlogo S[] = { + // Sabayon + { + .names = {"Sabayon"}, + .lines = FASTFETCH_DATATEXT_LOGO_SABAYON, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // Sabotage + { + .names = {"Sabotage"}, + .lines = FASTFETCH_DATATEXT_LOGO_SABOTAGE, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Sailfish + { + .names = {"Sailfish"}, + .lines = FASTFETCH_DATATEXT_LOGO_SAILFISH, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + }, + }, + // SalentOS + { + .names = {"SalentOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_SALENTOS, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_RED, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + }, + }, + // SalientOS + { + .names = {"Salient OS", "SalientOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_SALIENTOS, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + }, + // Salix + { + .names = {"Salix"}, + .lines = FASTFETCH_DATATEXT_LOGO_SALIX, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_GREEN, + }, + }, + // SambaBOX + { + .names = {"SambaBOX", "Profelis SambaBOX"}, + .lines = FASTFETCH_DATATEXT_LOGO_SAMBABOX, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_CYAN, + }, + }, + // Sasanqua + { + .names = {"Sasanqua"}, + .lines = FASTFETCH_DATATEXT_LOGO_SASANQUA, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_RED, + }, + }, + // Scientific + { + .names = {"Scientific"}, + .lines = FASTFETCH_DATATEXT_LOGO_SCIENTIFIC, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_RED, + }, + }, + // Semc + { + .names = {"semc"}, + .lines = FASTFETCH_DATATEXT_LOGO_SEMC, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_LIGHT_BLACK, + FF_COLOR_FG_RED, + }, + }, + // Septor + { + .names = {"Septor"}, + .lines = FASTFETCH_DATATEXT_LOGO_SEPTOR, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_BLUE, + }, + }, + // Serene + { + .names = {"Serene"}, + .lines = FASTFETCH_DATATEXT_LOGO_SERENE, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_CYAN, + }, + }, + // SharkLinux + { + .names = {"SharkLinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_SHARKLINUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // ShastraOS + { + .names = {"ShastraOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_SHASTRAOS, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + }, + // Siduction + { + .names = {"Siduction"}, + .lines = FASTFETCH_DATATEXT_LOGO_SIDUCTION, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + } + }, + // SkiffOS + { + .names = {"SkiffOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_SKIFFOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // Slitaz + { + .names = {"Slitaz"}, + .lines = FASTFETCH_DATATEXT_LOGO_SLITAZ, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_YELLOW, + }, + }, + // Slackel + { + .names = {"Slackel"}, + .lines = FASTFETCH_DATATEXT_LOGO_SLACKEL, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_YELLOW, + }, + }, + // Slackware + { + .names = {"slackware", "slackware-linux", "slackwarelinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_SLACKWARE, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // SlackwareSmall + { + .names = {"slackware-small", "slackware-linux-small", "slackware_small", "slackwarelinux_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_SLACKWARE_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // SmartOS + { + .names = {"SmartOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_SMARTOS, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + }, + // Soda + { + .names = {"Soda"}, + .lines = FASTFETCH_DATATEXT_LOGO_SODA, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // SourceMage + { + .names = {"Source Mage", "source_mage"}, + .lines = FASTFETCH_DATATEXT_LOGO_SOURCE_MAGE, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Solaris + { + .names = {"solaris", "sunos"}, + .lines = FASTFETCH_DATATEXT_LOGO_SOLARIS, + .colors = { + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // SolarisSmall + { + .names = {"solaris-small", "solaris_small", "sunos-small", "sunos_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_SOLARIS_SMALL, + .colors = { + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Solus + { + .names = {"solus", "solus-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_SOLUS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Sparky + { + .names = {"Sparky"}, + .lines = FASTFETCH_DATATEXT_LOGO_SPARKY, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE + }, + }, + // Star + { + .names = {"Star"}, + .lines = FASTFETCH_DATATEXT_LOGO_STAR, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_WHITE, + }, + }, + // StockLinux + { + .names = {"Stock Linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_STOCK_LINUX, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // SteamOS + { + .names = {"steamos"}, + .lines = FASTFETCH_DATATEXT_LOGO_STEAMOS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // Sulin + { + .names = {"Sulin"}, + .lines = FASTFETCH_DATATEXT_LOGO_SULIN, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // Suse + { + .names = {"suse", "suse-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_SUSE, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_GREEN, + }, + }, + // SuseSmall + { + .names = {"suse_small", "suse-linux_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_GREEN, + }, + }, + // Swagarch + { + .names = {"Swagarch"}, + .lines = FASTFETCH_DATATEXT_LOGO_SWAGARCH, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // LAST + {}, +}; + +static const FFlogo T[] = { + // T2 + { + .names = {"T2"}, + .lines = FASTFETCH_DATATEXT_LOGO_T2, + .colors = { + FF_COLOR_FG_WHITE, + FF_COLOR_FG_BLUE, + }, + }, + // Tails + { + .names = {"Tails"}, + .lines = FASTFETCH_DATATEXT_LOGO_TAILS, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // TeArch + { + .names = {"TeArch"}, + .lines = FASTFETCH_DATATEXT_LOGO_TEARCH, + .colors = { + FF_COLOR_FG_256 "39", + FF_COLOR_FG_WHITE, + }, + }, + // TorizonCore + { + .names = {"TorizonCore"}, + .lines = FASTFETCH_DATATEXT_LOGO_TORIZONCORE, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_LIGHT_BLACK, + FF_COLOR_FG_MAGENTA, + }, + }, + // Trisquel + { + .names = {"Trisquel"}, + .lines = FASTFETCH_DATATEXT_LOGO_TRISQUEL, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_CYAN, + }, + }, + // Twister + { + .names = {"Twister"}, + .lines = FASTFETCH_DATATEXT_LOGO_TWISTER, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_RED, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + }, + }, + // LAST + {}, +}; + +static const FFlogo U[] = { + // Ubuntu + { + .names = {"ubuntu", "ubuntu-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // UbuntuBudgie + { + .names = {"ubuntu budgie", "ubuntu-budgie"}, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_BUDGIE, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // UbuntuCinnamon + { + .names = {"ubuntu cinnamon", "ubuntu-cinnamon"}, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_CINNAMON, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // UbuntuGnome + { + .names = {"ubuntu gnome", "ubuntu-gnome"}, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_GNOME, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_MAGENTA, + }, + // UbuntuKylin + { + .names = {"ubuntu kylin", "ubuntu-kylin"}, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_KYLIN, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // UbuntuMate + { + .names = {"ubuntu mate", "ubuntu-mate"}, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_MATE, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // UbuntuOld + { + .names = {"ubuntu_old", "ubuntu-linux_old"}, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // UbuntuKde + { + .names = {"ubuntu kde", "ubuntu-kde", "ubuntu-plasma"}, + .lines = FASTFETCH_DATATEXT_LOGO_KUBUNTU, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // UbuntuSmall + { + .names = {"ubuntu_small", "ubuntu-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_SMALL, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // UbuntuStudio + { + .names = {"ubuntu studio", "ubuntu-studio"}, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_STUDIO, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + }, + // UbuntuSway + { + .names = {"ubuntu sway", "ubuntu-sway"}, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_SWAY, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + }, + // UbuntuTouch + { + .names = {"ubuntu touch", "ubuntu-touch"}, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_TOUCH, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_WHITE, + }, + }, + // UbuntuUnity + { + .names = {"ubuntu unity", "ubuntu-unity"}, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_UNITY, + .colors = { + FF_COLOR_FG_MAGENTA, + FF_COLOR_FG_WHITE, + }, + }, + // Ubuntu2Small + { + .names = {"ubuntu2_small", "ubuntu2-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU2_SMALL, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, + // Ubuntu2Old + { + .names = {"ubuntu2_old"}, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_UBUNTU2_OLD, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_YELLOW, + }, + }, + // Ultramarine + { + .names = {"Ultramarine", "Ultramarine Linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ULTRAMARINE, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + }, + // Univalent + { + .names = {"Univalent"}, + .lines = FASTFETCH_DATATEXT_LOGO_UNIVALENT, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_CYAN, + }, + }, + // Univention + { + .names = {"Univention"}, + .lines = FASTFETCH_DATATEXT_LOGO_UNIVENTION, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // UOS + { + .names = {"UOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_UOS, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // UrukOS + { + .names = {"UrukOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_URUKOS, + .colors = { + FF_COLOR_FG_LIGHT_BLUE, + FF_COLOR_FG_LIGHT_BLUE, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_LIGHT_BLUE, + FF_COLOR_FG_BLUE, + } + }, + // Uwuntu + { + .names = {"uwuntu"}, + .lines = FASTFETCH_DATATEXT_LOGO_UWUNTU, + .colors = { + FF_COLOR_FG_256 "225", + FF_COLOR_FG_256 "206", + FF_COLOR_FG_256 "52", + }, + }, + // LAST + {}, +}; + +static const FFlogo V[] = { + // Vanilla + { + .names = {"vanilla", "vanilla-os", "vanilla-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_VANILLA, + .colors = { + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_YELLOW, + }, + // Venom + { + .names = {"Venom"}, + .lines = FASTFETCH_DATATEXT_LOGO_VENOM, + .colors = { + FF_COLOR_FG_LIGHT_BLACK, + FF_COLOR_FG_BLUE, + }, + }, + // Vnux + { + .names = {"Vnux"}, + .lines = FASTFETCH_DATATEXT_LOGO_VNUX, + .colors = { + FF_COLOR_FG_256 "11", + FF_COLOR_FG_256 "8", + FF_COLOR_FG_256 "15", + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, + }, + // Vzlinux + { + .names = {"Vzlinux"}, + .lines = FASTFETCH_DATATEXT_LOGO_VZLINUX, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + FF_COLOR_FG_YELLOW, + }, + }, + // Void + { + .names = {"void", "void-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_VOID, + .colors = { + FF_COLOR_FG_GREEN, + FF_COLOR_FG_BLACK, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // VoidSmall + { + .names = {"void_small", "void-linux-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_VOID_SMALL, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_WHITE, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // LAST + {}, +}; + +static const FFlogo W[] = { + // WiiLinuxNgx + { + .names = {"WiiLinuxNgx"}, + .lines = FASTFETCH_DATATEXT_LOGO_WII_LINUX_NGX, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + }, + }, + // Windows11 + { + .names = {"Windows 11", "Windows Server 2022"}, + .lines = FASTFETCH_DATATEXT_LOGO_WINDOWS_11, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Windows11Small + { + .names = {"Windows 11_small", "Windows 11-small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_WINDOWS_11_SMALL, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_CYAN, + }, + // Windows8 + { + .names = {"Windows 8", "Windows 8.1", "Windows 10", "Windows Server 2012", "Windows Server 2012 R2", "Windows Server 2016", "Windows Server 2019"}, + .lines = FASTFETCH_DATATEXT_LOGO_WINDOWS_8, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_CYAN, + FF_COLOR_FG_CYAN, + FF_COLOR_FG_CYAN, + }, + .colorKeys = FF_COLOR_FG_YELLOW, + .colorTitle = FF_COLOR_FG_WHITE, + }, + // Windows + { + .names = {"Windows", "Windows 7", "Windows Server 2008", "Windows Server 2008 R2"}, + .lines = FASTFETCH_DATATEXT_LOGO_WINDOWS, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_GREEN, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_YELLOW, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Windows95 + { + .names = {"Windows 95", "Windows 9x"}, + .lines = FASTFETCH_DATATEXT_LOGO_WINDOWS_95, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_BLUE, + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_GREEN, + FF_COLOR_FG_RED, + FF_COLOR_FG_BLACK, + }, + .colorKeys = FF_COLOR_FG_CYAN, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // LAST + {}, +}; + +static const FFlogo X[] = { + // Xferience + { + .names = {"Xferience"}, + .lines = FASTFETCH_DATATEXT_LOGO_XFERIENCE, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_CYAN, + }, + }, + // LAST + {}, +}; + +static const FFlogo Y[] = { + // YiffOS + { + .names = {"YiffOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_YIFFOS, + .colors = { + FF_COLOR_FG_256 "93", + FF_COLOR_FG_256 "92", + }, + }, + // LAST + {}, +}; + +static const FFlogo Z[] = { + // Zorin + { + .names = {"zorin", "zorin-linux", "zorinos", "zorinos-linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ZORIN, + .colors = { + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, + // LAST + {}, +}; + +const FFlogo* ffLogoBuiltins[] = { + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, +}; diff --git a/src/logo/image/im6.c b/src/logo/image/im6.c index ba652a3705..c9a1e56a40 100644 --- a/src/logo/image/im6.c +++ b/src/logo/image/im6.c @@ -12,12 +12,12 @@ static void* logoResize(const void* image, size_t width, size_t height, void* ex return ffResizeImage(image, width, height, UndefinedFilter, 1.0, exceptionInfo); } -FFLogoImageResult ffLogoPrintImageIM6(FFinstance* instance, FFLogoRequestData* requestData) +FFLogoImageResult ffLogoPrintImageIM6(FFLogoRequestData* requestData) { - FF_LIBRARY_LOAD(imageMagick, &instance->config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8) + FF_LIBRARY_LOAD(imageMagick, &instance.config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR); - return ffLogoPrintImageImpl(instance, requestData, &(FFIMData) { + return ffLogoPrintImageImpl(requestData, &(FFIMData) { .resizeFunc = logoResize, .library = imageMagick, }); diff --git a/src/logo/image/im7.c b/src/logo/image/im7.c index 0677b4911c..394e124dfd 100644 --- a/src/logo/image/im7.c +++ b/src/logo/image/im7.c @@ -12,16 +12,16 @@ static void* logoResize(const void* image, size_t width, size_t height, void* ex return ffResizeImage(image, width, height, UndefinedFilter, exceptionInfo); } -FFLogoImageResult ffLogoPrintImageIM7(FFinstance* instance, FFLogoRequestData* requestData) +FFLogoImageResult ffLogoPrintImageIM7(FFLogoRequestData* requestData) { - FF_LIBRARY_LOAD(imageMagick, &instance->config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, + FF_LIBRARY_LOAD(imageMagick, &instance.config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-7.Q16HDRI" FF_LIBRARY_EXTENSION, 11, "libMagickCore-7.Q16" FF_LIBRARY_EXTENSION, 11, "libMagickCore-7.Q16HDRI-10" FF_LIBRARY_EXTENSION, -1 // Required for Windows ) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR); - return ffLogoPrintImageImpl(instance, requestData, &(FFIMData) { + return ffLogoPrintImageImpl(requestData, &(FFIMData) { .resizeFunc = logoResize, .library = imageMagick, }); diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 4fe3b2a579..f50b734237 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -14,8 +14,7 @@ static FFstrbuf base64Encode(FFstrbuf* in) { const char* base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - FFstrbuf out; - ffStrbufInitA(&out, 8 * (1 + in->length / 6)); + FFstrbuf out = ffStrbufCreateA(8 * (1 + in->length / 6)); unsigned val = 0; int valb = -6; @@ -35,57 +34,58 @@ static FFstrbuf base64Encode(FFstrbuf* in) return out; } -static bool printImageIterm(FFinstance* instance) +static bool printImageIterm(void) { - if(instance->config.logo.width == 0 || instance->config.logo.height == 0) + if(instance.config.logo.width == 0 || instance.config.logo.height == 0) { fputs("Logo: `iterm` protocol only works when both `--logo-width` and `--logo-height` being specified\n", stderr); return false; } - FFstrbuf buf; - ffStrbufInit(&buf); - if(!ffAppendFileBuffer(instance->config.logo.source.chars, &buf)) + FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate(); + if(!ffAppendFileBuffer(instance.config.logo.source.chars, &buf)) { fputs("Logo: Failed to load image file\n", stderr); return false; } - ffPrintCharTimes('\n', instance->config.logo.paddingTop); - ffPrintCharTimes(' ', instance->config.logo.paddingLeft); - FFstrbuf base64 = base64Encode(&buf); - instance->state.logoWidth = instance->config.logo.width + instance->config.logo.paddingLeft + instance->config.logo.paddingRight; - instance->state.logoHeight = instance->config.logo.paddingTop + instance->config.logo.height; + ffPrintCharTimes('\n', instance.config.logo.paddingTop); + ffPrintCharTimes(' ', instance.config.logo.paddingLeft); + + FF_STRBUF_AUTO_DESTROY base64 = base64Encode(&buf); + instance.state.logoWidth = instance.config.logo.width + instance.config.logo.paddingLeft + instance.config.logo.paddingRight; + instance.state.logoHeight = instance.config.logo.paddingTop + instance.config.logo.height; printf("\033]1337;File=inline=1;width=%u;height=%u;preserveAspectRatio=%u:%s\a\033[9999999D\n\033[%uA", - (unsigned) instance->config.logo.width, - (unsigned) instance->config.logo.height, - (unsigned) instance->config.logo.preserveAspectRadio, + (unsigned) instance.config.logo.width, + (unsigned) instance.config.logo.height, + (unsigned) instance.config.logo.preserveAspectRadio, base64.chars, - (unsigned) instance->state.logoHeight + (unsigned) instance.state.logoHeight ); - ffStrbufDestroy(&buf); - ffStrbufDestroy(&base64); - return true; } -static bool printImageKittyDirect(FFinstance* instance) +static bool printImageKittyDirect(void) { - ffPrintCharTimes(' ', instance->config.logo.paddingLeft); - ffPrintCharTimes('\n', instance->config.logo.paddingTop); - FFstrbuf base64 = base64Encode(&instance->config.logo.source); - printf("\033_Ga=T,f=100,t=f,c=%u,r=%u,C=1;%s\033\\\033[9999999D", - (unsigned) instance->config.logo.width, - (unsigned) instance->config.logo.height, - base64.chars + if (!instance.config.logo.width || !instance.config.logo.height) + { + fputs("Logo: `kitty-direct` protocol only works when both `--logo-width` and `--logo-height` being specified\n", stderr); + return false; + } + ffPrintCharTimes('\n', instance.config.logo.paddingTop); + ffPrintCharTimes(' ', instance.config.logo.paddingLeft); + + FF_STRBUF_AUTO_DESTROY base64 = base64Encode(&instance.config.logo.source); + instance.state.logoWidth = instance.config.logo.width + instance.config.logo.paddingLeft + instance.config.logo.paddingRight; + instance.state.logoHeight = instance.config.logo.paddingTop + instance.config.logo.height; + printf("\033_Ga=T,f=100,t=f,c=%u,r=%u;%s\033\\\033[9999999D\n\033[%uA", + (unsigned) instance.config.logo.width, + (unsigned) instance.config.logo.height, + base64.chars, + (unsigned) instance.state.logoHeight ); - instance->state.logoWidth = instance->config.logo.width + instance->config.logo.paddingLeft + instance->config.logo.paddingRight; - instance->state.logoHeight = instance->config.logo.paddingTop + instance->config.logo.height; - - ffStrbufDestroy(&base64); - return true; } @@ -126,9 +126,9 @@ static inline char* realpath(const char* restrict file_name, char* restrict reso #include #include -static bool compressBlob(const FFinstance* instance, void** blob, size_t* length) +static bool compressBlob(void** blob, size_t* length) { - FF_LIBRARY_LOAD(zlib, &instance->config.libZ, false, "libz" FF_LIBRARY_EXTENSION, 2) + FF_LIBRARY_LOAD(zlib, &instance.config.libZ, false, "libz" FF_LIBRARY_EXTENSION, 2) FF_LIBRARY_LOAD_SYMBOL(zlib, compressBound, false) FF_LIBRARY_LOAD_SYMBOL(zlib, compress2, false) @@ -206,36 +206,36 @@ static void writeCacheUint32(FFLogoRequestData* requestData, uint32_t value, con writeCacheStrbuf(requestData, &content, cacheFileName); } -static void printImagePixels(FFinstance* instance, FFLogoRequestData* requestData, const FFstrbuf* result, const char* cacheFileName) +static void printImagePixels(FFLogoRequestData* requestData, const FFstrbuf* result, const char* cacheFileName) { //Calculate character dimensions - instance->state.logoWidth = requestData->logoCharacterWidth + instance->config.logo.paddingLeft + instance->config.logo.paddingRight; + instance.state.logoWidth = requestData->logoCharacterWidth + instance.config.logo.paddingLeft + instance.config.logo.paddingRight; - instance->state.logoHeight = requestData->logoCharacterHeight + instance->config.logo.paddingTop; + instance.state.logoHeight = requestData->logoCharacterHeight + instance.config.logo.paddingTop; if(requestData->type == FF_LOGO_TYPE_IMAGE_KITTY) - instance->state.logoHeight -= 1; + instance.state.logoHeight -= 1; //Write cache files writeCacheStrbuf(requestData, result, cacheFileName); - if(instance->config.logo.width == 0) - writeCacheUint32(requestData, instance->state.logoWidth, FF_CACHE_FILE_WIDTH); + if(instance.config.logo.width == 0) + writeCacheUint32(requestData, instance.state.logoWidth, FF_CACHE_FILE_WIDTH); - if(instance->config.logo.height == 0) - writeCacheUint32(requestData, instance->state.logoHeight, FF_CACHE_FILE_HEIGHT); + if(instance.config.logo.height == 0) + writeCacheUint32(requestData, instance.state.logoHeight, FF_CACHE_FILE_HEIGHT); //Write result to stdout - ffPrintCharTimes('\n', instance->config.logo.paddingTop); - ffPrintCharTimes(' ', instance->config.logo.paddingLeft); + ffPrintCharTimes('\n', instance.config.logo.paddingTop); + ffPrintCharTimes(' ', instance.config.logo.paddingLeft); fflush(stdout); ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), result); //Go to upper left corner fputs("\033[9999999D", stdout); - printf("\033[%uA", instance->state.logoHeight); + printf("\033[%uA", instance.state.logoHeight); } -static bool printImageSixel(FFinstance* instance, FFLogoRequestData* requestData, const ImageData* imageData) +static bool printImageSixel(FFLogoRequestData* requestData, const ImageData* imageData) { imageData->ffCopyMagickString(imageData->imageInfo->magick, "SIXEL", 6); @@ -248,7 +248,7 @@ static bool printImageSixel(FFinstance* instance, FFLogoRequestData* requestData result.chars = (char*) blob; result.length = (uint32_t) length; - printImagePixels(instance, requestData, &result, FF_CACHE_FILE_SIXEL); + printImagePixels(requestData, &result, FF_CACHE_FILE_SIXEL); free(blob); return true; @@ -271,7 +271,7 @@ static void appendKittyChunk(FFstrbuf* result, const char** blob, size_t* length *blob += chunkSize; } -static bool printImageKitty(FFinstance* instance, FFLogoRequestData* requestData, const ImageData* imageData) +static bool printImageKitty(FFLogoRequestData* requestData, const ImageData* imageData) { imageData->ffCopyMagickString(imageData->imageInfo->magick, "RGBA", 5); @@ -281,7 +281,7 @@ static bool printImageKitty(FFinstance* instance, FFLogoRequestData* requestData return false; #ifdef FF_HAVE_ZLIB - bool isCompressed = compressBlob(instance, &blob, &length); + bool isCompressed = compressBlob(&blob, &length); #else bool isCompressed = false; #endif @@ -291,8 +291,7 @@ static bool printImageKitty(FFinstance* instance, FFLogoRequestData* requestData if(!checkAllocationResult(chars, length)) return false; - FFstrbuf result; - ffStrbufInitA(&result, (uint32_t) (length + 1024)); + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA((uint32_t) (length + 1024)); const char* currentPos = chars; size_t remainingLength = length; @@ -304,18 +303,17 @@ static bool printImageKitty(FFinstance* instance, FFLogoRequestData* requestData while(remainingLength > 0) appendKittyChunk(&result, ¤tPos, &remainingLength, true); - printImagePixels(instance, requestData, &result, isCompressed ? FF_CACHE_FILE_KITTY_COMPRESSED : FF_CACHE_FILE_KITTY_UNCOMPRESSED); + printImagePixels(requestData, &result, isCompressed ? FF_CACHE_FILE_KITTY_COMPRESSED : FF_CACHE_FILE_KITTY_UNCOMPRESSED); - ffStrbufDestroy(&result); free(chars); return true; } #ifdef FF_HAVE_CHAFA #include -static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData, const ImageData* imageData) +static bool printImageChafa(FFLogoRequestData* requestData, const ImageData* imageData) { - FF_LIBRARY_LOAD(chafa, &instance->config.libChafa, false, + FF_LIBRARY_LOAD(chafa, &instance.config.libChafa, false, "libchafa" FF_LIBRARY_EXTENSION, 1, "libchafa-0" FF_LIBRARY_EXTENSION, -1 // Required for Windows ) @@ -339,36 +337,36 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData ChafaSymbolMap* symbolMap = ffchafa_symbol_map_new(); GError* error = NULL; - if(!ffchafa_symbol_map_apply_selectors(symbolMap, instance->config.logo.chafaSymbols.chars, &error)) + if(!ffchafa_symbol_map_apply_selectors(symbolMap, instance.config.logo.chafaSymbols.chars, &error)) fputs(error->message, stderr); ChafaCanvasConfig* canvasConfig = ffchafa_canvas_config_new(); ffchafa_canvas_config_set_geometry(canvasConfig, (gint) requestData->logoCharacterWidth, (gint) requestData->logoCharacterHeight); ffchafa_canvas_config_set_symbol_map(canvasConfig, symbolMap); - if(instance->config.logo.chafaFgOnly) + if(instance.config.logo.chafaFgOnly) { FF_LIBRARY_LOAD_SYMBOL_LAZY(chafa, chafa_canvas_config_set_fg_only_enabled); if(ffchafa_canvas_config_set_fg_only_enabled) ffchafa_canvas_config_set_fg_only_enabled(canvasConfig, true); } - if(instance->config.logo.chafaCanvasMode < CHAFA_CANVAS_MODE_MAX) + if(instance.config.logo.chafaCanvasMode < CHAFA_CANVAS_MODE_MAX) { FF_LIBRARY_LOAD_SYMBOL_LAZY(chafa, chafa_canvas_config_set_canvas_mode); if(ffchafa_canvas_config_set_canvas_mode) - ffchafa_canvas_config_set_canvas_mode(canvasConfig, (ChafaCanvasMode) instance->config.logo.chafaCanvasMode); + ffchafa_canvas_config_set_canvas_mode(canvasConfig, (ChafaCanvasMode) instance.config.logo.chafaCanvasMode); } - if(instance->config.logo.chafaColorSpace < CHAFA_COLOR_SPACE_MAX) + if(instance.config.logo.chafaColorSpace < CHAFA_COLOR_SPACE_MAX) { FF_LIBRARY_LOAD_SYMBOL_LAZY(chafa, chafa_canvas_config_set_color_space) if(ffchafa_canvas_config_set_color_space) - ffchafa_canvas_config_set_color_space(canvasConfig, (ChafaColorSpace) instance->config.logo.chafaColorSpace); + ffchafa_canvas_config_set_color_space(canvasConfig, (ChafaColorSpace) instance.config.logo.chafaColorSpace); } - if(instance->config.logo.chafaDitherMode < CHAFA_DITHER_MODE_MAX) + if(instance.config.logo.chafaDitherMode < CHAFA_DITHER_MODE_MAX) { FF_LIBRARY_LOAD_SYMBOL_LAZY(chafa, chafa_canvas_config_set_dither_mode) if(ffchafa_canvas_config_set_dither_mode) - ffchafa_canvas_config_set_dither_mode(canvasConfig, (ChafaDitherMode) instance->config.logo.chafaDitherMode); + ffchafa_canvas_config_set_dither_mode(canvasConfig, (ChafaDitherMode) instance.config.logo.chafaDitherMode); } ChafaCanvas* canvas = ffchafa_canvas_new(canvasConfig); @@ -387,7 +385,7 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData result.length = (uint32_t) str->len; result.chars = str->str; - ffLogoPrintChars(instance, result.chars, false); + ffLogoPrintChars(result.chars, false); writeCacheStrbuf(requestData, &result, FF_CACHE_FILE_CHAFA); // FIXME: These functions must be imported from `libglib` dlls on Windows @@ -409,7 +407,7 @@ static bool printImageChafa(FFinstance* instance, FFLogoRequestData* requestData } #endif -FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* requestData, const FFIMData* imData) +FFLogoImageResult ffLogoPrintImageImpl(FFLogoRequestData* requestData, const FFIMData* imData) { FF_LIBRARY_LOAD_SYMBOL(imData->library, MagickCoreGenesis, FF_LOGO_IMAGE_RESULT_INIT_ERROR); FF_LIBRARY_LOAD_SYMBOL(imData->library, MagickCoreTerminus, FF_LOGO_IMAGE_RESULT_INIT_ERROR); @@ -444,7 +442,7 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* } //+1, because we need to copy the null byte too - imageData.ffCopyMagickString(imageInfoIn->filename, instance->config.logo.source.chars, instance->config.logo.source.length + 1); + imageData.ffCopyMagickString(imageInfoIn->filename, instance.config.logo.source.chars, instance.config.logo.source.length + 1); imageData.image = ffReadImage(imageInfoIn, imageData.exceptionInfo); ffDestroyImageInfo(imageInfoIn); @@ -499,13 +497,13 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* if(requestData->type == FF_LOGO_TYPE_IMAGE_CHAFA) { #ifdef FF_HAVE_CHAFA - printSuccessful = printImageChafa(instance, requestData, &imageData); + printSuccessful = printImageChafa(requestData, &imageData); #endif } else if(requestData->type == FF_LOGO_TYPE_IMAGE_KITTY) - printSuccessful = printImageKitty(instance, requestData, &imageData); + printSuccessful = printImageKitty(requestData, &imageData); else if(requestData->type == FF_LOGO_TYPE_IMAGE_SIXEL) - printSuccessful = printImageSixel(instance, requestData, &imageData); + printSuccessful = printImageSixel(requestData, &imageData); ffDestroyImageInfo(imageData.imageInfo); ffDestroyImage(imageData.image); @@ -534,8 +532,7 @@ static void readCachedStrbuf(FFLogoRequestData* requestData, FFstrbuf* result, c static uint32_t readCachedUint32(FFLogoRequestData* requestData, const char* cacheFileName) { - FFstrbuf content; - ffStrbufInit(&content); + FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate(); readCachedStrbuf(requestData, &content, cacheFileName); uint32_t result = 0; @@ -548,33 +545,26 @@ static uint32_t readCachedUint32(FFLogoRequestData* requestData, const char* cac memcpy(&result, content.chars, sizeof(result)); - ffStrbufDestroy(&content); - return result; } -static bool printCachedChars(FFinstance* instance, FFLogoRequestData* requestData) +static bool printCachedChars(FFLogoRequestData* requestData) { - FFstrbuf content; - ffStrbufInitA(&content, 32768); + FF_STRBUF_AUTO_DESTROY content = ffStrbufCreateA(32768); if(requestData->type == FF_LOGO_TYPE_IMAGE_CHAFA) readCachedStrbuf(requestData, &content, FF_CACHE_FILE_CHAFA); if(content.length == 0) - { - ffStrbufDestroy(&content); return false; - } - ffLogoPrintChars(instance, content.chars, false); - ffStrbufDestroy(&content); + ffLogoPrintChars(content.chars, false); return true; } -static bool printCachedPixel(FFinstance* instance, FFLogoRequestData* requestData) +static bool printCachedPixel(FFLogoRequestData* requestData) { - requestData->logoCharacterWidth = instance->config.logo.width; + requestData->logoCharacterWidth = instance.config.logo.width; if(requestData->logoCharacterWidth == 0) { requestData->logoCharacterWidth = readCachedUint32(requestData, FF_CACHE_FILE_WIDTH); @@ -582,7 +572,7 @@ static bool printCachedPixel(FFinstance* instance, FFLogoRequestData* requestDat return false; } - requestData->logoCharacterHeight = instance->config.logo.height; + requestData->logoCharacterHeight = instance.config.logo.height; if(requestData->logoCharacterHeight == 0) { requestData->logoCharacterHeight = readCachedUint32(requestData, FF_CACHE_FILE_HEIGHT); @@ -603,8 +593,8 @@ static bool printCachedPixel(FFinstance* instance, FFLogoRequestData* requestDat if(fd == -1) return false; - ffPrintCharTimes('\n', instance->config.logo.paddingTop); - ffPrintCharTimes(' ', instance->config.logo.paddingLeft); + ffPrintCharTimes('\n', instance.config.logo.paddingTop); + ffPrintCharTimes(' ', instance.config.logo.paddingLeft); fflush(stdout); char buffer[32768]; @@ -614,21 +604,21 @@ static bool printCachedPixel(FFinstance* instance, FFLogoRequestData* requestDat close(fd); - instance->state.logoWidth = requestData->logoCharacterWidth + instance->config.logo.paddingLeft + instance->config.logo.paddingRight; - instance->state.logoHeight = requestData->logoCharacterHeight + instance->config.logo.paddingTop; + instance.state.logoWidth = requestData->logoCharacterWidth + instance.config.logo.paddingLeft + instance.config.logo.paddingRight; + instance.state.logoHeight = requestData->logoCharacterHeight + instance.config.logo.paddingTop; //Go to upper left corner fputs("\033[9999999D", stdout); - printf("\033[%uA", instance->state.logoHeight); + printf("\033[%uA", instance.state.logoHeight); return true; } -static bool printCached(FFinstance* instance, FFLogoRequestData* requestData) +static bool printCached(FFLogoRequestData* requestData) { if(requestData->type == FF_LOGO_TYPE_IMAGE_CHAFA) - return printCachedChars(instance, requestData); + return printCachedChars(requestData); else - return printCachedPixel(instance, requestData); + return printCachedPixel(requestData); } static bool getCharacterPixelDimensions(FFLogoRequestData* requestData) @@ -668,7 +658,7 @@ static bool getCharacterPixelDimensions(FFLogoRequestData* requestData) return requestData->characterPixelWidth > 1.0 && requestData->characterPixelHeight > 1.0; } -static bool printImageIfExistsSlowPath(FFinstance* instance, FFLogoType type, bool printError) +static bool printImageIfExistsSlowPath(FFLogoType type, bool printError) { FFLogoRequestData requestData; requestData.type = type; @@ -676,7 +666,7 @@ static bool printImageIfExistsSlowPath(FFinstance* instance, FFLogoType type, bo requestData.characterPixelHeight = 1; if( - (type != FF_LOGO_TYPE_IMAGE_CHAFA || instance->config.logo.width == 0 || instance->config.logo.height == 0) && + (type != FF_LOGO_TYPE_IMAGE_CHAFA || instance.config.logo.width == 0 || instance.config.logo.height == 0) && !getCharacterPixelDimensions(&requestData) ) { if(printError) @@ -684,15 +674,15 @@ static bool printImageIfExistsSlowPath(FFinstance* instance, FFLogoType type, bo return false; } - requestData.logoPixelWidth = simpleCeil((double) instance->config.logo.width * requestData.characterPixelWidth); - requestData.logoPixelHeight = simpleCeil((double) instance->config.logo.height * requestData.characterPixelHeight); + requestData.logoPixelWidth = simpleCeil((double) instance.config.logo.width * requestData.characterPixelWidth); + requestData.logoPixelHeight = simpleCeil((double) instance.config.logo.height * requestData.characterPixelHeight); ffStrbufInit(&requestData.cacheDir); - ffStrbufAppend(&requestData.cacheDir, &instance->state.platform.cacheDir); + ffStrbufAppend(&requestData.cacheDir, &instance.state.platform.cacheDir); ffStrbufAppendS(&requestData.cacheDir, "fastfetch/images"); ffStrbufEnsureFree(&requestData.cacheDir, PATH_MAX); - if(realpath(instance->config.logo.source.chars, requestData.cacheDir.chars + requestData.cacheDir.length) == NULL) + if(realpath(instance.config.logo.source.chars, requestData.cacheDir.chars + requestData.cacheDir.length) == NULL) { //We can safely return here, because if realpath failed, we surely won't be able to read the file ffStrbufDestroy(&requestData.cacheDir); @@ -708,7 +698,7 @@ static bool printImageIfExistsSlowPath(FFinstance* instance, FFLogoType type, bo ffStrbufAppendF(&requestData.cacheDir, "%u", requestData.logoPixelHeight); ffStrbufAppendC(&requestData.cacheDir, '/'); - if(!instance->config.recache && printCached(instance, &requestData)) + if(!instance.config.recache && printCached(&requestData)) { ffStrbufDestroy(&requestData.cacheDir); return true; @@ -717,12 +707,12 @@ static bool printImageIfExistsSlowPath(FFinstance* instance, FFLogoType type, bo FFLogoImageResult result = FF_LOGO_IMAGE_RESULT_INIT_ERROR; #ifdef FF_HAVE_IMAGEMAGICK7 - result = ffLogoPrintImageIM7(instance, &requestData); + result = ffLogoPrintImageIM7(&requestData); #endif #ifdef FF_HAVE_IMAGEMAGICK6 if(result == FF_LOGO_IMAGE_RESULT_INIT_ERROR) - result = ffLogoPrintImageIM6(instance, &requestData); + result = ffLogoPrintImageIM6(&requestData); #endif ffStrbufDestroy(&requestData.cacheDir); @@ -743,25 +733,20 @@ static bool printImageIfExistsSlowPath(FFinstance* instance, FFLogoType type, bo #endif //FF_HAVE_IMAGEMAGICK{6, 7} -bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type, bool printError) +bool ffLogoPrintImageIfExists(FFLogoType type, bool printError) { - if(!ffPathExists(instance->config.logo.source.chars, FF_PATHTYPE_FILE)) + if(!ffPathExists(instance.config.logo.source.chars, FF_PATHTYPE_FILE)) { if(printError) - fprintf(stderr, "Logo: Image source \"%s\" does not exist\n", instance->config.logo.source.chars); + fprintf(stderr, "Logo: Image source \"%s\" does not exist\n", instance.config.logo.source.chars); return false; } if(type == FF_LOGO_TYPE_IMAGE_ITERM) - return printImageIterm(instance); + return printImageIterm(); - if( - type == FF_LOGO_TYPE_IMAGE_KITTY && - ffStrbufEndsWithIgnCaseS(&instance->config.logo.source, ".png") && - instance->config.logo.width && - instance->config.logo.height - ) - return printImageKittyDirect(instance); + if(type == FF_LOGO_TYPE_IMAGE_KITTY_DIRECT) + return printImageKittyDirect(); #if !defined(FF_HAVE_CHAFA) if(type == FF_LOGO_TYPE_IMAGE_CHAFA) @@ -777,6 +762,6 @@ bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type, bool printE fputs("Logo: Image Magick support is not compiled in\n", stderr); return false; #else - return printImageIfExistsSlowPath(instance, type, printError); + return printImageIfExistsSlowPath(type, printError); #endif } diff --git a/src/logo/image/image.h b/src/logo/image/image.h index 83d77131a0..7d54edd8a9 100644 --- a/src/logo/image/image.h +++ b/src/logo/image/image.h @@ -35,17 +35,17 @@ typedef struct FFIMData void*(*resizeFunc)(const void* image, size_t width, size_t height, void* exceptionInfo); } FFIMData; -FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData* requestData, const FFIMData* imData); +FFLogoImageResult ffLogoPrintImageImpl(FFLogoRequestData* requestData, const FFIMData* imData); #endif #ifdef FF_HAVE_IMAGEMAGICK7 -FFLogoImageResult ffLogoPrintImageIM7(FFinstance* instance, FFLogoRequestData* requestData); +FFLogoImageResult ffLogoPrintImageIM7(FFLogoRequestData* requestData); #endif #ifdef FF_HAVE_IMAGEMAGICK6 #include -FFLogoImageResult ffLogoPrintImageIM6(FFinstance* instance, FFLogoRequestData* requestData); +FFLogoImageResult ffLogoPrintImageIM6(FFLogoRequestData* requestData); #endif #endif diff --git a/src/logo/logo.c b/src/logo/logo.c index 43d39bc97c..fa074e7d6b 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -1,44 +1,60 @@ -#include "logo.h" +#include "logo/logo.h" #include "common/io/io.h" #include "common/printing.h" #include "detection/os/os.h" #include "detection/terminalshell/terminalshell.h" #include "util/textModifier.h" +#include "util/stringUtils.h" #include #include -static void ffLogoPrintCharsRaw(FFinstance* instance, const char* data, size_t length) +typedef enum FFLogoSize { - fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); - ffPrintCharTimes('\n', instance->config.logo.paddingTop); - ffPrintCharTimes(' ', instance->config.logo.paddingLeft); + FF_LOGO_SIZE_UNKNOWN, + FF_LOGO_SIZE_NORMAL, + FF_LOGO_SIZE_SMALL, +} FFLogoSize; + +static void ffLogoPrintCharsRaw(const char* data, size_t length) +{ + FFLogoOptions* options = &instance.config.logo; + + if (instance.config.brightColor) + fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); + + ffPrintCharTimes('\n', options->paddingTop); + ffPrintCharTimes(' ', options->paddingLeft); fwrite(data, length, 1, stdout); - instance->state.logoHeight = instance->config.logo.paddingTop + instance->config.logo.height; - instance->state.logoWidth = instance->config.logo.paddingLeft + instance->config.logo.width + instance->config.logo.paddingRight; - printf("\033[9999999D\n\033[%uA", instance->state.logoHeight); + instance.state.logoHeight = options->paddingTop + options->height; + instance.state.logoWidth = options->paddingLeft + options->width + options->paddingRight; + printf("\033[9999999D\n\033[%uA", instance.state.logoHeight); } -void ffLogoPrintChars(FFinstance* instance, const char* data, bool doColorReplacement) +void ffLogoPrintChars(const char* data, bool doColorReplacement) { + FFLogoOptions* options = &instance.config.logo; + uint32_t currentlineLength = 0; - fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); - ffPrintCharTimes('\n', instance->config.logo.paddingTop); - ffPrintCharTimes(' ', instance->config.logo.paddingLeft); + if (instance.config.brightColor) + fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); + + ffPrintCharTimes('\n', options->paddingTop); + ffPrintCharTimes(' ', options->paddingLeft); - instance->state.logoHeight = instance->config.logo.paddingTop; + instance.state.logoHeight = options->paddingTop; //Use logoColor[0] as the default color if(doColorReplacement) - ffPrintColor(&instance->config.logo.colors[0]); + ffPrintColor(&options->colors[0]); while(*data != '\0') { //We are at the end of a line. Print paddings and update max line length if(*data == '\n' || (*data == '\r' && *(data + 1) == '\n')) { - ffPrintCharTimes(' ', instance->config.logo.paddingRight); + ffPrintCharTimes(' ', options->paddingRight); //We have \r\n, skip the \r if(*data == '\r') @@ -47,13 +63,13 @@ void ffLogoPrintChars(FFinstance* instance, const char* data, bool doColorReplac putchar('\n'); ++data; - ffPrintCharTimes(' ', instance->config.logo.paddingLeft); + ffPrintCharTimes(' ', options->paddingLeft); - if(currentlineLength > instance->state.logoWidth) - instance->state.logoWidth = currentlineLength; + if(currentlineLength > instance.state.logoWidth) + instance.state.logoWidth = currentlineLength; currentlineLength = 0; - ++instance->state.logoHeight; + ++instance.state.logoHeight; continue; } @@ -115,7 +131,7 @@ void ffLogoPrintChars(FFinstance* instance, const char* data, bool doColorReplac } else { - ffPrintColor(&instance->config.logo.colors[index]); + ffPrintColor(&options->colors[index]); ++data; continue; } @@ -148,281 +164,317 @@ void ffLogoPrintChars(FFinstance* instance, const char* data, bool doColorReplac } } - ffPrintCharTimes(' ', instance->config.logo.paddingRight); + ffPrintCharTimes(' ', options->paddingRight); fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); //Happens if the last line is the longest - if(currentlineLength > instance->state.logoWidth) - instance->state.logoWidth = currentlineLength; + if(currentlineLength > instance.state.logoWidth) + instance.state.logoWidth = currentlineLength; - instance->state.logoWidth += instance->config.logo.paddingLeft + instance->config.logo.paddingRight; + instance.state.logoWidth += options->paddingLeft + options->paddingRight; //Go to the leftmost position fputs("\033[9999999D", stdout); //If the logo height is > 1, go up the height - if(instance->state.logoHeight > 0) - printf("\033[%uA", instance->state.logoHeight); + if(instance.state.logoHeight > 0) + printf("\033[%uA", instance.state.logoHeight); } -static void logoApplyColors(FFinstance* instance, const FFlogo* logo) +static void logoApplyColors(const FFlogo* logo) { - if(instance->config.colorKeys.length == 0) - ffStrbufAppendS(&instance->config.colorKeys, logo->colorKeys); + if(instance.config.colorKeys.length == 0) + ffStrbufAppendS(&instance.config.colorKeys, logo->colorKeys ? logo->colorKeys : logo->colors[0]); - if(instance->config.colorTitle.length == 0) - ffStrbufAppendS(&instance->config.colorTitle, logo->colorTitle); + if(instance.config.colorTitle.length == 0) + ffStrbufAppendS(&instance.config.colorTitle, logo->colorTitle ? logo->colorTitle : logo->colors[1]); } -static bool logoHasName(const FFlogo* logo, const char* name) +static bool logoHasName(const FFlogo* logo, const FFstrbuf* name, bool small) { - const char** logoName = logo->names; - - while(*logoName != NULL) - { - if(strcasecmp(*logoName, name) == 0) + for( + const char* const* logoName = logo->names; + *logoName != NULL && logoName <= &logo->names[FASTFETCH_LOGO_MAX_NAMES]; + ++logoName + ) { + if(small) + { + uint32_t logoNameLength = (uint32_t) (strlen(*logoName) - strlen("_small")); + if(name->length == logoNameLength && strncasecmp(*logoName, name->chars, logoNameLength) == 0) return true; + } + if(ffStrbufIgnCaseEqualS(name, *logoName)) return true; - ++logoName; } return false; } -static const FFlogo* logoGetBuiltin(const char* name) +static const FFlogo* logoGetBuiltin(const FFstrbuf* name, FFLogoSize size) { - GetLogoMethod* methods = ffLogoBuiltinGetAll(); + if (name->length == 0 || !isalpha(name->chars[0])) + return NULL; - while(*methods != NULL) + for(const FFlogo* logo = ffLogoBuiltins[toupper(name->chars[0]) - 'A']; *logo->names; ++logo) { - const FFlogo* logo = (*methods)(); + switch (size) + { + // Never use alternate logos + case FF_LOGO_SIZE_NORMAL: + if(logo->type != FF_LOGO_LINE_TYPE_NORMAL) continue; + break; + case FF_LOGO_SIZE_SMALL: + if(logo->type != FF_LOGO_LINE_TYPE_SMALL_BIT) continue; + break; + default: + break; + } - if(logoHasName(logo, name)) + if(logoHasName(logo, name, size == FF_LOGO_SIZE_SMALL)) return logo; - - ++methods; } return NULL; } -static const FFlogo* logoGetBuiltinDetected(const FFinstance* instance) +static const FFlogo* logoGetBuiltinDetected(FFLogoSize size) { - const FFOSResult* os = ffDetectOS(instance); + const FFOSResult* os = ffDetectOS(); - const FFlogo* logo = logoGetBuiltin(os->id.chars); + const FFlogo* logo = logoGetBuiltin(&os->id, size); if(logo != NULL) return logo; - logo = logoGetBuiltin(os->name.chars); + logo = logoGetBuiltin(&os->name, size); if(logo != NULL) return logo; - logo = logoGetBuiltin(os->prettyName.chars); + logo = logoGetBuiltin(&os->prettyName, size); if(logo != NULL) return logo; - logo = logoGetBuiltin(os->idLike.chars); + logo = logoGetBuiltin(&os->idLike, size); if(logo != NULL) return logo; - logo = logoGetBuiltin(instance->state.platform.systemName.chars); + logo = logoGetBuiltin(&instance.state.platform.systemName, size); if(logo != NULL) return logo; - return ffLogoBuiltinGetUnknown(); + return &ffLogoUnknown; } -static inline void logoApplyColorsDetected(FFinstance* instance) +static inline void logoApplyColorsDetected(void) { - logoApplyColors(instance, logoGetBuiltinDetected(instance)); + logoApplyColors(logoGetBuiltinDetected(FF_LOGO_SIZE_NORMAL)); } -static void logoPrintStruct(FFinstance* instance, const FFlogo* logo) +static void logoPrintStruct(const FFlogo* logo) { - logoApplyColors(instance, logo); + logoApplyColors(logo); + + FFLogoOptions* options = &instance.config.logo; - const char** colors = logo->builtinColors; + const char* const* colors = logo->colors; for(int i = 0; *colors != NULL && i < FASTFETCH_LOGO_MAX_COLORS; i++, colors++) { - if(instance->config.logo.colors[i].length == 0) - ffStrbufAppendS(&instance->config.logo.colors[i], *colors); + if(options->colors[i].length == 0) + ffStrbufAppendS(&options->colors[i], *colors); } - ffLogoPrintChars(instance, logo->data, true); + ffLogoPrintChars(logo->lines, true); } -static void logoPrintNone(FFinstance* instance) +static void logoPrintNone(void) { - logoApplyColorsDetected(instance); - instance->state.logoHeight = 0; - instance->state.logoWidth = 0; + logoApplyColorsDetected(); + instance.state.logoHeight = 0; + instance.state.logoWidth = 0; } -static bool logoPrintBuiltinIfExists(FFinstance* instance, const char* name) +static bool logoPrintBuiltinIfExists(const FFstrbuf* name, FFLogoSize size) { - if(strcasecmp(name, "none") == 0) + if(ffStrbufIgnCaseEqualS(name, "none")) { - logoPrintNone(instance); + logoPrintNone(); return true; } - const FFlogo* logo = logoGetBuiltin(name); + const FFlogo* logo = logoGetBuiltin(name, size); if(logo == NULL) return false; - logoPrintStruct(instance, logo); + logoPrintStruct(logo); return true; } -static inline void logoPrintDetected(FFinstance* instance) +static inline void logoPrintDetected(FFLogoSize size) { - logoPrintStruct(instance, logoGetBuiltinDetected(instance)); + logoPrintStruct(logoGetBuiltinDetected(size)); } -static bool logoPrintData(FFinstance* instance, bool doColorReplacement) { - if(instance->config.logo.source.length == 0) +static bool logoPrintData(bool doColorReplacement) +{ + FFLogoOptions* options = &instance.config.logo; + if(options->source.length == 0) return false; - ffLogoPrintChars(instance, instance->config.logo.source.chars, doColorReplacement); - logoApplyColorsDetected(instance); + ffLogoPrintChars(options->source.chars, doColorReplacement); + logoApplyColorsDetected(); return true; } -static void updateLogoPath(FFinstance* instance) +static void updateLogoPath(void) { - if(ffPathExists(instance->config.logo.source.chars, FF_PATHTYPE_FILE)) + FFLogoOptions* options = &instance.config.logo; + + if(ffPathExists(options->source.chars, FF_PATHTYPE_FILE)) return; - FFstrbuf fullPath; - ffStrbufInit(&fullPath); + FF_STRBUF_AUTO_DESTROY fullPath = ffStrbufCreate(); + if (ffPathExpandEnv(options->source.chars, &fullPath) && ffPathExists(fullPath.chars, FF_PATHTYPE_FILE)) + { + ffStrbufSet(&options->source, &fullPath); + return; + } - FF_LIST_FOR_EACH(FFstrbuf, dataDir, instance->state.platform.dataDirs) + FF_LIST_FOR_EACH(FFstrbuf, dataDir, instance.state.platform.dataDirs) { //We need to copy it, because multiple threads might be using dataDirs at the same time ffStrbufSet(&fullPath, dataDir); ffStrbufAppendS(&fullPath, "fastfetch/logos/"); - ffStrbufAppend(&fullPath, &instance->config.logo.source); + ffStrbufAppend(&fullPath, &options->source); if(ffPathExists(fullPath.chars, FF_PATHTYPE_FILE)) { - ffStrbufSet(&instance->config.logo.source, &fullPath); + ffStrbufSet(&options->source, &fullPath); break; } } - - ffStrbufDestroy(&fullPath); } -static bool logoPrintFileIfExists(FFinstance* instance, bool doColorReplacement, bool raw) +static bool logoPrintFileIfExists(bool doColorReplacement, bool raw) { - FFstrbuf content; - ffStrbufInit(&content); + FFLogoOptions* options = &instance.config.logo; - if(!ffAppendFileBuffer(instance->config.logo.source.chars, &content)) + FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate(); + + if(!ffAppendFileBuffer(options->source.chars, &content)) { - ffStrbufDestroy(&content); - fputs("Logo: Failed to load file content from logo source\n", stderr); + fprintf(stderr, "Logo: Failed to load file content from logo source: %s \n", options->source.chars); return false; } - logoApplyColorsDetected(instance); + logoApplyColorsDetected(); if(raw) - ffLogoPrintCharsRaw(instance, content.chars, content.length); + ffLogoPrintCharsRaw(content.chars, content.length); else - ffLogoPrintChars(instance, content.chars, doColorReplacement); - ffStrbufDestroy(&content); + ffLogoPrintChars(content.chars, doColorReplacement); + return true; } -static bool logoPrintImageIfExists(FFinstance* instance, FFLogoType logo, bool printError) +static bool logoPrintImageIfExists(FFLogoType logo, bool printError) { - if(!ffLogoPrintImageIfExists(instance, logo, printError)) + if(!ffLogoPrintImageIfExists(logo, printError)) return false; - logoApplyColorsDetected(instance); + logoApplyColorsDetected(); return true; } -static bool logoTryKnownType(FFinstance* instance) +static bool logoTryKnownType(void) { - if(instance->config.logo.type == FF_LOGO_TYPE_NONE) + FFLogoOptions* options = &instance.config.logo; + + if(options->type == FF_LOGO_TYPE_NONE) { - logoApplyColorsDetected(instance); + logoApplyColorsDetected(); return true; } - if(instance->config.logo.type == FF_LOGO_TYPE_BUILTIN) - return logoPrintBuiltinIfExists(instance, instance->config.logo.source.chars); + if(options->type == FF_LOGO_TYPE_BUILTIN) + return logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_NORMAL); - if(instance->config.logo.type == FF_LOGO_TYPE_DATA) - return logoPrintData(instance, true); + if(options->type == FF_LOGO_TYPE_SMALL) + return logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_SMALL); - if(instance->config.logo.type == FF_LOGO_TYPE_DATA_RAW) - return logoPrintData(instance, false); + if(options->type == FF_LOGO_TYPE_DATA) + return logoPrintData(true); - updateLogoPath(instance); //We sure have a file, resolve relative paths + if(options->type == FF_LOGO_TYPE_DATA_RAW) + return logoPrintData(false); - if(instance->config.logo.type == FF_LOGO_TYPE_FILE) - return logoPrintFileIfExists(instance, true, false); + updateLogoPath(); //We sure have a file, resolve relative paths - if(instance->config.logo.type == FF_LOGO_TYPE_FILE_RAW) - return logoPrintFileIfExists(instance, false, false); + if(options->type == FF_LOGO_TYPE_FILE) + return logoPrintFileIfExists(true, false); - if(instance->config.logo.type == FF_LOGO_TYPE_IMAGE_RAW) + if(options->type == FF_LOGO_TYPE_FILE_RAW) + return logoPrintFileIfExists(false, false); + + if(options->type == FF_LOGO_TYPE_IMAGE_RAW) { - if(instance->config.logo.width == 0 || instance->config.logo.height == 0) + if(options->width == 0 || options->height == 0) { fputs("both `--logo-width` and `--logo-height` must be specified\n", stderr); return false; } - return logoPrintFileIfExists(instance, false, true); + return logoPrintFileIfExists(false, true); } - return logoPrintImageIfExists(instance, instance->config.logo.type, true); + return logoPrintImageIfExists(options->type, true); } -static void logoPrintKnownType(FFinstance* instance) +static void logoPrintKnownType(void) { - if(!logoTryKnownType(instance)) - logoPrintDetected(instance); + if(!logoTryKnownType()) + logoPrintDetected(FF_LOGO_SIZE_UNKNOWN); } -void ffLogoPrint(FFinstance* instance) +void ffLogoPrint(void) { //In pipe mode, we don't have a logo or padding. //We also don't need to set main color, because it won't be printed anyway. //So we can return quickly here. - if(instance->config.pipe) + if(instance.config.pipe) + { + instance.state.logoHeight = 0; + instance.state.logoWidth = 0; + return; + } + + const FFLogoOptions* options = &instance.config.logo; + + if (options->type == FF_LOGO_TYPE_NONE) { - instance->state.logoHeight = 0; - instance->state.logoWidth = 0; + logoPrintNone(); return; } //If the source is not set, we can directly print the detected logo. - if(instance->config.logo.source.length == 0) + if(options->source.length == 0) { - logoPrintDetected(instance); + logoPrintDetected(options->type == FF_LOGO_TYPE_SMALL ? FF_LOGO_SIZE_SMALL : FF_LOGO_SIZE_NORMAL); return; } //If the source and source type is set to something else than auto, always print with the set type. - if(instance->config.logo.source.length > 0 && instance->config.logo.type != FF_LOGO_TYPE_AUTO) + if(options->source.length > 0 && options->type != FF_LOGO_TYPE_AUTO) { - logoPrintKnownType(instance); + logoPrintKnownType(); return; } //If source matches the name of a builtin logo, print it and return. - if(logoPrintBuiltinIfExists(instance, instance->config.logo.source.chars)) + if(logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_UNKNOWN)) return; //Make sure the logo path is set correctly. - updateLogoPath(instance); + updateLogoPath(); - const FFTerminalShellResult* terminalShell = ffDetectTerminalShell(instance); + const FFTerminalShellResult* terminalShell = ffDetectTerminalShell(); //Terminal emulators that support kitty graphics protocol. bool supportsKitty = @@ -432,87 +484,81 @@ void ffLogoPrint(FFinstance* instance) ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "wayst") == 0; //Try to load the logo as an image. If it succeeds, print it and return. - if(logoPrintImageIfExists(instance, supportsKitty ? FF_LOGO_TYPE_IMAGE_KITTY : FF_LOGO_TYPE_IMAGE_CHAFA, false)) + if(logoPrintImageIfExists(supportsKitty ? FF_LOGO_TYPE_IMAGE_KITTY : FF_LOGO_TYPE_IMAGE_CHAFA, false)) return; //Try to load the logo as a file. If it succeeds, print it and return. - if(logoPrintFileIfExists(instance, true, false)) + if(logoPrintFileIfExists(true, false)) return; - logoPrintDetected(instance); + logoPrintDetected(FF_LOGO_SIZE_UNKNOWN); } -void ffLogoPrintLine(FFinstance* instance) +void ffLogoPrintLine(void) { - if(instance->state.logoWidth > 0) - printf("\033[%uC", instance->state.logoWidth); + if(instance.state.logoWidth > 0) + printf("\033[%uC", instance.state.logoWidth); - ++instance->state.keysHeight; + ++instance.state.keysHeight; } -void ffLogoPrintRemaining(FFinstance* instance) +void ffLogoPrintRemaining(void) { - while(instance->state.keysHeight <= instance->state.logoHeight) - { - ffLogoPrintLine(instance); - putchar('\n'); - } + if (instance.state.keysHeight <= instance.state.logoHeight) + ffPrintCharTimes('\n', instance.state.logoHeight - instance.state.keysHeight + 1); + instance.state.keysHeight = instance.state.logoHeight + 1; } -void ffLogoBuiltinPrint(FFinstance* instance) +void ffLogoBuiltinPrint(void) { - GetLogoMethod* methods = ffLogoBuiltinGetAll(); + FFLogoOptions* options = &instance.config.logo; - while(*methods != NULL) + for(uint8_t ch = 0; ch < 26; ++ch) { - const FFlogo* logo = (*methods)(); - printf("\033[%sm%s:\033[0m\n", logo->builtinColors[0], logo->names[0]); - logoPrintStruct(instance, logo); - ffLogoPrintRemaining(instance); - - //reset everything - instance->state.logoHeight = 0; - instance->state.keysHeight = 0; - for(uint8_t i = 0; i < FASTFETCH_LOGO_MAX_COLORS; i++) - ffStrbufClear(&instance->config.logo.colors[i]); - - puts("\n"); - ++methods; + for(const FFlogo* logo = ffLogoBuiltins[ch]; *logo->names; ++logo) + { + printf("\033[%sm%s:\033[0m\n", logo->colors[0], logo->names[0]); + logoPrintStruct(logo); + ffLogoPrintRemaining(); + + //reset everything + instance.state.logoHeight = 0; + instance.state.keysHeight = 0; + for(uint8_t i = 0; i < FASTFETCH_LOGO_MAX_COLORS; i++) + ffStrbufClear(&options->colors[i]); + + putchar('\n'); + } } } -void ffLogoBuiltinList() +void ffLogoBuiltinList(void) { - GetLogoMethod* methods = ffLogoBuiltinGetAll(); - uint32_t counter = 0; - - while(*methods != NULL) + for(uint8_t ch = 0; ch < 26; ++ch) { - const FFlogo* logo = (*methods)(); - const char** names = logo->names; + for(const FFlogo* logo = ffLogoBuiltins[ch]; *logo->names; ++logo) + { + ++counter; + printf("%u)%s ", counter, counter < 10 ? " " : ""); - printf("%u)%s ", counter, counter < 10 ? " " : ""); - ++counter; + for( + const char* const* names = logo->names; + *names != NULL && names <= &logo->names[FASTFETCH_LOGO_MAX_NAMES]; + ++names + ) + printf("\"%s\" ", *names); - while(*names != NULL) - { - printf("\"%s\" ", *names); - ++names; + putchar('\n'); } - - putchar('\n'); - ++methods; } } -void ffLogoBuiltinListAutocompletion() +void ffLogoBuiltinListAutocompletion(void) { - GetLogoMethod* methods = ffLogoBuiltinGetAll(); - - while(*methods != NULL) + for(uint8_t ch = 0; ch < 26; ++ch) { - printf("%s\n", (*methods)()->names[0]); - ++methods; + for(const FFlogo* logo = ffLogoBuiltins[ch]; *logo->names; ++logo) + printf("%s\n", logo->names[0]); } } diff --git a/src/logo/logo.h b/src/logo/logo.h index 0664f6f98a..62e8841436 100644 --- a/src/logo/logo.h +++ b/src/logo/logo.h @@ -5,25 +5,37 @@ #include "fastfetch.h" +typedef enum FFLogoLineType +{ + FF_LOGO_LINE_TYPE_NORMAL = 0, + FF_LOGO_LINE_TYPE_SMALL_BIT = 1 << 0, // The names of small logo must end with `_small` or `-small` + FF_LOGO_LINE_TYPE_ALTER_BIT = 1 << 1, +} FFLogoLineType; + typedef struct FFlogo { - const char* data; - const char** names; //Null terminated - const char** builtinColors; //Null terminated + const char* lines; + const char* names[FASTFETCH_LOGO_MAX_NAMES]; + const char* colors[FASTFETCH_LOGO_MAX_COLORS]; const char* colorKeys; const char* colorTitle; + FFLogoLineType type; } FFlogo; -typedef const FFlogo*(*GetLogoMethod)(); - //logo.c -void ffLogoPrintChars(FFinstance* instance, const char* data, bool doColorReplacement); +void ffLogoPrintChars(const char* data, bool doColorReplacement); //builtin.c -const FFlogo* ffLogoBuiltinGetUnknown(); -GetLogoMethod* ffLogoBuiltinGetAll(); +extern const FFlogo* ffLogoBuiltins[]; +extern const FFlogo ffLogoUnknown; //image/image.c -bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type, bool printError); +bool ffLogoPrintImageIfExists(FFLogoType type, bool printError); + +//option.c +void ffInitLogoOptions(FFLogoOptions* options); +bool ffParseLogoCommandOptions(FFLogoOptions* options, const char* key, const char* value); +void ffDestroyLogoOptions(FFLogoOptions* options); +const char* ffParseLogoJsonConfig(); #endif diff --git a/src/logo/option.c b/src/logo/option.c new file mode 100644 index 0000000000..96e9caed0b --- /dev/null +++ b/src/logo/option.c @@ -0,0 +1,405 @@ +#include "logo/logo.h" + +#include "common/jsonconfig.h" +#include "util/stringUtils.h" + +void ffInitLogoOptions(FFLogoOptions* options) +{ + ffStrbufInit(&options->source); + options->type = FF_LOGO_TYPE_AUTO; + for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i) + ffStrbufInit(&options->colors[i]); + options->width = 0; + options->height = 0; //preserve aspect ratio + options->paddingTop = 0; + options->paddingLeft = 0; + options->paddingRight = 4; + options->printRemaining = true; + options->preserveAspectRadio = false; + + options->chafaFgOnly = false; + ffStrbufInitStatic(&options->chafaSymbols, "block+border+space-wide-inverted"); // Chafa default + options->chafaCanvasMode = UINT32_MAX; + options->chafaColorSpace = UINT32_MAX; + options->chafaDitherMode = UINT32_MAX; +} + +bool ffParseLogoCommandOptions(FFLogoOptions* options, const char* key, const char* value) +{ + if (strcasecmp(key, "-l") == 0) + goto logoType; + + const char* subKey = ffOptionTestPrefix(key, "logo"); + if(subKey) + { + if (subKey[0] == '\0') + { +logoType: + if(value == NULL) + { + fprintf(stderr, "Error: usage: %s \n", key); + exit(477); + } + //this is usually wanted when disabling logo + if(strcasecmp(value, "none") == 0) + { + options->paddingTop = 0; + options->paddingRight = 0; + options->paddingLeft = 0; + options->type = FF_LOGO_TYPE_NONE; + } + else if(strcasecmp(value, "small") == 0) + { + options->type = FF_LOGO_TYPE_SMALL; + } + else + ffOptionParseString(key, value, &options->source); + } + else if(strcasecmp(subKey, "type") == 0) + { + options->type = (FFLogoType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "auto", FF_LOGO_TYPE_AUTO }, + { "builtin", FF_LOGO_TYPE_BUILTIN }, + { "small", FF_LOGO_TYPE_SMALL }, + { "file", FF_LOGO_TYPE_FILE }, + { "file-raw", FF_LOGO_TYPE_FILE_RAW }, + { "data", FF_LOGO_TYPE_DATA }, + { "data-raw", FF_LOGO_TYPE_DATA_RAW }, + { "sixel", FF_LOGO_TYPE_IMAGE_SIXEL }, + { "kitty", FF_LOGO_TYPE_IMAGE_KITTY }, + { "kitty-direct", FF_LOGO_TYPE_IMAGE_KITTY_DIRECT }, + { "iterm", FF_LOGO_TYPE_IMAGE_ITERM }, + { "chafa", FF_LOGO_TYPE_IMAGE_CHAFA }, + { "raw", FF_LOGO_TYPE_IMAGE_RAW }, + { "none", FF_LOGO_TYPE_NONE }, + {}, + }); + } + else if(ffStrStartsWithIgnCase(subKey, "color-") && subKey[6] != '\0' && subKey[7] == '\0') // matches "--logo-color-*" + { + //Map the number to an array index, so that '1' -> 0, '2' -> 1, etc. + int index = (int)subKey[6] - '0' - 1; + + //Match only --logo-color-[1-9] + if(index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS) + { + fprintf(stderr, "Error: invalid --color-[1-9] index: %c\n", key[13]); + exit(472); + } + if(value == NULL) + { + fprintf(stderr, "Error: usage: %s \n", key); + exit(477); + } + ffOptionParseColor(value, &options->colors[index]); + } + else if(strcasecmp(subKey, "width") == 0) + options->width = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "height") == 0) + options->height = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "padding") == 0) + { + uint32_t padding = ffOptionParseUInt32(key, value); + options->paddingLeft = padding; + options->paddingRight = padding; + } + else if(strcasecmp(subKey, "padding-top") == 0) + options->paddingTop = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "padding-left") == 0) + options->paddingLeft = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "padding-right") == 0) + options->paddingRight = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "print-remaining") == 0) + options->printRemaining = ffOptionParseBoolean(value); + else if(strcasecmp(subKey, "preserve-aspect-radio") == 0) + options->preserveAspectRadio = ffOptionParseBoolean(value); + else + return false; + } + else if((subKey = ffOptionTestPrefix(key, "file"))) + { + if(subKey[0] == '\0') + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_FILE; + } + else if(strcasecmp(key, "raw") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_FILE_RAW; + } + else + return false; + } + else if((subKey = ffOptionTestPrefix(key, "data"))) + { + if(subKey[0] == '\0') + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_DATA; + } + else if(strcasecmp(subKey, "raw") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_DATA_RAW; + } + else + return false; + } + else if(strcasecmp(key, "--sixel") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_IMAGE_SIXEL; + } + else if(strcasecmp(key, "--kitty") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_IMAGE_KITTY; + } + else if(strcasecmp(key, "--kitty-direct") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_IMAGE_KITTY_DIRECT; + } + else if(strcasecmp(key, "--iterm") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_IMAGE_ITERM; + } + else if(strcasecmp(key, "--raw") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_IMAGE_RAW; + } + else if((subKey = ffOptionTestPrefix(key, "chafa"))) + { + if(subKey[0] == '\0') + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_IMAGE_CHAFA; + } + else if(strcasecmp(subKey, "fg-only") == 0) + options->chafaFgOnly = ffOptionParseBoolean(value); + else if(strcasecmp(subKey, "symbols") == 0) + ffOptionParseString(key, value, &options->chafaSymbols); + else if(strcasecmp(subKey, "canvas-mode") == 0) + options->chafaCanvasMode = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "color-space") == 0) + options->chafaColorSpace = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "dither-mode") == 0) + options->chafaDitherMode = ffOptionParseUInt32(key, value); + else + return false; + } + else + return false; + + return true; +} + +void ffDestroyLogoOptions(FFLogoOptions* options) +{ + ffStrbufDestroy(&options->source); + ffStrbufDestroy(&options->chafaSymbols); + for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i) + ffStrbufDestroy(&options->colors[i]); +} + +const char* ffParseLogoJsonConfig(void) +{ + FFLogoOptions* options = &instance.config.logo; + + yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc); + assert(root); + + if (!yyjson_is_obj(root)) + return "Invalid JSON config format. Root value must be an object"; + + yyjson_val* object = yyjson_obj_get(root, "logo"); + if (!object) return NULL; + if (yyjson_is_null(object)) + { + options->type = FF_LOGO_TYPE_NONE; + options->paddingTop = 0; + options->paddingRight = 0; + options->paddingLeft = 0; + return NULL; + } + + if (yyjson_is_str(object)) + { + const char* value = yyjson_get_str(object); + ffStrbufSetS(&options->source, value); + return NULL; + } + + if (!yyjson_is_obj(object)) return "Property 'logo' must be an object"; + + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(object, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + + if (strcasecmp(key, "type") == 0) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "auto", FF_LOGO_TYPE_AUTO }, + { "builtin", FF_LOGO_TYPE_BUILTIN }, + { "small", FF_LOGO_TYPE_SMALL }, + { "file", FF_LOGO_TYPE_FILE }, + { "file-raw", FF_LOGO_TYPE_FILE_RAW }, + { "data", FF_LOGO_TYPE_DATA }, + { "data-raw", FF_LOGO_TYPE_DATA_RAW }, + { "sixel", FF_LOGO_TYPE_IMAGE_SIXEL }, + { "kitty", FF_LOGO_TYPE_IMAGE_KITTY }, + { "kitty-direct", FF_LOGO_TYPE_IMAGE_KITTY_DIRECT }, + { "iterm", FF_LOGO_TYPE_IMAGE_ITERM }, + { "chafa", FF_LOGO_TYPE_IMAGE_CHAFA }, + { "raw", FF_LOGO_TYPE_IMAGE_RAW }, + { "none", FF_LOGO_TYPE_NONE }, + {}, + }); + + if (error) return error; + options->type = (FFLogoType) value; + continue; + } + else if (strcasecmp(key, "source") == 0) + { + ffStrbufSetS(&options->source, yyjson_get_str(val)); + continue; + } + else if (strcasecmp(key, "color") == 0) + { + if (!yyjson_is_obj(val)) + return "Property 'color' must be an object"; + + yyjson_val *key_c, *valc; + size_t idxc, maxc; + yyjson_obj_foreach(val, idxc, maxc, key_c, valc) + { + const char* keyc = yyjson_get_str(key_c); + uint32_t index = (uint32_t) strtoul(keyc, NULL, 10); + if (index < 1 || index > 9) + return "Keys of property 'color' must be a number between 1 to 9"; + + ffOptionParseColor(yyjson_get_str(valc), &options->colors[index - 1]); + } + continue; + } + else if (strcasecmp(key, "width") == 0) + { + uint32_t value = (uint32_t) yyjson_get_uint(val); + if (value == 0) + return "Logo width must be a possitive integer"; + options->width = value; + continue; + } + else if (strcasecmp(key, "height") == 0) + { + uint32_t value = (uint32_t) yyjson_get_uint(val); + if (value == 0) + return "Logo height must be a possitive integer"; + options->height = value; + continue; + } + else if (strcasecmp(key, "padding") == 0) + { + if (!yyjson_is_obj(val)) + return "Logo padding must be an object"; + + #define FF_PARSE_PADDING_POSITON(pos, paddingPos) \ + yyjson_val* pos = yyjson_obj_get(val, #pos); \ + if (pos) \ + { \ + if (!yyjson_is_uint(pos)) \ + return "Logo padding values must be possitive integers"; \ + options->paddingPos = (uint32_t) yyjson_get_uint(pos); \ + } + FF_PARSE_PADDING_POSITON(left, paddingLeft); + FF_PARSE_PADDING_POSITON(top, paddingTop); + FF_PARSE_PADDING_POSITON(right, paddingRight); + #undef FF_PARSE_PADDING_POSITON + continue; + } + else if (strcasecmp(key, "printRemaining") == 0) + { + options->printRemaining = yyjson_get_bool(val); + continue; + } + else if (strcasecmp(key, "preserveAspectRadio") == 0) + { + options->preserveAspectRadio = yyjson_get_bool(val); + continue; + } + else if (strcasecmp(key, "chafa") == 0) + { + if (!yyjson_is_obj(val)) + return "Chafa config must be an object"; + + yyjson_val* fgOnly = yyjson_obj_get(val, "fgOnly"); + if (fgOnly) + options->chafaFgOnly = yyjson_get_bool(fgOnly); + + yyjson_val* symbols = yyjson_obj_get(val, "symbols"); + if (symbols) + ffStrbufAppendS(&options->chafaSymbols, yyjson_get_str(symbols)); + + yyjson_val* canvasMode = yyjson_obj_get(val, "canvasMode"); + if (canvasMode) + { + int value; + const char* error = ffJsonConfigParseEnum(canvasMode, &value, (FFKeyValuePair[]) { + { "TRUECOLOR", 0 }, + { "INDEXED_256", 1 }, + { "INDEXED_240", 2 }, + { "INDEXED_16", 3 }, + { "FGBG_BGFG", 4 }, + { "FGBG", 5 }, + { "INDEXED_8", 6 }, + { "INDEXED_16_8", 7 }, + {}, + }); + + if (error) return error; + options->chafaCanvasMode = (uint32_t) value; + } + + yyjson_val* colorSpace = yyjson_obj_get(val, "colorSpace"); + if (colorSpace) + { + int value; + const char* error = ffJsonConfigParseEnum(colorSpace, &value, (FFKeyValuePair[]) { + { "RGB", 0 }, + { "DIN99D", 1 }, + {}, + }); + + if (error) return error; + options->chafaColorSpace = (uint32_t) value; + } + + yyjson_val* ditherMode = yyjson_obj_get(val, "ditherMode"); + if (ditherMode) + { + int value; + const char* error = ffJsonConfigParseEnum(ditherMode, &value, (FFKeyValuePair[]) { + { "NONE", 0 }, + { "ORDERED", 1 }, + { "DIFFUSION", 2 }, + {}, + }); + + if (error) return error; + options->chafaDitherMode = (uint32_t) value; + } + continue; + } + else + return "Unknown logo key"; + } + + return NULL; +} diff --git a/src/logo/option.h b/src/logo/option.h new file mode 100644 index 0000000000..e1073db370 --- /dev/null +++ b/src/logo/option.h @@ -0,0 +1,44 @@ +#pragma once + +#include "util/FFstrbuf.h" + +#define FASTFETCH_LOGO_MAX_NAMES 9 +#define FASTFETCH_LOGO_MAX_COLORS 9 //two digits would make parsing much more complicated (index 1 - 9) + +typedef enum FFLogoType +{ + FF_LOGO_TYPE_AUTO, //if something is given, first try builtin, then file. Otherwise detect logo + FF_LOGO_TYPE_BUILTIN, //builtin ascii art + FF_LOGO_TYPE_SMALL, //builtin ascii art, small version + FF_LOGO_TYPE_FILE, //text file, printed with color code replacement + FF_LOGO_TYPE_FILE_RAW, //text file, printed as is + FF_LOGO_TYPE_DATA, //text data, printed with color code replacement + FF_LOGO_TYPE_DATA_RAW, //text data, printed as is + FF_LOGO_TYPE_IMAGE_SIXEL, //image file, printed as sixel codes. + FF_LOGO_TYPE_IMAGE_KITTY, //image file, printed as kitty graphics protocol + FF_LOGO_TYPE_IMAGE_KITTY_DIRECT, //image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm) + FF_LOGO_TYPE_IMAGE_ITERM, //image file, printed as iterm graphics protocol + FF_LOGO_TYPE_IMAGE_CHAFA, //image file, printed as ascii art using libchafa + FF_LOGO_TYPE_IMAGE_RAW, //image file, printed as raw binary string + FF_LOGO_TYPE_NONE, //--logo none +} FFLogoType; + +typedef struct FFLogoOptions +{ + FFstrbuf source; + FFLogoType type; + FFstrbuf colors[FASTFETCH_LOGO_MAX_COLORS]; + uint32_t width; + uint32_t height; + uint32_t paddingTop; + uint32_t paddingLeft; + uint32_t paddingRight; + bool printRemaining; + bool preserveAspectRadio; + + bool chafaFgOnly; + FFstrbuf chafaSymbols; + uint32_t chafaCanvasMode; + uint32_t chafaColorSpace; + uint32_t chafaDitherMode; +} FFLogoOptions; diff --git a/src/modules/battery.c b/src/modules/battery.c deleted file mode 100644 index 6bafb0ee7e..0000000000 --- a/src/modules/battery.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/bar.h" -#include "detection/battery/battery.h" - -#define FF_BATTERY_MODULE_NAME "Battery" -#define FF_BATTERY_NUM_FORMAT_ARGS 5 - -static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t index) -{ - if(instance->config.battery.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_BATTERY_MODULE_NAME, index, &instance->config.battery.key); - - bool showStatus = - !(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT) && - result->status.length > 0 && - ffStrbufIgnCaseCompS(&result->status, "Unknown") != 0; - - FFstrbuf str; - ffStrbufInit(&str); - - if(result->capacity >= 0) - { - if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) - { - if(result->capacity <= 20) - ffAppendPercentBar(instance, &str, (uint8_t)result->capacity, 10, 10, 0); - else if(result->capacity <= 50) - ffAppendPercentBar(instance, &str, (uint8_t)result->capacity, 10, 0, 10); - else - ffAppendPercentBar(instance, &str, (uint8_t)result->capacity, 0, 10, 10); - } - - if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) - { - if(str.length > 0) - ffStrbufAppendC(&str, ' '); - - ffAppendPercentNum(instance, &str, (uint8_t) result->capacity, 51, 21, str.length > 0); - } - } - - if(showStatus) - { - if(str.length > 0) - ffStrbufAppendF(&str, " [%s]", result->status.chars); - else - ffStrbufAppend(&str, &result->status); - } - - if(result->temperature == result->temperature) //FF_BATTERY_TEMP_UNSET - { - if(str.length > 0) - ffStrbufAppendS(&str, " - "); - - ffStrbufAppendF(&str, "%.1f°C", result->temperature); - } - - ffStrbufPutTo(&str, stdout); - ffStrbufDestroy(&str); - } - else - { - ffPrintFormat(instance, FF_BATTERY_MODULE_NAME, index, &instance->config.battery, FF_BATTERY_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->technology}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &result->capacity}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->status}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &result->temperature}, - }); - } -} - -void ffPrintBattery(FFinstance* instance) -{ - FFlist results; - ffListInitA(&results, sizeof(BatteryResult), 0); - - const char* error = ffDetectBatteryImpl(instance, &results); - - if (error) - { - ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &instance->config.battery, "%s", error); - } - else - { - for(uint8_t i = 0; i < (uint8_t) results.length; i++) - { - BatteryResult* result = ffListGet(&results, i); - printBattery(instance, result, i); - - ffStrbufDestroy(&result->manufacturer); - ffStrbufDestroy(&result->modelName); - ffStrbufDestroy(&result->technology); - ffStrbufDestroy(&result->status); - } - if(results.length == 0) - ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &instance->config.battery, "No batteries found"); - } - - ffListDestroy(&results); -} diff --git a/src/modules/battery/battery.c b/src/modules/battery/battery.c new file mode 100644 index 0000000000..5f5a93329b --- /dev/null +++ b/src/modules/battery/battery.c @@ -0,0 +1,187 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/bar.h" +#include "common/parsing.h" +#include "detection/battery/battery.h" +#include "modules/battery/battery.h" +#include "util/stringUtils.h" + +#define FF_BATTERY_NUM_FORMAT_ARGS 5 + +static void printBattery(FFBatteryOptions* options, BatteryResult* result, uint8_t index) +{ + if(instance.config.battery.moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_BATTERY_MODULE_NAME, index, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + bool showStatus = + !(instance.config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT) && + result->status.length > 0 && + ffStrbufIgnCaseCompS(&result->status, "Unknown") != 0; + + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + + if(result->capacity >= 0) + { + if(instance.config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + if(result->capacity <= 20) + ffAppendPercentBar(&str, (uint8_t)result->capacity, 10, 10, 0); + else if(result->capacity <= 50) + ffAppendPercentBar(&str, (uint8_t)result->capacity, 10, 0, 10); + else + ffAppendPercentBar(&str, (uint8_t)result->capacity, 0, 10, 10); + } + + if(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + { + if(str.length > 0) + ffStrbufAppendC(&str, ' '); + + ffAppendPercentNum(&str, (uint8_t) result->capacity, 51, 21, str.length > 0); + } + } + + if(showStatus) + { + if(str.length > 0) + ffStrbufAppendF(&str, " [%s]", result->status.chars); + else + ffStrbufAppend(&str, &result->status); + } + + if(result->temperature == result->temperature) //FF_BATTERY_TEMP_UNSET + { + if(str.length > 0) + ffStrbufAppendS(&str, " - "); + + ffParseTemperature(result->temperature, &str); + } + + ffStrbufPutTo(&str, stdout); + } + else + { + ffPrintFormat(FF_BATTERY_MODULE_NAME, index, &options->moduleArgs, FF_BATTERY_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->technology}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &result->capacity}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->status}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &result->temperature}, + }); + } +} + +void ffPrintBattery(FFBatteryOptions* options) +{ + FFlist results; + ffListInitA(&results, sizeof(BatteryResult), 0); + + const char* error = ffDetectBattery(options, &results); + + if (error) + { + ffPrintError(FF_BATTERY_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + } + else + { + for(uint8_t i = 0; i < (uint8_t) results.length; i++) + { + BatteryResult* result = ffListGet(&results, i); + printBattery(options, result, i); + + ffStrbufDestroy(&result->manufacturer); + ffStrbufDestroy(&result->modelName); + ffStrbufDestroy(&result->technology); + ffStrbufDestroy(&result->status); + } + if(results.length == 0) + ffPrintError(FF_BATTERY_MODULE_NAME, 0, &options->moduleArgs, "No batteries found"); + } + + ffListDestroy(&results); +} + +void ffInitBatteryOptions(FFBatteryOptions* options) +{ + options->moduleName = FF_BATTERY_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + options->temp = false; + + #ifdef __linux__ + ffStrbufInit(&options->dir); + #endif +} + +bool ffParseBatteryCommandOptions(FFBatteryOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BATTERY_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffStrEqualsIgnCase(subKey, "temp")) + { + options->temp = ffOptionParseBoolean(value); + return true; + } + + #ifdef __linux__ + if (ffStrEqualsIgnCase(subKey, "dir")) + { + ffOptionParseString(key, value, &options->dir); + return true; + } + #endif + + return false; +} + +void ffDestroyBatteryOptions(FFBatteryOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + + #ifdef __linux__ + ffStrbufDestroy(&options->dir); + #endif +} + +void ffParseBatteryJsonObject(yyjson_val* module) +{ + FFBatteryOptions __attribute__((__cleanup__(ffDestroyBatteryOptions))) options; + ffInitBatteryOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + #ifdef __linux__ + if (ffStrEqualsIgnCase(key, "dir")) + { + ffStrbufSetS(&options.dir, yyjson_get_str(val)); + continue; + } + #endif + + if (ffStrEqualsIgnCase(key, "temp")) + { + options.temp = yyjson_get_bool(val); + continue; + } + + ffPrintError(FF_BATTERY_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintBattery(&options); +} diff --git a/src/modules/battery/battery.h b/src/modules/battery/battery.h new file mode 100644 index 0000000000..a57a3718c5 --- /dev/null +++ b/src/modules/battery/battery.h @@ -0,0 +1,12 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BATTERY_MODULE_NAME "Battery" + +void ffPrintBattery(FFBatteryOptions* options); + +void ffInitBatteryOptions(FFBatteryOptions* options); +bool ffParseBatteryCommandOptions(FFBatteryOptions* options, const char* key, const char* value); +void ffDestroyBatteryOptions(FFBatteryOptions* options); +void ffParseBatteryJsonObject(yyjson_val* module); diff --git a/src/modules/battery/option.h b/src/modules/battery/option.h new file mode 100644 index 0000000000..73632b9c67 --- /dev/null +++ b/src/modules/battery/option.h @@ -0,0 +1,17 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFBatteryOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + bool temp; + + #ifdef __linux__ + FFstrbuf dir; + #endif +} FFBatteryOptions; diff --git a/src/modules/bios.c b/src/modules/bios.c deleted file mode 100644 index 7b38533555..0000000000 --- a/src/modules/bios.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/bios/bios.h" - -#define FF_BIOS_MODULE_NAME "Bios" -#define FF_BIOS_NUM_FORMAT_ARGS 4 - -void ffPrintBios(FFinstance* instance) -{ - FFBiosResult result; - ffDetectBios(&result); - - if(result.error.length > 0) - { - ffPrintError(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios, "%*s", result.error.length, result.error.chars); - goto exit; - } - - if(result.biosRelease.length == 0) - { - ffPrintError(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios, "bios_release is not set."); - goto exit; - } - - if(instance->config.bios.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios.key); - puts(result.biosRelease.chars); - } - else - { - ffPrintFormat(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios, FF_BIOS_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosDate}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosRelease}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVersion}, - }); - } - -exit: - ffStrbufDestroy(&result.biosDate); - ffStrbufDestroy(&result.biosRelease); - ffStrbufDestroy(&result.biosVendor); - ffStrbufDestroy(&result.biosVersion); - ffStrbufDestroy(&result.error); -} diff --git a/src/modules/bios/bios.c b/src/modules/bios/bios.c new file mode 100644 index 0000000000..398a7cc838 --- /dev/null +++ b/src/modules/bios/bios.c @@ -0,0 +1,100 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/bios/bios.h" +#include "modules/bios/bios.h" +#include "util/stringUtils.h" + +#define FF_BIOS_NUM_FORMAT_ARGS 4 + +void ffPrintBios(FFBiosOptions* options) +{ + FFBiosResult bios; + ffStrbufInit(&bios.date); + ffStrbufInit(&bios.release); + ffStrbufInit(&bios.vendor); + ffStrbufInit(&bios.version); + + const char* error = ffDetectBios(&bios); + + if(error) + { + ffPrintError(FF_BIOS_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + goto exit; + } + + if(bios.version.length == 0) + { + ffPrintError(FF_BIOS_MODULE_NAME, 0, &options->moduleArgs, "bios_version is not set."); + goto exit; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_BIOS_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufWriteTo(&bios.version, stdout); + if (bios.release.length) + printf(" (%s)", bios.release.chars); + putchar('\n'); + } + else + { + ffPrintFormat(FF_BIOS_MODULE_NAME, 0, &options->moduleArgs, FF_BIOS_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &bios.date}, + {FF_FORMAT_ARG_TYPE_STRBUF, &bios.release}, + {FF_FORMAT_ARG_TYPE_STRBUF, &bios.vendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &bios.version}, + }); + } + +exit: + ffStrbufDestroy(&bios.date); + ffStrbufDestroy(&bios.release); + ffStrbufDestroy(&bios.vendor); + ffStrbufDestroy(&bios.version); +} + +void ffInitBiosOptions(FFBiosOptions* options) +{ + options->moduleName = FF_BIOS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseBiosCommandOptions(FFBiosOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BIOS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyBiosOptions(FFBiosOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseBiosJsonObject(yyjson_val* module) +{ + FFBiosOptions __attribute__((__cleanup__(ffDestroyBiosOptions))) options; + ffInitBiosOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_BIOS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintBios(&options); +} diff --git a/src/modules/bios/bios.h b/src/modules/bios/bios.h new file mode 100644 index 0000000000..a82606f03a --- /dev/null +++ b/src/modules/bios/bios.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BIOS_MODULE_NAME "Bios" + +void ffPrintBios(FFBiosOptions* options); +void ffInitBiosOptions(FFBiosOptions* options); +bool ffParseBiosCommandOptions(FFBiosOptions* options, const char* key, const char* value); +void ffDestroyBiosOptions(FFBiosOptions* options); +void ffParseBiosJsonObject(yyjson_val* module); diff --git a/src/modules/bios/option.h b/src/modules/bios/option.h new file mode 100644 index 0000000000..6c0f674206 --- /dev/null +++ b/src/modules/bios/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFBiosOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFBiosOptions; diff --git a/src/modules/bluetooth.c b/src/modules/bluetooth.c deleted file mode 100644 index 6038acf01d..0000000000 --- a/src/modules/bluetooth.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "common/printing.h" -#include "detection/bluetooth/bluetooth.h" - -#define FF_BLUETOOTH_MODULE_NAME "Bluetooth" -#define FF_BLUETOOTH_NUM_FORMAT_ARGS 4 - -static void printDevice(FFinstance* instance, const FFBluetoothDevice* device, uint8_t index) -{ - if(instance->config.bluetooth.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_BLUETOOTH_MODULE_NAME, index, &instance->config.bluetooth.key); - ffStrbufWriteTo(&device->name, stdout); - - if(device->battery > 0) - printf(" (%d%%)", device->battery); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_BLUETOOTH_MODULE_NAME, index, &instance->config.bluetooth, FF_BLUETOOTH_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->address}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->type}, - {FF_FORMAT_ARG_TYPE_UINT8, &device->battery} - }); - } -} - -void ffPrintBluetooth(FFinstance* instance) -{ - const FFBluetoothResult* bluetooth = ffDetectBluetooth(instance); - - if(bluetooth->error.length > 0) - { - ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &instance->config.bluetooth, "%s", bluetooth->error.chars); - return; - } - - FFlist filtered; - ffListInit(&filtered, sizeof(FFBluetoothDevice*)); - - FF_LIST_FOR_EACH(FFBluetoothDevice, device, bluetooth->devices) - { - if(!device->connected && !instance->config.bluetoothShowDisconnected) - continue; - - *(FFBluetoothDevice**)ffListAdd(&filtered) = device; - } - - if(filtered.length == 0) - { - ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &instance->config.bluetooth, "No bluetooth devices found"); - return; - } - - for(uint32_t i = 0; i < filtered.length; i++) - { - uint8_t index = (uint8_t) (filtered.length == 1 ? 0 : i + 1); - printDevice(instance, *(FFBluetoothDevice**)ffListGet(&filtered, i), index); - } - - ffListDestroy(&filtered); -} diff --git a/src/modules/bluetooth/bluetooth.c b/src/modules/bluetooth/bluetooth.c new file mode 100644 index 0000000000..bbd5e0e11a --- /dev/null +++ b/src/modules/bluetooth/bluetooth.c @@ -0,0 +1,133 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/bluetooth/bluetooth.h" +#include "modules/bluetooth/bluetooth.h" +#include "util/stringUtils.h" + +#define FF_BLUETOOTH_NUM_FORMAT_ARGS 4 + +static void printDevice(FFBluetoothOptions* options, const FFBluetoothDevice* device, uint8_t index) +{ + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufWriteTo(&device->name, stdout); + + if(device->battery > 0) + printf(" (%d%%)", device->battery); + + if(!device->connected) + puts(" [disconnected]"); + else + putchar('\n'); + } + else + { + ffPrintFormat(FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs, FF_BLUETOOTH_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->address}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->type}, + {FF_FORMAT_ARG_TYPE_UINT8, &device->battery} + }); + } +} + +void ffPrintBluetooth(FFBluetoothOptions* options) +{ + FF_LIST_AUTO_DESTROY devices = ffListCreate(sizeof (FFBluetoothDevice)); + const char* error = ffDetectBluetooth(&devices); + + if(error) + { + ffPrintError(FF_BLUETOOTH_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + } + else + { + FF_LIST_AUTO_DESTROY filtered = ffListCreate(sizeof(FFBluetoothDevice*)); + + FF_LIST_FOR_EACH(FFBluetoothDevice, device, devices) + { + if(!device->connected && !options->showDisconnected) + continue; + + *(FFBluetoothDevice**)ffListAdd(&filtered) = device; + } + + if(filtered.length == 0) + { + ffPrintError(FF_BLUETOOTH_MODULE_NAME, 0, &options->moduleArgs, "No bluetooth devices found"); + } + + for(uint32_t i = 0; i < filtered.length; i++) + { + uint8_t index = (uint8_t) (filtered.length == 1 ? 0 : i + 1); + printDevice(options, *(FFBluetoothDevice**)ffListGet(&filtered, i), index); + } + } + + FF_LIST_FOR_EACH(FFBluetoothDevice, device, devices) + { + ffStrbufDestroy(&device->name); + ffStrbufDestroy(&device->type); + ffStrbufDestroy(&device->address); + } +} + +void ffInitBluetoothOptions(FFBluetoothOptions* options) +{ + options->moduleName = FF_BLUETOOTH_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + options->showDisconnected = false; +} + +bool ffParseBluetoothCommandOptions(FFBluetoothOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BLUETOOTH_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffStrEqualsIgnCase(subKey, "show-disconnected")) + { + options->showDisconnected = ffOptionParseBoolean(value); + return true; + } + + return false; +} + +void ffDestroyBluetoothOptions(FFBluetoothOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseBluetoothJsonObject(yyjson_val* module) +{ + FFBluetoothOptions __attribute__((__cleanup__(ffDestroyBluetoothOptions))) options; + ffInitBluetoothOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (ffStrEqualsIgnCase(key, "showDisconnected")) + { + options.showDisconnected = yyjson_get_bool(val); + continue; + } + + ffPrintError(FF_BLUETOOTH_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintBluetooth(&options); +} diff --git a/src/modules/bluetooth/bluetooth.h b/src/modules/bluetooth/bluetooth.h new file mode 100644 index 0000000000..1a54baf1d5 --- /dev/null +++ b/src/modules/bluetooth/bluetooth.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BLUETOOTH_MODULE_NAME "Bluetooth" + +void ffPrintBluetooth(FFBluetoothOptions* options); +void ffInitBluetoothOptions(FFBluetoothOptions* options); +bool ffParseBluetoothCommandOptions(FFBluetoothOptions* options, const char* key, const char* value); +void ffDestroyBluetoothOptions(FFBluetoothOptions* options); +void ffParseBluetoothJsonObject(yyjson_val* module); diff --git a/src/modules/bluetooth/option.h b/src/modules/bluetooth/option.h new file mode 100644 index 0000000000..b347dc4660 --- /dev/null +++ b/src/modules/bluetooth/option.h @@ -0,0 +1,13 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFBluetoothOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + bool showDisconnected; +} FFBluetoothOptions; diff --git a/src/modules/board.c b/src/modules/board.c deleted file mode 100644 index 558653892a..0000000000 --- a/src/modules/board.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/board/board.h" - -#define FF_BOARD_MODULE_NAME "Board" -#define FF_BOARD_NUM_FORMAT_ARGS 3 - -void ffPrintBoard(FFinstance* instance) -{ - FFBoardResult result; - ffDetectBoard(&result); - - if(result.error.length > 0) - { - ffPrintError(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board, "%*s", result.error.length, result.error.chars); - goto exit; - } - - if(result.boardName.length == 0) - { - ffPrintError(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board, "board_name is not set."); - goto exit; - } - - if(instance->config.board.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board.key); - puts(result.boardName.chars); - } - else - { - ffPrintFormat(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board, FF_BOARD_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVersion}, - }); - } - -exit: - ffStrbufDestroy(&result.boardName); - ffStrbufDestroy(&result.boardVendor); - ffStrbufDestroy(&result.boardVersion); - ffStrbufDestroy(&result.error); -} diff --git a/src/modules/board/board.c b/src/modules/board/board.c new file mode 100644 index 0000000000..5c92ef20d9 --- /dev/null +++ b/src/modules/board/board.c @@ -0,0 +1,96 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/board/board.h" +#include "modules/board/board.h" +#include "util/stringUtils.h" + +#define FF_BOARD_NUM_FORMAT_ARGS 3 + +void ffPrintBoard(FFBoardOptions* options) +{ + FFBoardResult result; + ffStrbufInit(&result.name); + ffStrbufInit(&result.vendor); + ffStrbufInit(&result.version); + const char* error = ffDetectBoard(&result); + + if(error) + { + ffPrintError(FF_BOARD_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + goto exit; + } + + if(result.name.length == 0) + { + ffPrintError(FF_BOARD_MODULE_NAME, 0, &options->moduleArgs, "board_name is not set."); + goto exit; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_BOARD_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufWriteTo(&result.name, stdout); + if (result.version.length) + printf(" (%s)", result.version.chars); + putchar('\n'); + } + else + { + ffPrintFormat(FF_BOARD_MODULE_NAME, 0, &options->moduleArgs, FF_BOARD_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.vendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.version}, + }); + } + +exit: + ffStrbufDestroy(&result.name); + ffStrbufDestroy(&result.vendor); + ffStrbufDestroy(&result.version); +} + +void ffInitBoardOptions(FFBoardOptions* options) +{ + options->moduleName = FF_BOARD_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseBoardCommandOptions(FFBoardOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BOARD_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyBoardOptions(FFBoardOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseBoardJsonObject(yyjson_val* module) +{ + FFBoardOptions __attribute__((__cleanup__(ffDestroyBoardOptions))) options; + ffInitBoardOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_BOARD_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintBoard(&options); +} diff --git a/src/modules/board/board.h b/src/modules/board/board.h new file mode 100644 index 0000000000..112eabbf2d --- /dev/null +++ b/src/modules/board/board.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BOARD_MODULE_NAME "Board" + +void ffPrintBoard(FFBoardOptions* options); +void ffInitBoardOptions(FFBoardOptions* options); +bool ffParseBoardCommandOptions(FFBoardOptions* options, const char* key, const char* value); +void ffDestroyBoardOptions(FFBoardOptions* options); +void ffParseBoardJsonObject(yyjson_val* module); diff --git a/src/modules/board/option.h b/src/modules/board/option.h new file mode 100644 index 0000000000..582854d236 --- /dev/null +++ b/src/modules/board/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFBoardOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFBoardOptions; diff --git a/src/modules/break.c b/src/modules/break.c deleted file mode 100644 index 45b09e5fda..0000000000 --- a/src/modules/break.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" - -void ffPrintBreak(FFinstance* instance) -{ - ffLogoPrintLine(instance); - putchar('\n'); -} diff --git a/src/modules/break/break.c b/src/modules/break/break.c new file mode 100644 index 0000000000..1dc3c8e0ae --- /dev/null +++ b/src/modules/break/break.c @@ -0,0 +1,13 @@ +#include "common/printing.h" +#include "modules/break/break.h" + +void ffPrintBreak(void) +{ + ffLogoPrintLine(); + putchar('\n'); +} + +void ffParseBreakJsonObject(FF_MAYBE_UNUSED yyjson_val* module) +{ + return ffPrintBreak(); +} diff --git a/src/modules/break/break.h b/src/modules/break/break.h new file mode 100644 index 0000000000..f87c81d3d7 --- /dev/null +++ b/src/modules/break/break.h @@ -0,0 +1,8 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BREAK_MODULE_NAME "Break" + +void ffPrintBreak(); +void ffParseBreakJsonObject(yyjson_val* module); diff --git a/src/modules/brightness.c b/src/modules/brightness.c deleted file mode 100644 index 9c1cde4996..0000000000 --- a/src/modules/brightness.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/brightness/brightness.h" - -#define FF_BRIGHTNESS_MODULE_NAME "Brightness" -#define FF_BRIGHTNESS_NUM_FORMAT_ARGS 2 - -void ffPrintBrightness(FFinstance* instance) -{ - FF_LIST_AUTO_DESTROY result; - ffListInit(&result, sizeof(FFBrightnessResult)); - const char* error = ffDetectBrightness(&result); - - if(error) - { - ffPrintError(instance, FF_BRIGHTNESS_MODULE_NAME, 0, &instance->config.brightness, "%s", error); - return; - } - - if(result.length == 0) - { - ffPrintError(instance, FF_BRIGHTNESS_MODULE_NAME, 0, &instance->config.brightness, "No result is detected."); - return; - } - - FF_STRBUF_AUTO_DESTROY key; - ffStrbufInit(&key); - - FF_LIST_FOR_EACH(FFBrightnessResult, item, result) - { - if(instance->config.brightness.key.length == 0) - { - ffStrbufAppendF(&key, "%s (%s)", FF_BRIGHTNESS_MODULE_NAME, item->name.chars); - } - else - { - ffParseFormatString(&key, &instance->config.brightness.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &item->name} - }); - } - - if(instance->config.brightness.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - printf("%.0f%%\n", item->value); - } - else - { - ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.brightness.outputFormat, FF_BRIGHTNESS_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &item->value}, - {FF_FORMAT_ARG_TYPE_FLOAT, &item->name} - }); - } - - ffStrbufClear(&key); - ffStrbufDestroy(&item->name); - } -} diff --git a/src/modules/brightness/brightness.c b/src/modules/brightness/brightness.c new file mode 100644 index 0000000000..3e5ea3663e --- /dev/null +++ b/src/modules/brightness/brightness.c @@ -0,0 +1,121 @@ +#include "common/bar.h" +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/brightness/brightness.h" +#include "modules/brightness/brightness.h" +#include "util/stringUtils.h" + +#define FF_BRIGHTNESS_NUM_FORMAT_ARGS 2 + +void ffPrintBrightness(FFBrightnessOptions* options) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFBrightnessResult)); + + const char* error = ffDetectBrightness(&result); + + if(error) + { + ffPrintError(FF_BRIGHTNESS_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(result.length == 0) + { + ffPrintError(FF_BRIGHTNESS_MODULE_NAME, 0, &options->moduleArgs, "No result is detected."); + return; + } + + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); + + FF_LIST_FOR_EACH(FFBrightnessResult, item, result) + { + if(options->moduleArgs.key.length == 0) + { + ffStrbufAppendF(&key, "%s (%s)", FF_BRIGHTNESS_MODULE_NAME, item->name.chars); + } + else + { + ffParseFormatString(&key, &options->moduleArgs.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &item->name} + }); + } + + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(key.chars, 0, NULL, &options->moduleArgs.keyColor); + + if (instance.config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffAppendPercentBar(&str, (uint8_t) (item->value + 0.5), 0, 10, 10); + } + + if(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + { + if(str.length > 0) + ffStrbufAppendC(&str, ' '); + + ffAppendPercentNum(&str, (uint8_t) (item->value + 0.5), 10, 10, str.length > 0); + } + + ffStrbufPutTo(&str, stdout); + } + else + { + ffPrintFormatString(key.chars, 0, NULL, &options->moduleArgs.keyColor, &options->moduleArgs.outputFormat, FF_BRIGHTNESS_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_FLOAT, &item->value}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->name}, + }); + } + + ffStrbufClear(&key); + ffStrbufDestroy(&item->name); + } +} + +void ffInitBrightnessOptions(FFBrightnessOptions* options) +{ + options->moduleName = FF_BRIGHTNESS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseBrightnessCommandOptions(FFBrightnessOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BRIGHTNESS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyBrightnessOptions(FFBrightnessOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseBrightnessJsonObject(yyjson_val* module) +{ + FFBrightnessOptions __attribute__((__cleanup__(ffDestroyBrightnessOptions))) options; + ffInitBrightnessOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_BRIGHTNESS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintBrightness(&options); +} diff --git a/src/modules/brightness/brightness.h b/src/modules/brightness/brightness.h new file mode 100644 index 0000000000..f9724d65c7 --- /dev/null +++ b/src/modules/brightness/brightness.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BRIGHTNESS_MODULE_NAME "Brightness" + +void ffPrintBrightness(FFBrightnessOptions* options); +void ffInitBrightnessOptions(FFBrightnessOptions* options); +bool ffParseBrightnessCommandOptions(FFBrightnessOptions* options, const char* key, const char* value); +void ffDestroyBrightnessOptions(FFBrightnessOptions* options); +void ffParseBrightnessJsonObject(yyjson_val* module); diff --git a/src/modules/brightness/option.h b/src/modules/brightness/option.h new file mode 100644 index 0000000000..803ea4792e --- /dev/null +++ b/src/modules/brightness/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFBrightnessOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFBrightnessOptions; diff --git a/src/modules/chassis.c b/src/modules/chassis.c deleted file mode 100644 index 997242d657..0000000000 --- a/src/modules/chassis.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/chassis/chassis.h" - -#define FF_CHASSIS_MODULE_NAME "Chassis" -#define FF_CHASSIS_NUM_FORMAT_ARGS 3 - -void ffPrintChassis(FFinstance* instance) -{ - FFChassisResult result; - ffDetectChassis(&result); - - if(result.error.length > 0) - { - ffPrintError(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.chassis, "%*s", result.error.length, result.error.chars); - goto exit; - } - - if(result.chassisType.length == 0) - { - ffPrintError(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.chassis, "chassis_type is not set by O.E.M."); - return; - } - - if(instance->config.chassis.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.chassis.key); - - FFstrbuf output; - ffStrbufInitCopy(&output, &result.chassisType); - - if(result.chassisVersion.length > 0) - ffStrbufAppendF(&output, " (%s)", result.chassisVersion.chars); - - ffStrbufPutTo(&output, stdout); - - ffStrbufDestroy(&output); - } - else - { - ffPrintFormat(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.chassis, FF_CHASSIS_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisType}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisVersion}, - }); - } - -exit: - ffStrbufDestroy(&result.chassisType); - ffStrbufDestroy(&result.chassisVendor); - ffStrbufDestroy(&result.chassisVersion); - ffStrbufDestroy(&result.error); -} diff --git a/src/modules/chassis/chassis.c b/src/modules/chassis/chassis.c new file mode 100644 index 0000000000..e229748c8b --- /dev/null +++ b/src/modules/chassis/chassis.c @@ -0,0 +1,97 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/chassis/chassis.h" +#include "modules/chassis/chassis.h" +#include "util/stringUtils.h" + +#define FF_CHASSIS_NUM_FORMAT_ARGS 3 + +void ffPrintChassis(FFChassisOptions* options) +{ + FFChassisResult result; + ffStrbufInit(&result.type); + ffStrbufInit(&result.vendor); + ffStrbufInit(&result.version); + + const char* error = ffDetectChassis(&result); + + if(error) + { + ffPrintError(FF_CHASSIS_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + goto exit; + } + + if(result.type.length == 0) + { + ffPrintError(FF_CHASSIS_MODULE_NAME, 0, &options->moduleArgs, "chassis_type is not set by O.E.M."); + goto exit; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_CHASSIS_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufWriteTo(&result.type, stdout); + if (result.version.length) + printf(" (%s)", result.version.chars); + putchar('\n'); + } + else + { + ffPrintFormat(FF_CHASSIS_MODULE_NAME, 0, &options->moduleArgs, FF_CHASSIS_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.type}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.vendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.version}, + }); + } + +exit: + ffStrbufDestroy(&result.type); + ffStrbufDestroy(&result.vendor); + ffStrbufDestroy(&result.version); +} + +void ffInitChassisOptions(FFChassisOptions* options) +{ + options->moduleName = FF_CHASSIS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseChassisCommandOptions(FFChassisOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_CHASSIS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyChassisOptions(FFChassisOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseChassisJsonObject(yyjson_val* module) +{ + FFChassisOptions __attribute__((__cleanup__(ffDestroyChassisOptions))) options; + ffInitChassisOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_CHASSIS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintChassis(&options); +} diff --git a/src/modules/chassis/chassis.h b/src/modules/chassis/chassis.h new file mode 100644 index 0000000000..0526608da9 --- /dev/null +++ b/src/modules/chassis/chassis.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_CHASSIS_MODULE_NAME "Chassis" + +void ffPrintChassis(FFChassisOptions* options); +void ffInitChassisOptions(FFChassisOptions* options); +bool ffParseChassisCommandOptions(FFChassisOptions* options, const char* key, const char* value); +void ffDestroyChassisOptions(FFChassisOptions* options); +void ffParseChassisJsonObject(yyjson_val* module); diff --git a/src/modules/chassis/option.h b/src/modules/chassis/option.h new file mode 100644 index 0000000000..939fd165d7 --- /dev/null +++ b/src/modules/chassis/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFChassisOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFChassisOptions; diff --git a/src/modules/colors.c b/src/modules/colors.c deleted file mode 100644 index 186a225cf2..0000000000 --- a/src/modules/colors.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "util/textModifier.h" - -void ffPrintColors(FFinstance* instance) -{ - if(instance->config.pipe) - return; - - ffLogoPrintLine(instance); - - // 4%d: Set the background color - // 3%d: Set the foreground color - for(uint8_t i = 0; i < 8; i++) - printf("\033[4%d;3%dm███", i, i); - - puts(FASTFETCH_TEXT_MODIFIER_RESET); - - ffLogoPrintLine(instance); - - // 1: Set everything to bolt. This causes normal colors on some systems to be bright. - // 4%d: Set the backgound to the not bright color - // 3%d: Set the foreground to the not bright color - // 10%d: Set the background to the bright color - // 9%d: Set the foreground to the bright color - for(uint8_t i = 0; i < 8; i++) - printf("\033[1;4%d;3%d;10%d;9%dm███", i, i, i, i); - - puts(FASTFETCH_TEXT_MODIFIER_RESET); -} diff --git a/src/modules/colors/colors.c b/src/modules/colors/colors.c new file mode 100644 index 0000000000..da559b5a34 --- /dev/null +++ b/src/modules/colors/colors.c @@ -0,0 +1,142 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "util/textModifier.h" +#include "modules/colors/colors.h" +#include "util/stringUtils.h" + +void ffPrintColors(FFColorsOptions* options) +{ + if(instance.config.pipe) + return; + + ffLogoPrintLine(); + + if(options->paddingLeft > 0) + ffPrintCharTimes(' ', options->paddingLeft); + + if (options->symbol == FF_COLORS_SYMBOL_BLOCK) + { + // 4%d: Set the background color + // 3%d: Set the foreground color + for(uint8_t i = 0; i < 8; i++) + printf("\033[4%d;3%dm███", i, i); + + puts(FASTFETCH_TEXT_MODIFIER_RESET); + + ffLogoPrintLine(); + + if(options->paddingLeft > 0) + ffPrintCharTimes(' ', options->paddingLeft); + + // 1: Set everything to bolt. This causes normal colors on some systems to be bright. + // 4%d: Set the backgound to the not bright color + // 3%d: Set the foreground to the not bright color + // 10%d: Set the background to the bright color + // 9%d: Set the foreground to the bright color + for(uint8_t i = 0; i < 8; i++) + printf("\033[1;4%d;3%d;10%d;9%dm███", i, i, i, i); + } + else + { + const char* symbol; + switch (options->symbol) + { + case FF_COLORS_SYMBOL_CIRCLE: symbol = "●"; break; + case FF_COLORS_SYMBOL_DIAMOND: symbol = "◆"; break; + case FF_COLORS_SYMBOL_TRIANGLE: symbol = "▲"; break; + case FF_COLORS_SYMBOL_SQUARE: symbol = "■"; break; + case FF_COLORS_SYMBOL_STAR: symbol = "★"; break; + default: symbol = "███"; break; + } + for (int i = 8; i >= 1; --i) + printf("\e[3%dm%s ", i, symbol); + } + + puts(FASTFETCH_TEXT_MODIFIER_RESET); +} + +void ffInitColorsOptions(FFColorsOptions* options) +{ + options->moduleName = FF_COLORS_MODULE_NAME; + options->symbol = FF_COLORS_SYMBOL_BLOCK; + options->paddingLeft = 0; +} + +bool ffParseColorsCommandOptions(FFColorsOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_COLORS_MODULE_NAME); + if (!subKey) return false; + + if (ffStrEqualsIgnCase(subKey, "symbol")) + { + options->symbol = (FFColorsSymbol) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "block", FF_COLORS_SYMBOL_BLOCK }, + { "circle", FF_COLORS_SYMBOL_CIRCLE }, + { "diamond", FF_COLORS_SYMBOL_DIAMOND }, + { "triangle", FF_COLORS_SYMBOL_TRIANGLE }, + { "square", FF_COLORS_SYMBOL_SQUARE }, + { "star", FF_COLORS_SYMBOL_STAR }, + {}, + }); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "padding-left")) + { + options->paddingLeft = ffOptionParseUInt32(key, value); + return true; + } + + return false; +} + +void ffDestroyColorsOptions(FF_MAYBE_UNUSED FFColorsOptions* options) +{ +} + +void ffParseColorsJsonObject(yyjson_val* module) +{ + FFColorsOptions __attribute__((__cleanup__(ffDestroyColorsOptions))) options; + ffInitColorsOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffStrEqualsIgnCase(key, "symbol")) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "block", FF_COLORS_SYMBOL_BLOCK }, + { "circle", FF_COLORS_SYMBOL_CIRCLE }, + { "diamond", FF_COLORS_SYMBOL_DIAMOND }, + { "triangle", FF_COLORS_SYMBOL_TRIANGLE }, + { "square", FF_COLORS_SYMBOL_SQUARE }, + { "star", FF_COLORS_SYMBOL_STAR }, + {}, + }); + if (error) + ffPrintErrorString(FF_COLORS_MODULE_NAME, 0, NULL, NULL, "Invalid %s value: %s", key, error); + else + options.symbol = (FFColorsSymbol) value; + continue; + } + + if (ffStrEqualsIgnCase(key, "paddingLeft")) + { + options.paddingLeft = (uint32_t) yyjson_get_uint(val); + continue; + } + + ffPrintErrorString(FF_COLORS_MODULE_NAME, 0, NULL, NULL, "Unknown JSON key %s", key); + } + } + + ffPrintColors(&options); +} diff --git a/src/modules/colors/colors.h b/src/modules/colors/colors.h new file mode 100644 index 0000000000..64ebe96c86 --- /dev/null +++ b/src/modules/colors/colors.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_COLORS_MODULE_NAME "Colors" + +void ffPrintColors(FFColorsOptions* options); +void ffInitColorsOptions(FFColorsOptions* options); +void ffDestroyColorsOptions(FFColorsOptions* options); +bool ffParseColorsCommandOptions(FFColorsOptions* options, const char* key, const char* value); +void ffParseColorsJsonObject(yyjson_val* module); diff --git a/src/modules/colors/option.h b/src/modules/colors/option.h new file mode 100644 index 0000000000..afcb23fb64 --- /dev/null +++ b/src/modules/colors/option.h @@ -0,0 +1,22 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFColorsSymbol +{ + FF_COLORS_SYMBOL_BLOCK, + FF_COLORS_SYMBOL_CIRCLE, + FF_COLORS_SYMBOL_DIAMOND, + FF_COLORS_SYMBOL_SQUARE, + FF_COLORS_SYMBOL_TRIANGLE, + FF_COLORS_SYMBOL_STAR, +} FFColorsSymbol; + +typedef struct FFColorsOptions +{ + const char* moduleName; + FFColorsSymbol symbol; + uint32_t paddingLeft; +} FFColorsOptions; diff --git a/src/modules/command.c b/src/modules/command.c deleted file mode 100644 index 1b767013bf..0000000000 --- a/src/modules/command.c +++ /dev/null @@ -1,67 +0,0 @@ -#include "fastfetch.h" - -#include "common/printing.h" -#include "common/processing.h" -#include "util/textModifier.h" - -#define FF_COMMAND_MODULE_NAME "Command" - -static void printError(FFinstance* instance, const char* key, const char* error) -{ - ffPrintLogoAndKey(instance, key, 0, NULL); - - if(instance->config.pipe) - fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout); - - fputs(error, stdout); - - if(!instance->config.pipe) - fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); - - putchar('\n'); -} - -void ffPrintCommand(FFinstance* instance) -{ - FF_STRBUF_AUTO_DESTROY key; - ffStrbufInit(&key); - - if(!ffListShift(&instance->config.commandKeys, &key)) - ffStrbufInitS(&key, FF_COMMAND_MODULE_NAME); - - FF_STRBUF_AUTO_DESTROY text; - ffStrbufInit(&text); - if(!ffListShift(&instance->config.commandTexts, &text)) - { - printError(instance, key.chars, "No command text left"); - return; - } - - FF_STRBUF_AUTO_DESTROY result; - ffStrbufInit(&result); - const char* error = ffProcessAppendStdOut(&result, (char* const[]){ - instance->config.commandShell.chars, - #ifdef _WIN32 - "/c", - #else - "-c", - #endif - text.chars, - NULL - }); - - if(error) - { - printError(instance, key.chars, error); - return; - } - - if(!result.length) - { - printError(instance, key.chars, "No result printed"); - return; - } - - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - puts(result.chars); -} diff --git a/src/modules/command/command.c b/src/modules/command/command.c new file mode 100644 index 0000000000..7337e7553d --- /dev/null +++ b/src/modules/command/command.c @@ -0,0 +1,117 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/processing.h" +#include "modules/command/command.h" +#include "util/stringUtils.h" + +void ffPrintCommand(FFCommandOptions* options) +{ + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate(); + const char* error = ffProcessAppendStdOut(&result, (char* const[]){ + options->shell.chars, + #ifdef _WIN32 + "/c", + #else + "-c", + #endif + options->text.chars, + NULL + }); + + if(error) + { + ffPrintError(FF_COMMAND_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(!result.length) + { + ffPrintError(FF_COMMAND_MODULE_NAME, 0, &options->moduleArgs, "No result printed"); + return; + } + + ffPrintLogoAndKey(FF_COMMAND_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufPutTo(&result, stdout); +} + +void ffInitCommandOptions(FFCommandOptions* options) +{ + options->moduleName = FF_COMMAND_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + ffStrbufInitStatic(&options->shell, + #ifdef _WIN32 + "cmd.exe" + #else + "/bin/sh" + #endif + ); + + ffStrbufInit(&options->text); +} + +bool ffParseCommandCommandOptions(FFCommandOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_COMMAND_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if(ffStrEqualsIgnCase(subKey, "shell")) + { + ffOptionParseString(key, value, &options->shell); + return true; + } + + if(ffStrEqualsIgnCase(subKey, "text")) + { + ffOptionParseString(key, value, &options->text); + return true; + } + + return false; +} + +void ffDestroyCommandOptions(FFCommandOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + ffStrbufDestroy(&options->shell); + ffStrbufDestroy(&options->text); +} + +void ffParseCommandJsonObject(yyjson_val* module) +{ + FFCommandOptions __attribute__((__cleanup__(ffDestroyCommandOptions))) options; + ffInitCommandOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (ffStrEqualsIgnCase(key, "shell")) + { + ffStrbufSetS(&options.shell, yyjson_get_str(val)); + continue; + } + + if (ffStrEqualsIgnCase(key, "text")) + { + ffStrbufSetS(&options.text, yyjson_get_str(val)); + continue; + } + + ffPrintError(FF_COMMAND_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintCommand(&options); +} diff --git a/src/modules/command/command.h b/src/modules/command/command.h new file mode 100644 index 0000000000..eca179b358 --- /dev/null +++ b/src/modules/command/command.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_COMMAND_MODULE_NAME "Command" + +void ffPrintCommand(FFCommandOptions* options); +void ffInitCommandOptions(FFCommandOptions* options); +bool ffParseCommandCommandOptions(FFCommandOptions* options, const char* key, const char* value); +void ffDestroyCommandOptions(FFCommandOptions* options); +void ffParseCommandJsonObject(yyjson_val* module); diff --git a/src/modules/command/option.h b/src/modules/command/option.h new file mode 100644 index 0000000000..41d3408a4a --- /dev/null +++ b/src/modules/command/option.h @@ -0,0 +1,14 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFCommandOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFstrbuf shell; + FFstrbuf text; +} FFCommandOptions; diff --git a/src/modules/cpu.c b/src/modules/cpu.c deleted file mode 100644 index eb38a9805a..0000000000 --- a/src/modules/cpu.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/cpu/cpu.h" - -#define FF_CPU_MODULE_NAME "CPU" -#define FF_CPU_NUM_FORMAT_ARGS 8 - -void ffPrintCPU(FFinstance* instance) -{ - const FFCPUResult* cpu = ffDetectCPU(instance); - - if(cpu->vendor.length == 0 && cpu->name.length == 0 && cpu->coresOnline <= 1) - { - ffPrintError(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu, "No CPU detected"); - return; - } - - if(instance->config.cpu.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu.key); - - if(cpu->name.length > 0) - ffStrbufWriteTo(&cpu->name, stdout); - else if(cpu->vendor.length > 0) - { - ffStrbufWriteTo(&cpu->vendor, stdout); - fputs(" CPU", stdout); - } - else - fputs("CPU", stdout); - - if(cpu->coresOnline > 1) - printf(" (%u)", cpu->coresOnline); - - if(cpu->frequencyMax > 0.0) - printf(" @ %.9g GHz", cpu->frequencyMax); - - if(cpu->temperature == cpu->temperature) //FF_CPU_TEMP_UNSET - printf(" - %.1f°C", cpu->temperature); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &cpu->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &cpu->vendor}, - {FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresPhysical}, - {FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresLogical}, - {FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresOnline}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMin}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMax}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->temperature} - }); - } -} diff --git a/src/modules/cpu/cpu.c b/src/modules/cpu/cpu.c new file mode 100644 index 0000000000..14d751685f --- /dev/null +++ b/src/modules/cpu/cpu.c @@ -0,0 +1,137 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/parsing.h" +#include "detection/cpu/cpu.h" +#include "modules/cpu/cpu.h" +#include "util/stringUtils.h" + +#define FF_CPU_NUM_FORMAT_ARGS 8 + +void ffPrintCPU(FFCPUOptions* options) +{ + FFCPUResult cpu; + cpu.temperature = FF_CPU_TEMP_UNSET; + cpu.coresPhysical = cpu.coresLogical = cpu.coresOnline = 0; + cpu.frequencyMax = cpu.frequencyMin = 0; + ffStrbufInit(&cpu.name); + ffStrbufInit(&cpu.vendor); + + const char* error = ffDetectCPU(options, &cpu); + + if(error) + { + ffPrintError(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + } + else if(cpu.vendor.length == 0 && cpu.name.length == 0 && cpu.coresOnline <= 1) + { + ffPrintError(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, "No CPU detected"); + } + else + { + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_CPU_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + + if(cpu.name.length > 0) + ffStrbufAppend(&str, &cpu.name); + else if(cpu.vendor.length > 0) + { + ffStrbufAppend(&str, &cpu.vendor); + ffStrbufAppendS(&str, " CPU"); + } + else + ffStrbufAppendS(&str, "Unknown"); + + if(cpu.coresOnline > 1) + ffStrbufAppendF(&str, " (%u)", cpu.coresOnline); + + if(cpu.frequencyMax > 0.0) + ffStrbufAppendF(&str, " @ %.9g GHz", cpu.frequencyMax); + + if(cpu.temperature == cpu.temperature) //FF_CPU_TEMP_UNSET + { + ffStrbufAppendS(&str, " - "); + ffParseTemperature(cpu.temperature, &str); + } + + ffStrbufPutTo(&str, stdout); + } + else + { + ffPrintFormat(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &cpu.name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &cpu.vendor}, + {FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresPhysical}, + {FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresLogical}, + {FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresOnline}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.frequencyMin}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.frequencyMax}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.temperature} + }); + } + } + + ffStrbufDestroy(&cpu.name); + ffStrbufDestroy(&cpu.vendor); +} + +void ffInitCPUOptions(FFCPUOptions* options) +{ + options->moduleName = FF_CPU_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + options->temp = false; +} + +bool ffParseCPUCommandOptions(FFCPUOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_CPU_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffStrEqualsIgnCase(subKey, "temp")) + { + options->temp = ffOptionParseBoolean(value); + return true; + } + + return false; +} + +void ffDestroyCPUOptions(FFCPUOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseCPUJsonObject(yyjson_val* module) +{ + FFCPUOptions __attribute__((__cleanup__(ffDestroyCPUOptions))) options; + ffInitCPUOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (ffStrEqualsIgnCase(key, "temp")) + { + options.temp = yyjson_get_bool(val); + continue; + } + + ffPrintError(FF_CPU_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintCPU(&options); +} diff --git a/src/modules/cpu/cpu.h b/src/modules/cpu/cpu.h new file mode 100644 index 0000000000..731149d5bc --- /dev/null +++ b/src/modules/cpu/cpu.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_CPU_MODULE_NAME "CPU" + +void ffPrintCPU(FFCPUOptions* options); +void ffInitCPUOptions(FFCPUOptions* options); +bool ffParseCPUCommandOptions(FFCPUOptions* options, const char* key, const char* value); +void ffDestroyCPUOptions(FFCPUOptions* options); +void ffParseCPUJsonObject(yyjson_val* module); diff --git a/src/modules/cpu/option.h b/src/modules/cpu/option.h new file mode 100644 index 0000000000..9e54bfeafc --- /dev/null +++ b/src/modules/cpu/option.h @@ -0,0 +1,13 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFCPUOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + bool temp; +} FFCPUOptions; diff --git a/src/modules/cpuUsage.c b/src/modules/cpuUsage.c deleted file mode 100644 index cb952a06a3..0000000000 --- a/src/modules/cpuUsage.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/bar.h" -#include "detection/cpuUsage/cpuUsage.h" - -#define FF_CPU_USAGE_MODULE_NAME "CPU Usage" -#define FF_CPU_USAGE_NUM_FORMAT_ARGS 1 - -void ffPrintCPUUsage(FFinstance* instance) -{ - double percentage = 0.0/0.0; - const char* error = ffGetCpuUsageResult(&percentage); - - if(error) - { - ffPrintError(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpu, "%s", error); - return; - } - - if(instance->config.cpuUsage.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpuUsage.key); - - FF_STRBUF_AUTO_DESTROY str; - ffStrbufInit(&str); - if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) - ffAppendPercentBar(instance, &str, (uint8_t)percentage, 0, 5, 8); - if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) - { - if(str.length > 0) - ffStrbufAppendC(&str, ' '); - ffAppendPercentNum(instance, &str, (uint8_t) percentage, 50, 80, str.length > 0); - } - ffStrbufPutTo(&str, stdout); - } - else - { - ffPrintFormat(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpuUsage, FF_CPU_USAGE_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_DOUBLE, &percentage} - }); - } -} diff --git a/src/modules/cpuusage/cpuusage.c b/src/modules/cpuusage/cpuusage.c new file mode 100644 index 0000000000..32f24a4628 --- /dev/null +++ b/src/modules/cpuusage/cpuusage.c @@ -0,0 +1,89 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/bar.h" +#include "detection/cpuusage/cpuusage.h" +#include "modules/cpuusage/cpuusage.h" +#include "util/stringUtils.h" + +#define FF_CPUUSAGE_DISPLAY_NAME "CPU Usage" +#define FF_CPUUSAGE_NUM_FORMAT_ARGS 1 + +void ffPrintCPUUsage(FFCPUUsageOptions* options) +{ + double percentage = 0.0/0.0; + const char* error = ffGetCpuUsageResult(&percentage); + + if(error) + { + ffPrintError(FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + if(instance.config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffAppendPercentBar(&str, (uint8_t)percentage, 0, 5, 8); + if(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + { + if(str.length > 0) + ffStrbufAppendC(&str, ' '); + ffAppendPercentNum(&str, (uint8_t) percentage, 50, 80, str.length > 0); + } + ffStrbufPutTo(&str, stdout); + } + else + { + ffPrintFormat(FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs, FF_CPUUSAGE_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_DOUBLE, &percentage} + }); + } +} + +void ffInitCPUUsageOptions(FFCPUUsageOptions* options) +{ + options->moduleName = FF_CPUUSAGE_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseCPUUsageCommandOptions(FFCPUUsageOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_CPUUSAGE_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyCPUUsageOptions(FFCPUUsageOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseCPUUsageJsonObject(yyjson_val* module) +{ + FFCPUUsageOptions __attribute__((__cleanup__(ffDestroyCPUUsageOptions))) options; + ffInitCPUUsageOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_CPUUSAGE_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintCPUUsage(&options); +} diff --git a/src/modules/cpuusage/cpuusage.h b/src/modules/cpuusage/cpuusage.h new file mode 100644 index 0000000000..e0275a5ea9 --- /dev/null +++ b/src/modules/cpuusage/cpuusage.h @@ -0,0 +1,13 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_CPUUSAGE_MODULE_NAME "CPUUsage" + +void ffPrepareCPUUsage(); + +void ffPrintCPUUsage(FFCPUUsageOptions* options); +void ffInitCPUUsageOptions(FFCPUUsageOptions* options); +bool ffParseCPUUsageCommandOptions(FFCPUUsageOptions* options, const char* key, const char* value); +void ffDestroyCPUUsageOptions(FFCPUUsageOptions* options); +void ffParseCPUUsageJsonObject(yyjson_val* module); diff --git a/src/modules/cpuusage/option.h b/src/modules/cpuusage/option.h new file mode 100644 index 0000000000..c779b6c5a5 --- /dev/null +++ b/src/modules/cpuusage/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFCPUUsageOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFCPUUsageOptions; diff --git a/src/modules/cursor.c b/src/modules/cursor.c deleted file mode 100644 index a5ddc90be8..0000000000 --- a/src/modules/cursor.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "fastfetch.h" - -#include "common/printing.h" -#include "detection/cursor/cursor.h" - -#define FF_CURSOR_MODULE_NAME "Cursor" -#define FF_CURSOR_NUM_FORMAT_ARGS 2 - -static void printCursor(FFinstance* instance, FFCursorResult* cursor) -{ - ffStrbufRemoveIgnCaseEndS(&cursor->theme, "cursors"); - ffStrbufRemoveIgnCaseEndS(&cursor->theme, "cursor"); - ffStrbufTrimRight(&cursor->theme, '_'); - ffStrbufTrimRight(&cursor->theme, '-'); - if(cursor->theme.length == 0) - ffStrbufAppendS(&cursor->theme, "default"); - - if(instance->config.cursor.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor.key); - ffStrbufWriteTo(&cursor->theme, stdout); - - if(cursor->size.length > 0) - printf(" (%spx)", cursor->size.chars); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, FF_CURSOR_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &cursor->theme}, - {FF_FORMAT_ARG_TYPE_STRBUF, &cursor->size} - }); - } -} - - -void ffPrintCursor(FFinstance* instance) -{ - FFCursorResult result; - ffStrbufInit(&result.error); - ffStrbufInit(&result.theme); - ffStrbufInit(&result.size); - - ffDetectCursor(instance, &result); - - if(result.error.length) - ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "%s", result.error.chars); - else - printCursor(instance, &result); - - ffStrbufDestroy(&result.error); - ffStrbufDestroy(&result.theme); - ffStrbufDestroy(&result.size); -} diff --git a/src/modules/cursor/cursor.c b/src/modules/cursor/cursor.c new file mode 100644 index 0000000000..06a8d3d91d --- /dev/null +++ b/src/modules/cursor/cursor.c @@ -0,0 +1,97 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/cursor/cursor.h" +#include "modules/cursor/cursor.h" +#include "util/stringUtils.h" + +#define FF_CURSOR_NUM_FORMAT_ARGS 2 + +void ffPrintCursor(FFCursorOptions* options) +{ + FFCursorResult result; + ffStrbufInit(&result.error); + ffStrbufInit(&result.theme); + ffStrbufInit(&result.size); + + ffDetectCursor(&result); + + if(result.error.length) + ffPrintError(FF_CURSOR_MODULE_NAME, 0, &options->moduleArgs, "%s", result.error.chars); + else + { + ffStrbufRemoveIgnCaseEndS(&result.theme, "cursors"); + ffStrbufRemoveIgnCaseEndS(&result.theme, "cursor"); + ffStrbufTrimRight(&result.theme, '_'); + ffStrbufTrimRight(&result.theme, '-'); + if(result.theme.length == 0) + ffStrbufAppendS(&result.theme, "default"); + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_CURSOR_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufWriteTo(&result.theme, stdout); + + if(result.size.length > 0) + printf(" (%spx)", result.size.chars); + + putchar('\n'); + } + else + { + ffPrintFormat(FF_CURSOR_MODULE_NAME, 0, &options->moduleArgs, FF_CURSOR_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result.theme}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.size} + }); + } + } + + ffStrbufDestroy(&result.error); + ffStrbufDestroy(&result.theme); + ffStrbufDestroy(&result.size); +} + +void ffInitCursorOptions(FFCursorOptions* options) +{ + options->moduleName = FF_CURSOR_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseCursorCommandOptions(FFCursorOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_CURSOR_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyCursorOptions(FFCursorOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseCursorJsonObject(yyjson_val* module) +{ + FFCursorOptions __attribute__((__cleanup__(ffDestroyCursorOptions))) options; + ffInitCursorOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_CURSOR_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintCursor(&options); +} diff --git a/src/modules/cursor/cursor.h b/src/modules/cursor/cursor.h new file mode 100644 index 0000000000..5c23741a2c --- /dev/null +++ b/src/modules/cursor/cursor.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_CURSOR_MODULE_NAME "Cursor" + +void ffPrintCursor(FFCursorOptions* options); +void ffInitCursorOptions(FFCursorOptions* options); +bool ffParseCursorCommandOptions(FFCursorOptions* options, const char* key, const char* value); +void ffDestroyCursorOptions(FFCursorOptions* options); +void ffParseCursorJsonObject(yyjson_val* module); diff --git a/src/modules/cursor/option.h b/src/modules/cursor/option.h new file mode 100644 index 0000000000..9a648c844c --- /dev/null +++ b/src/modules/cursor/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFCursorOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFCursorOptions; diff --git a/src/modules/custom.c b/src/modules/custom.c deleted file mode 100644 index f91a5b69ec..0000000000 --- a/src/modules/custom.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "util/textModifier.h" - -void ffPrintCustom(FFinstance* instance, const char* key, const char* value) -{ - ffPrintLogoAndKey(instance, key, 0, NULL); - ffPrintUserString(value); - puts(FASTFETCH_TEXT_MODIFIER_RESET); -} diff --git a/src/modules/custom/custom.c b/src/modules/custom/custom.c new file mode 100644 index 0000000000..64ab00579a --- /dev/null +++ b/src/modules/custom/custom.c @@ -0,0 +1,64 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "modules/custom/custom.h" +#include "util/textModifier.h" +#include "util/stringUtils.h" + +void ffPrintCustom(FFCustomOptions* options) +{ + if (options->moduleArgs.outputFormat.length == 0) + { + ffPrintError(FF_CUSTOM_MODULE_NAME, 0, &options->moduleArgs, "output format must be set for custom module"); + return; + } + + ffPrintLogoAndKey(options->moduleArgs.key.length == 0 ? NULL : FF_CUSTOM_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffPrintUserString(options->moduleArgs.outputFormat.chars); + puts(FASTFETCH_TEXT_MODIFIER_RESET); +} + +void ffInitCustomOptions(FFCustomOptions* options) +{ + options->moduleName = FF_CUSTOM_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseCustomCommandOptions(FFCustomOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_CUSTOM_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyCustomOptions(FFCustomOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseCustomJsonObject(yyjson_val* module) +{ + FFCustomOptions __attribute__((__cleanup__(ffDestroyCustomOptions))) options; + ffInitCustomOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_CUSTOM_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintCustom(&options); +} diff --git a/src/modules/custom/custom.h b/src/modules/custom/custom.h new file mode 100644 index 0000000000..6d1981d7c8 --- /dev/null +++ b/src/modules/custom/custom.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_CUSTOM_MODULE_NAME "Custom" + +void ffPrintCustom(FFCustomOptions* options); +void ffInitCustomOptions(FFCustomOptions* options); +bool ffParseCustomCommandOptions(FFCustomOptions* options, const char* key, const char* value); +void ffDestroyCustomOptions(FFCustomOptions* options); +void ffParseCustomJsonObject(yyjson_val* module); diff --git a/src/modules/custom/option.h b/src/modules/custom/option.h new file mode 100644 index 0000000000..f2b2388318 --- /dev/null +++ b/src/modules/custom/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFCustomOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFCustomOptions; diff --git a/src/modules/date.c b/src/modules/date.c deleted file mode 100644 index a92209ed03..0000000000 --- a/src/modules/date.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/datetime/datetime.h" - -#define FF_DATE_MODULE_NAME "Date" - -void ffPrintDate(FFinstance* instance) -{ - if(instance->config.date.outputFormat.length > 0) - { - ffPrintDateTimeFormat(instance, FF_DATE_MODULE_NAME, &instance->config.date); - return; - } - - const FFDateTimeResult* datetime = ffDetectDateTime(instance); - ffPrintLogoAndKey(instance, FF_DATE_MODULE_NAME, 0, &instance->config.date.key); - - //yyyy-mm-dd - printf("%u-%s-%u\n", datetime->year, datetime->monthPretty.chars, datetime->dayInMonth); -} diff --git a/src/modules/datetime.c b/src/modules/datetime.c deleted file mode 100644 index 968d17725b..0000000000 --- a/src/modules/datetime.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/datetime/datetime.h" - -#define FF_DATETIME_MODULE_NAME "Date & Time" -#define FF_DATETIME_NUM_FORMAT_ARGS 20 - -void ffPrintDateTimeFormat(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs) -{ - const FFDateTimeResult* result = ffDetectDateTime(instance); - ffPrintFormat(instance, moduleName, 0, moduleArgs, FF_DATETIME_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_UINT16, &result->year}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->yearShort}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->month}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthPretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthNameShort}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->week}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->weekday}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->weekdayShort}, - {FF_FORMAT_ARG_TYPE_UINT16, &result->dayInYear}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->dayInMonth}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->dayInWeek}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->hour}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->hourPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->hour12}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->hour12Pretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->minute}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->minutePretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->second}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->secondPretty} - }); -} - -void ffPrintDateTime(FFinstance* instance) -{ - if(instance->config.dateTime.outputFormat.length > 0) - { - ffPrintDateTimeFormat(instance, FF_DATETIME_MODULE_NAME, &instance->config.dateTime); - return; - } - - const FFDateTimeResult* datetime = ffDetectDateTime(instance); - ffPrintLogoAndKey(instance, FF_DATETIME_MODULE_NAME, 0, &instance->config.dateTime.key); - - //yyyy-MM-dd HH:mm:ss - printf("%u-%s-%02u %s:%s:%s\n", datetime->year, datetime->monthPretty.chars, datetime->dayInMonth, datetime->hourPretty.chars, datetime->minutePretty.chars, datetime->secondPretty.chars); -} diff --git a/src/modules/datetime/datetime.c b/src/modules/datetime/datetime.c new file mode 100644 index 0000000000..12134c178f --- /dev/null +++ b/src/modules/datetime/datetime.c @@ -0,0 +1,96 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/datetime/datetime.h" +#include "modules/datetime/datetime.h" +#include "util/stringUtils.h" + +#define FF_DATETIME_DISPLAY_NAME "Date & Time" +#define FF_DATETIME_NUM_FORMAT_ARGS 20 + +void ffPrintDateTimeFormat(const char* moduleName, const FFModuleArgs* moduleArgs) +{ + const FFDateTimeResult* result = ffDetectDateTime(); + ffPrintFormat(moduleName, 0, moduleArgs, FF_DATETIME_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_UINT16, &result->year}, // 1 + {FF_FORMAT_ARG_TYPE_UINT8, &result->yearShort}, // 2 + {FF_FORMAT_ARG_TYPE_UINT8, &result->month}, // 3 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthPretty}, // 4 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthName}, // 5 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthNameShort}, // 6 + {FF_FORMAT_ARG_TYPE_UINT8, &result->week}, // 7 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->weekday}, // 8 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->weekdayShort}, // 9 + {FF_FORMAT_ARG_TYPE_UINT16, &result->dayInYear}, // 10 + {FF_FORMAT_ARG_TYPE_UINT8, &result->dayInMonth}, // 11 + {FF_FORMAT_ARG_TYPE_UINT8, &result->dayInWeek}, // 12 + {FF_FORMAT_ARG_TYPE_UINT8, &result->hour}, // 13 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->hourPretty}, // 14 + {FF_FORMAT_ARG_TYPE_UINT8, &result->hour12}, // 15 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->hour12Pretty}, // 16 + {FF_FORMAT_ARG_TYPE_UINT8, &result->minute}, // 17 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->minutePretty}, // 18 + {FF_FORMAT_ARG_TYPE_UINT8, &result->second}, // 19 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->secondPretty} // 20 + }); +} + +void ffPrintDateTime(FFDateTimeOptions* options) +{ + if(options->moduleArgs.outputFormat.length > 0) + { + ffPrintDateTimeFormat(FF_DATETIME_DISPLAY_NAME, &options->moduleArgs); + return; + } + + const FFDateTimeResult* datetime = ffDetectDateTime(); + ffPrintLogoAndKey(FF_DATETIME_DISPLAY_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + //yyyy-MM-dd HH:mm:ss + printf("%u-%s-%02u %s:%s:%s\n", datetime->year, datetime->monthPretty.chars, datetime->dayInMonth, datetime->hourPretty.chars, datetime->minutePretty.chars, datetime->secondPretty.chars); +} + +void ffInitDateTimeOptions(FFDateTimeOptions* options) +{ + options->moduleName = FF_DATETIME_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseDateTimeCommandOptions(FFDateTimeOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_DATETIME_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyDateTimeOptions(FFDateTimeOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseDateTimeJsonObject(yyjson_val* module) +{ + FFDateTimeOptions __attribute__((__cleanup__(ffDestroyDateTimeOptions))) options; + ffInitDateTimeOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_DATETIME_DISPLAY_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintDateTime(&options); +} diff --git a/src/modules/datetime/datetime.h b/src/modules/datetime/datetime.h new file mode 100644 index 0000000000..269343711c --- /dev/null +++ b/src/modules/datetime/datetime.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_DATETIME_MODULE_NAME "DateTime" + +void ffPrintDateTime(FFDateTimeOptions* options); +void ffInitDateTimeOptions(FFDateTimeOptions* options); +bool ffParseDateTimeCommandOptions(FFDateTimeOptions* options, const char* key, const char* value); +void ffDestroyDateTimeOptions(FFDateTimeOptions* options); +void ffParseDateTimeJsonObject(yyjson_val* module); diff --git a/src/modules/datetime/option.h b/src/modules/datetime/option.h new file mode 100644 index 0000000000..1c32501e65 --- /dev/null +++ b/src/modules/datetime/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFDateTimeOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFDateTimeOptions; diff --git a/src/modules/de.c b/src/modules/de.c deleted file mode 100644 index eb2cb50627..0000000000 --- a/src/modules/de.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/displayserver/displayserver.h" - -#define FF_DE_MODULE_NAME "DE" -#define FF_DE_NUM_FORMAT_ARGS 3 - -void ffPrintDesktopEnvironment(FFinstance* instance) -{ - #ifdef __ANDROID__ - ffPrintError(instance, FF_DE_MODULE_NAME, 0, &instance->config.de, "DE detection is not supported on Android"); - return; - #endif - - const FFDisplayServerResult* result = ffConnectDisplayServer(instance); - - if(result->dePrettyName.length == 0) - { - ffPrintError(instance, FF_DE_MODULE_NAME, 0, &instance->config.de, "No DE found"); - return; - } - - if(instance->config.de.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_DE_MODULE_NAME, 0, &instance->config.de.key); - - ffStrbufWriteTo(&result->dePrettyName, stdout); - - if(result->deVersion.length > 0) - { - putchar(' '); - ffStrbufWriteTo(&result->deVersion, stdout); - } - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_DE_MODULE_NAME, 0, &instance->config.de, FF_DE_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result->deProcessName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->dePrettyName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->deVersion} - }); - } -} diff --git a/src/modules/de/de.c b/src/modules/de/de.c new file mode 100644 index 0000000000..a32e6dc01c --- /dev/null +++ b/src/modules/de/de.c @@ -0,0 +1,87 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/displayserver/displayserver.h" +#include "modules/de/de.h" +#include "util/stringUtils.h" + +#define FF_DE_NUM_FORMAT_ARGS 3 + +void ffPrintDE(FFDEOptions* options) +{ + const FFDisplayServerResult* result = ffConnectDisplayServer(); + + if(result->dePrettyName.length == 0) + { + ffPrintError(FF_DE_MODULE_NAME, 0, &options->moduleArgs, "No DE found"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_DE_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + ffStrbufWriteTo(&result->dePrettyName, stdout); + + if(result->deVersion.length > 0) + { + putchar(' '); + ffStrbufWriteTo(&result->deVersion, stdout); + } + + putchar('\n'); + } + else + { + ffPrintFormat(FF_DE_MODULE_NAME, 0, &options->moduleArgs, FF_DE_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result->deProcessName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->dePrettyName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->deVersion} + }); + } +} + +void ffInitDEOptions(FFDEOptions* options) +{ + options->moduleName = FF_DE_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseDECommandOptions(FFDEOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_DE_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyDEOptions(FFDEOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseDEJsonObject(yyjson_val* module) +{ + FFDEOptions __attribute__((__cleanup__(ffDestroyDEOptions))) options; + ffInitDEOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_DE_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintDE(&options); +} diff --git a/src/modules/de/de.h b/src/modules/de/de.h new file mode 100644 index 0000000000..2676655847 --- /dev/null +++ b/src/modules/de/de.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_DE_MODULE_NAME "DE" + +void ffPrintDE(FFDEOptions* options); +void ffInitDEOptions(FFDEOptions* options); +bool ffParseDECommandOptions(FFDEOptions* options, const char* key, const char* value); +void ffDestroyDEOptions(FFDEOptions* options); +void ffParseDEJsonObject(yyjson_val* module); diff --git a/src/modules/de/option.h b/src/modules/de/option.h new file mode 100644 index 0000000000..52b8954e72 --- /dev/null +++ b/src/modules/de/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFDEOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFDEOptions; diff --git a/src/modules/disk.c b/src/modules/disk.c deleted file mode 100644 index dd2064d735..0000000000 --- a/src/modules/disk.c +++ /dev/null @@ -1,157 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/parsing.h" -#include "common/bar.h" -#include "detection/disk/disk.h" - -#define FF_DISK_MODULE_NAME "Disk" -#define FF_DISK_NUM_FORMAT_ARGS 10 - -static void printDisk(FFinstance* instance, const FFDisk* disk) -{ - FF_STRBUF_AUTO_DESTROY key; - ffStrbufInit(&key); - - if(instance->config.disk.key.length == 0) - { - ffStrbufAppendF(&key, "%s (%s)", FF_DISK_MODULE_NAME, disk->mountpoint.chars); - } - else - { - ffParseFormatString(&key, &instance->config.disk.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &disk->mountpoint} - }); - } - - FF_STRBUF_AUTO_DESTROY usedPretty; - ffStrbufInit(&usedPretty); - ffParseSize(disk->bytesUsed, instance->config.binaryPrefixType, &usedPretty); - - FF_STRBUF_AUTO_DESTROY totalPretty; - ffStrbufInit(&totalPretty); - ffParseSize(disk->bytesTotal, instance->config.binaryPrefixType, &totalPretty); - - uint8_t bytesPercentage = disk->bytesTotal > 0 ? (uint8_t) (((long double) disk->bytesUsed / (long double) disk->bytesTotal) * 100.0) : 0; - - if(instance->config.disk.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - - FF_STRBUF_AUTO_DESTROY str; - ffStrbufInit(&str); - - if(disk->bytesTotal > 0) - { - if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) - { - ffAppendPercentBar(instance, &str, bytesPercentage, 0, 5, 8); - ffStrbufAppendC(&str, ' '); - } - - if(!(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) - ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); - - if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) - { - ffAppendPercentNum(instance, &str, (uint8_t) bytesPercentage, 50, 80, str.length > 0); - ffStrbufAppendC(&str, ' '); - } - } - else - ffStrbufAppendS(&str, "Unknown "); - - if(disk->type & FF_DISK_TYPE_EXTERNAL_BIT && !(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) - ffStrbufAppendS(&str, "[Removable]"); - - ffStrbufTrimRight(&str, ' '); - ffStrbufPutTo(&str, stdout); - } - else - { - uint8_t filesPercentage = disk->filesTotal > 0 ? (uint8_t) (((double) disk->filesUsed / (double) disk->filesTotal) * 100.0) : 0; - - ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.disk.outputFormat, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &bytesPercentage}, - {FF_FORMAT_ARG_TYPE_UINT, &disk->filesUsed}, - {FF_FORMAT_ARG_TYPE_UINT, &disk->filesTotal}, - {FF_FORMAT_ARG_TYPE_UINT8, &filesPercentage}, - {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type & FF_DISK_TYPE_EXTERNAL_BIT)}, - {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type & FF_DISK_TYPE_HIDDEN_BIT)}, - {FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem}, - {FF_FORMAT_ARG_TYPE_STRBUF, &disk->name} - }); - } -} - -static void printMountpoint(FFinstance* instance, const FFlist* disks, const char* mountpoint) -{ - for(uint32_t i = disks->length; i > 0; i--) - { - FFDisk* disk = ffListGet(disks, i - 1); - if(strncmp(mountpoint, disk->mountpoint.chars, disk->mountpoint.length) == 0) - { - printDisk(instance, disk); - return; - } - } - - ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "No disk found for mountpoint: %s", mountpoint); -} - -static void printMountpoints(FFinstance* instance, const FFlist* disks) -{ - #ifdef _WIN32 - const char separator = ';'; - #else - const char separator = ':'; - #endif - - FF_STRBUF_AUTO_DESTROY mountpoints; - ffStrbufInitCopy(&mountpoints, &instance->config.diskFolders); - ffStrbufTrim(&mountpoints, separator); - - uint32_t startIndex = 0; - while(startIndex < mountpoints.length) - { - uint32_t colonIndex = ffStrbufNextIndexC(&mountpoints, startIndex, separator); - mountpoints.chars[colonIndex] = '\0'; - - printMountpoint(instance, disks, mountpoints.chars + startIndex); - - startIndex = colonIndex + 1; - } -} - -static void printAutodetected(FFinstance* instance, const FFlist* disks) -{ - bool found = false; - - FF_LIST_FOR_EACH(FFDisk, disk, *disks) - { - if(!(disk->type & instance->config.diskShowTypes)) - continue; - - printDisk(instance, disk); - found = true; - } - - if (!found) - ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "No disk found"); -} - -void ffPrintDisk(FFinstance* instance) -{ - const FFDiskResult* disks = ffDetectDisks(); - if(disks->error.length > 0) - { - ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "%s", disks->error.chars); - return; - } - - if(instance->config.diskFolders.length == 0) - printAutodetected(instance, &disks->disks); - else - printMountpoints(instance, &disks->disks); -} diff --git a/src/modules/disk/disk.c b/src/modules/disk/disk.c new file mode 100644 index 0000000000..151596c27f --- /dev/null +++ b/src/modules/disk/disk.c @@ -0,0 +1,327 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/parsing.h" +#include "common/bar.h" +#include "detection/disk/disk.h" +#include "modules/disk/disk.h" +#include "util/stringUtils.h" + +#define FF_DISK_NUM_FORMAT_ARGS 10 +#pragma GCC diagnostic ignored "-Wsign-conversion" + +static void printDisk(FFDiskOptions* options, const FFDisk* disk) +{ + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); + + if(options->moduleArgs.key.length == 0) + { + if(instance.config.pipe) + ffStrbufAppendF(&key, "%s (%s)", FF_DISK_MODULE_NAME, disk->mountpoint.chars); + else + { + #ifdef __linux__ + if (getenv("WSL_DISTRO_NAME") != NULL && getenv("WT_SESSION") != NULL) + { + if (ffStrbufEqualS(&disk->filesystem, "9p") && ffStrbufStartsWithS(&disk->mountpoint, "/mnt/")) + ffStrbufAppendF(&key, "%s (\e]8;;file:///%c:/\e\\%s\e]8;;\e\\)", FF_DISK_MODULE_NAME, disk->mountpoint.chars[5], disk->mountpoint.chars); + else + ffStrbufAppendF(&key, "%s (\e]8;;file:////wsl.localhost/%s%s\e\\%s\e]8;;\e\\)", FF_DISK_MODULE_NAME, getenv("WSL_DISTRO_NAME"), disk->mountpoint.chars, disk->mountpoint.chars); + } + else + #endif + ffStrbufAppendF(&key, "%s (\e]8;;file://%s\e\\%s\e]8;;\e\\)", FF_DISK_MODULE_NAME, disk->mountpoint.chars, disk->mountpoint.chars); + } + } + else + { + ffParseFormatString(&key, &options->moduleArgs.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &disk->mountpoint} + }); + } + + FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate(); + ffParseSize(disk->bytesUsed, &usedPretty); + + FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate(); + ffParseSize(disk->bytesTotal, &totalPretty); + + uint8_t bytesPercentage = disk->bytesTotal > 0 ? (uint8_t) (((long double) disk->bytesUsed / (long double) disk->bytesTotal) * 100.0) : 0; + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(key.chars, 0, NULL, &options->moduleArgs.keyColor); + + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + + if(disk->bytesTotal > 0) + { + if(instance.config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffAppendPercentBar(&str, bytesPercentage, 0, 5, 8); + ffStrbufAppendC(&str, ' '); + } + + if(!(instance.config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); + + if(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + { + ffAppendPercentNum(&str, (uint8_t) bytesPercentage, 50, 80, str.length > 0); + ffStrbufAppendC(&str, ' '); + } + } + else + ffStrbufAppendS(&str, "Unknown "); + + if(!(instance.config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + { + if(disk->filesystem.length) + ffStrbufAppendF(&str, "- %s ", disk->filesystem.chars); + + if(disk->type & FF_DISK_TYPE_EXTERNAL_BIT) + ffStrbufAppendS(&str, "[External]"); + else if(disk->type & FF_DISK_TYPE_SUBVOLUME_BIT) + ffStrbufAppendS(&str, "[Subvolume]"); + else if(disk->type & FF_DISK_TYPE_HIDDEN_BIT) + ffStrbufAppendS(&str, "[Hidden]"); + } + + ffStrbufTrimRight(&str, ' '); + ffStrbufPutTo(&str, stdout); + } + else + { + uint8_t filesPercentage = disk->filesTotal > 0 ? (uint8_t) (((double) disk->filesUsed / (double) disk->filesTotal) * 100.0) : 0; + + bool isExternal = !!(disk->type & FF_DISK_TYPE_EXTERNAL_BIT); + bool isHidden = !!(disk->type & FF_DISK_TYPE_HIDDEN_BIT); + ffPrintFormatString(key.chars, 0, NULL, &options->moduleArgs.keyColor, &options->moduleArgs.outputFormat, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, + {FF_FORMAT_ARG_TYPE_UINT8, &bytesPercentage}, + {FF_FORMAT_ARG_TYPE_UINT, &disk->filesUsed}, + {FF_FORMAT_ARG_TYPE_UINT, &disk->filesTotal}, + {FF_FORMAT_ARG_TYPE_UINT8, &filesPercentage}, + {FF_FORMAT_ARG_TYPE_BOOL, &isExternal}, + {FF_FORMAT_ARG_TYPE_BOOL, &isHidden}, + {FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem}, + {FF_FORMAT_ARG_TYPE_STRBUF, &disk->name} + }); + } +} + +static void printMountpoint(FFDiskOptions* options, const FFlist* disks, const char* mountpoint) +{ + FF_LIST_FOR_EACH(FFDisk, disk, *disks) + { + if(ffStrbufEqualS(&disk->mountpoint, mountpoint)) + { + printDisk(options, disk); + return; + } + } + + ffPrintError(FF_DISK_MODULE_NAME, 0, &options->moduleArgs, "No disk found for mountpoint: %s", mountpoint); +} + +static void printMountpoints(FFDiskOptions* options, const FFlist* disks) +{ + #ifdef _WIN32 + const char separator = ';'; + #else + const char separator = ':'; + #endif + + FF_STRBUF_AUTO_DESTROY mountpoints = ffStrbufCreateCopy(&options->folders); + ffStrbufTrim(&mountpoints, separator); + + uint32_t startIndex = 0; + while(startIndex < mountpoints.length) + { + uint32_t colonIndex = ffStrbufNextIndexC(&mountpoints, startIndex, separator); + mountpoints.chars[colonIndex] = '\0'; + + printMountpoint(options, disks, mountpoints.chars + startIndex); + + startIndex = colonIndex + 1; + } +} + +static void printAutodetected(FFDiskOptions* options, const FFlist* disks) +{ + FF_LIST_FOR_EACH(FFDisk, disk, *disks) + { + if(!(disk->type & options->showTypes)) + continue; + + printDisk(options, disk); + } +} + +void ffPrintDisk(FFDiskOptions* options) +{ + FF_LIST_AUTO_DESTROY disks = ffListCreate(sizeof (FFDisk)); + const char* error = ffDetectDisks(&disks); + + if(error) + { + ffPrintError(FF_DISK_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + } + else + { + if(options->folders.length == 0) + printAutodetected(options, &disks); + else + printMountpoints(options, &disks); + } + + FF_LIST_FOR_EACH(FFDisk, disk, disks) + { + ffStrbufDestroy(&disk->mountpoint); + ffStrbufDestroy(&disk->filesystem); + ffStrbufDestroy(&disk->name); + } +} + + +void ffInitDiskOptions(FFDiskOptions* options) +{ + options->moduleName = FF_DISK_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + ffStrbufInit(&options->folders); + options->showTypes = FF_DISK_TYPE_REGULAR_BIT | FF_DISK_TYPE_EXTERNAL_BIT; +} + +bool ffParseDiskCommandOptions(FFDiskOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_DISK_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffStrEqualsIgnCase(subKey, "folders")) + { + ffOptionParseString(key, value, &options->folders); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "show-regular")) + { + if (ffOptionParseBoolean(value)) + options->showTypes |= FF_DISK_TYPE_REGULAR_BIT; + else + options->showTypes &= ~FF_DISK_TYPE_REGULAR_BIT; + return true; + } + + if (ffStrEqualsIgnCase(subKey, "show-external")) + { + if (ffOptionParseBoolean(value)) + options->showTypes |= FF_DISK_TYPE_EXTERNAL_BIT; + else + options->showTypes &= ~FF_DISK_TYPE_EXTERNAL_BIT; + return true; + } + + if (ffStrEqualsIgnCase(subKey, "show-hidden")) + { + if (ffOptionParseBoolean(value)) + options->showTypes |= FF_DISK_TYPE_HIDDEN_BIT; + else + options->showTypes &= ~FF_DISK_TYPE_HIDDEN_BIT; + return true; + } + + if (ffStrEqualsIgnCase(subKey, "show-subvolumes")) + { + if (ffOptionParseBoolean(value)) + options->showTypes |= FF_DISK_TYPE_SUBVOLUME_BIT; + else + options->showTypes &= ~FF_DISK_TYPE_SUBVOLUME_BIT; + return true; + } + + if (ffStrEqualsIgnCase(subKey, "show-unknown")) + { + if (ffOptionParseBoolean(value)) + options->showTypes |= FF_DISK_TYPE_UNKNOWN_BIT; + else + options->showTypes &= ~FF_DISK_TYPE_UNKNOWN_BIT; + return true; + } + + return false; +} + +void ffDestroyDiskOptions(FFDiskOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseDiskJsonObject(yyjson_val* module) +{ + FFDiskOptions __attribute__((__cleanup__(ffDestroyDiskOptions))) options; + ffInitDiskOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (ffStrEqualsIgnCase(key, "folders")) + { + ffStrbufSetS(&options.folders, yyjson_get_str(val)); + continue; + } + + if (ffStrEqualsIgnCase(key, "showExternal")) + { + if (yyjson_get_bool(val)) + options.showTypes |= FF_DISK_TYPE_EXTERNAL_BIT; + else + options.showTypes &= ~FF_DISK_TYPE_EXTERNAL_BIT; + continue; + } + + if (ffStrEqualsIgnCase(key, "showHidden")) + { + if (yyjson_get_bool(val)) + options.showTypes |= FF_DISK_TYPE_HIDDEN_BIT; + else + options.showTypes &= ~FF_DISK_TYPE_HIDDEN_BIT; + continue; + } + + if (ffStrEqualsIgnCase(key, "showSubvolumes")) + { + if (yyjson_get_bool(val)) + options.showTypes |= FF_DISK_TYPE_SUBVOLUME_BIT; + else + options.showTypes &= ~FF_DISK_TYPE_SUBVOLUME_BIT; + continue; + } + + if (ffStrEqualsIgnCase(key, "showUnknown")) + { + if (yyjson_get_bool(val)) + options.showTypes |= FF_DISK_TYPE_UNKNOWN_BIT; + else + options.showTypes &= ~FF_DISK_TYPE_UNKNOWN_BIT; + continue; + } + + ffPrintError(FF_DISK_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintDisk(&options); +} diff --git a/src/modules/disk/disk.h b/src/modules/disk/disk.h new file mode 100644 index 0000000000..aa508df141 --- /dev/null +++ b/src/modules/disk/disk.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_DISK_MODULE_NAME "Disk" + +void ffPrintDisk(FFDiskOptions* options); +void ffInitDiskOptions(FFDiskOptions* options); +bool ffParseDiskCommandOptions(FFDiskOptions* options, const char* key, const char* value); +void ffDestroyDiskOptions(FFDiskOptions* options); +void ffParseDiskJsonObject(yyjson_val* module); diff --git a/src/modules/disk/option.h b/src/modules/disk/option.h new file mode 100644 index 0000000000..702e5bcbf5 --- /dev/null +++ b/src/modules/disk/option.h @@ -0,0 +1,24 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFDiskType +{ + FF_DISK_TYPE_NONE = 0, + FF_DISK_TYPE_REGULAR_BIT = 1 << 0, + FF_DISK_TYPE_HIDDEN_BIT = 1 << 1, + FF_DISK_TYPE_EXTERNAL_BIT = 1 << 2, + FF_DISK_TYPE_SUBVOLUME_BIT = 1 << 3, + FF_DISK_TYPE_UNKNOWN_BIT = 1 << 4, +} FFDiskType; + +typedef struct FFDiskOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFstrbuf folders; + FFDiskType showTypes; +} FFDiskOptions; diff --git a/src/modules/display.c b/src/modules/display.c deleted file mode 100644 index f4dddbe1fc..0000000000 --- a/src/modules/display.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/displayserver/displayserver.h" - -#define FF_DISPLAY_MODULE_NAME "Display" -#define FF_DISPLAY_NUM_FORMAT_ARGS 7 - -void ffPrintDisplay(FFinstance* instance) -{ - #ifdef __ANDROID__ - ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display, "Display detection is not supported on Android"); - return; - #endif - - const FFDisplayServerResult* dsResult = ffConnectDisplayServer(instance); - - if (instance->config.displayCompactType != FF_DISPLAY_COMPACT_TYPE_NONE) - { - ffPrintLogoAndKey(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display.key); - - int index = 0; - FF_LIST_FOR_EACH(FFDisplayResult, result, dsResult->displays) - { - if (instance->config.displayCompactType & FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT) - { - if (index++) putchar(' '); - printf("%ix%i", result->width, result->height); - } - if (instance->config.displayCompactType & FF_DISPLAY_COMPACT_TYPE_SCALED_BIT) - { - if (index++) putchar(' '); - printf("%ix%i", result->scaledWidth, result->scaledHeight); - } - ffStrbufDestroy(&result->name); - } - putchar('\n'); - return; - } - - FF_STRBUF_AUTO_DESTROY key; - ffStrbufInit(&key); - - for(uint32_t i = 0; i < dsResult->displays.length; i++) - { - FFDisplayResult* result = ffListGet(&dsResult->displays, i); - uint8_t moduleIndex = dsResult->displays.length == 1 ? 0 : (uint8_t) (i + 1); - const char* displayType = result->type == FF_DISPLAY_TYPE_UNKNOWN ? NULL : result->type == FF_DISPLAY_TYPE_BUILTIN ? "built-in" : "external"; - - if(instance->config.display.outputFormat.length == 0) - { - if(result->name.length || (moduleIndex > 0 && displayType)) - { - ffStrbufClear(&key); - if(instance->config.display.key.length == 0) - { - ffStrbufAppendF(&key, "%s (%s)", FF_DISPLAY_MODULE_NAME, result->name.length ? result->name.chars : displayType); - } - else - { - ffParseFormatString(&key, &instance->config.display.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_UINT, &i}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, - {FF_FORMAT_ARG_TYPE_STRING, displayType}, - }); - } - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - } - else - { - ffPrintLogoAndKey(instance, FF_DISPLAY_MODULE_NAME, moduleIndex, &instance->config.display.key); - } - - printf("%ix%i", result->width, result->height); - - if(result->refreshRate > 0) - { - if(instance->config.displayPreciseRefreshRate) - printf(" @ %gHz", ((int) (result->refreshRate * 1000 + 0.5)) / 1000.0); - else - printf(" @ %iHz", (uint32_t) (result->refreshRate + 0.5)); - } - - if( - result->scaledWidth > 0 && result->scaledWidth != result->width && - result->scaledHeight > 0 && result->scaledHeight != result->height) - printf(" (as %ix%i)", result->scaledWidth, result->scaledHeight); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_DISPLAY_MODULE_NAME, moduleIndex, &instance->config.display, FF_DISPLAY_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_UINT, &result->width}, - {FF_FORMAT_ARG_TYPE_UINT, &result->height}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &result->refreshRate}, - {FF_FORMAT_ARG_TYPE_UINT, &result->scaledWidth}, - {FF_FORMAT_ARG_TYPE_UINT, &result->scaledHeight}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, - {FF_FORMAT_ARG_TYPE_STRING, displayType}, - }); - } - - ffStrbufDestroy(&result->name); - } - - if(dsResult->displays.length == 0) - ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display, "Couldn't detect display"); -} diff --git a/src/modules/display/display.c b/src/modules/display/display.c new file mode 100644 index 0000000000..848936f619 --- /dev/null +++ b/src/modules/display/display.c @@ -0,0 +1,194 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/displayserver/displayserver.h" +#include "modules/display/display.h" +#include "util/stringUtils.h" + +#define FF_DISPLAY_NUM_FORMAT_ARGS 8 + +void ffPrintDisplay(FFDisplayOptions* options) +{ + const FFDisplayServerResult* dsResult = ffConnectDisplayServer(); + + if(dsResult->displays.length == 0) + { + ffPrintError(FF_DISPLAY_MODULE_NAME, 0, &instance.config.display.moduleArgs, "Couldn't detect display"); + return; + } + + if (options->compactType != FF_DISPLAY_COMPACT_TYPE_NONE) + { + ffPrintLogoAndKey(FF_DISPLAY_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + int index = 0; + FF_LIST_FOR_EACH(FFDisplayResult, result, dsResult->displays) + { + if (options->compactType & FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT) + { + if (index++) putchar(' '); + printf("%ix%i", result->width, result->height); + } + if (options->compactType & FF_DISPLAY_COMPACT_TYPE_SCALED_BIT) + { + if (index++) putchar(' '); + printf("%ix%i", result->scaledWidth, result->scaledHeight); + } + } + putchar('\n'); + return; + } + + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); + + for(uint32_t i = 0; i < dsResult->displays.length; i++) + { + FFDisplayResult* result = ffListGet(&dsResult->displays, i); + uint8_t moduleIndex = dsResult->displays.length == 1 ? 0 : (uint8_t) (i + 1); + const char* displayType = result->type == FF_DISPLAY_TYPE_UNKNOWN ? NULL : result->type == FF_DISPLAY_TYPE_BUILTIN ? "built-in" : "external"; + + if(options->moduleArgs.outputFormat.length == 0) + { + ffStrbufClear(&key); + if(options->moduleArgs.key.length == 0) + { + const char* subkey = result->name.length ? result->name.chars : displayType; + if (subkey) + ffStrbufAppendF(&key, "%s (%s)", FF_DISPLAY_MODULE_NAME, subkey); + else if (moduleIndex > 0) + ffStrbufAppendF(&key, "%s (%d)", FF_DISPLAY_MODULE_NAME, moduleIndex); + else + ffStrbufAppendS(&key, FF_DISPLAY_MODULE_NAME); + } + else + { + ffParseFormatString(&key, &options->moduleArgs.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT, &i}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, + {FF_FORMAT_ARG_TYPE_STRING, displayType}, + }); + } + ffPrintLogoAndKey(key.chars, 0, NULL, &options->moduleArgs.keyColor); + + printf("%ix%i", result->width, result->height); + + if(result->refreshRate > 0) + { + if(options->preciseRefreshRate) + printf(" @ %gHz", ((int) (result->refreshRate * 1000 + 0.5)) / 1000.0); + else + printf(" @ %iHz", (uint32_t) (result->refreshRate + 0.5)); + } + + if( + result->scaledWidth > 0 && result->scaledWidth != result->width && + result->scaledHeight > 0 && result->scaledHeight != result->height) + printf(" (as %ix%i)", result->scaledWidth, result->scaledHeight); + + if(moduleIndex > 0 && result->primary) + printf(" *"); + + putchar('\n'); + } + else + { + ffPrintFormat(FF_DISPLAY_MODULE_NAME, moduleIndex, &options->moduleArgs, FF_DISPLAY_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_UINT, &result->width}, + {FF_FORMAT_ARG_TYPE_UINT, &result->height}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &result->refreshRate}, + {FF_FORMAT_ARG_TYPE_UINT, &result->scaledWidth}, + {FF_FORMAT_ARG_TYPE_UINT, &result->scaledHeight}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, + {FF_FORMAT_ARG_TYPE_STRING, displayType}, + {FF_FORMAT_ARG_TYPE_UINT, &result->rotation}, + {FF_FORMAT_ARG_TYPE_BOOL, &result->primary}, + }); + } + } +} + +void ffInitDisplayOptions(FFDisplayOptions* options) +{ + options->moduleName = FF_DISPLAY_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + options->compactType = FF_DISPLAY_COMPACT_TYPE_NONE; + options->preciseRefreshRate = false; +} + +bool ffParseDisplayCommandOptions(FFDisplayOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_DISPLAY_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffStrEqualsIgnCase(subKey, "compact-type")) + { + options->compactType = (FFDisplayCompactType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "none", FF_DISPLAY_COMPACT_TYPE_NONE }, + { "original", FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT }, + { "scaled", FF_DISPLAY_COMPACT_TYPE_SCALED_BIT }, + {}, + }); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "precise-refresh-rate")) + { + options->preciseRefreshRate = ffOptionParseBoolean(value); + return true; + } + + return false; +} + +void ffDestroyDisplayOptions(FFDisplayOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseDisplayJsonObject(yyjson_val* module) +{ + FFDisplayOptions __attribute__((__cleanup__(ffDestroyDisplayOptions))) options; + ffInitDisplayOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (ffStrEqualsIgnCase(key, "compactType")) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "none", FF_DISPLAY_COMPACT_TYPE_NONE }, + { "original", FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT }, + { "scaled", FF_DISPLAY_COMPACT_TYPE_SCALED_BIT }, + {}, + }); + if (error) + ffPrintError(FF_DISPLAY_MODULE_NAME, 0, &options.moduleArgs, "Invalid %s value: %s", key, error); + else + options.compactType = (FFDisplayCompactType) value; + continue; + } + + if (ffStrEqualsIgnCase(key, "preciseRefreshRate")) + { + options.preciseRefreshRate = yyjson_get_bool(val); + continue; + } + + ffPrintError(FF_DISPLAY_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintDisplay(&options); +} diff --git a/src/modules/display/display.h b/src/modules/display/display.h new file mode 100644 index 0000000000..66196f0638 --- /dev/null +++ b/src/modules/display/display.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_DISPLAY_MODULE_NAME "Display" + +void ffPrintDisplay(FFDisplayOptions* options); +void ffInitDisplayOptions(FFDisplayOptions* options); +bool ffParseDisplayCommandOptions(FFDisplayOptions* options, const char* key, const char* value); +void ffDestroyDisplayOptions(FFDisplayOptions* options); +void ffParseDisplayJsonObject(yyjson_val* module); diff --git a/src/modules/display/option.h b/src/modules/display/option.h new file mode 100644 index 0000000000..20def688c4 --- /dev/null +++ b/src/modules/display/option.h @@ -0,0 +1,21 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFDisplayCompactType +{ + FF_DISPLAY_COMPACT_TYPE_NONE = 0, + FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT = 1 << 0, + FF_DISPLAY_COMPACT_TYPE_SCALED_BIT = 1 << 1, +} FFDisplayCompactType; + +typedef struct FFDisplayOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFDisplayCompactType compactType; + bool preciseRefreshRate; +} FFDisplayOptions; diff --git a/src/modules/font.c b/src/modules/font.c deleted file mode 100644 index c33d144fef..0000000000 --- a/src/modules/font.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/font/font.h" -#include "detection/displayserver/displayserver.h" - -#define FF_FONT_MODULE_NAME "Font" -#define FF_FONT_NUM_FORMAT_ARGS (FF_DETECT_FONT_NUM_FONTS + 1) - -void ffPrintFont(FFinstance* instance) -{ - const FFFontResult* font = ffDetectFont(instance); - - if(font->error.length > 0) - { - ffPrintError(instance, FF_FONT_MODULE_NAME, 0, &instance->config.font, "%s", font->error.chars); - return; - } - - if(instance->config.font.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_FONT_MODULE_NAME, 0, &instance->config.font.key); - ffStrbufPutTo(&font->display, stdout); - } - else - { - ffPrintFormat(instance, FF_FONT_MODULE_NAME, 0, &instance->config.font, FF_FONT_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[0]}, - {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[1]}, - {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[2]}, - {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[3]}, - {FF_FORMAT_ARG_TYPE_STRBUF, &font->display}, - }); - } -} diff --git a/src/modules/font/font.c b/src/modules/font/font.c new file mode 100644 index 0000000000..9a8195cd00 --- /dev/null +++ b/src/modules/font/font.c @@ -0,0 +1,90 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/font/font.h" +#include "modules/font/font.h" +#include "util/stringUtils.h" + +#define FF_FONT_NUM_FORMAT_ARGS (FF_DETECT_FONT_NUM_FONTS + 1) + +void ffPrintFont(FFFontOptions* options) +{ + FFFontResult font; + for(uint32_t i = 0; i < FF_DETECT_FONT_NUM_FONTS; ++i) + ffStrbufInit(&font.fonts[i]); + ffStrbufInit(&font.display); + + const char* error = ffDetectFont(&font); + + if(error) + { + ffPrintError(FF_FONT_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + } + else + { + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_FONT_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufPutTo(&font.display, stdout); + } + else + { + ffPrintFormat(FF_FONT_MODULE_NAME, 0, &options->moduleArgs, FF_FONT_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &font.fonts[0]}, + {FF_FORMAT_ARG_TYPE_STRBUF, &font.fonts[1]}, + {FF_FORMAT_ARG_TYPE_STRBUF, &font.fonts[2]}, + {FF_FORMAT_ARG_TYPE_STRBUF, &font.fonts[3]}, + {FF_FORMAT_ARG_TYPE_STRBUF, &font.display}, + }); + } + } + + ffStrbufDestroy(&font.display); + for (uint32_t i = 0; i < FF_DETECT_FONT_NUM_FONTS; ++i) + ffStrbufDestroy(&font.fonts[i]); +} + +void ffInitFontOptions(FFFontOptions* options) +{ + options->moduleName = FF_FONT_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseFontCommandOptions(FFFontOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_FONT_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyFontOptions(FFFontOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseFontJsonObject(yyjson_val* module) +{ + FFFontOptions __attribute__((__cleanup__(ffDestroyFontOptions))) options; + ffInitFontOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_FONT_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintFont(&options); +} diff --git a/src/modules/font/font.h b/src/modules/font/font.h new file mode 100644 index 0000000000..a4e46f65ac --- /dev/null +++ b/src/modules/font/font.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_FONT_MODULE_NAME "Font" + +void ffPrintFont(FFFontOptions* options); +void ffInitFontOptions(FFFontOptions* options); +bool ffParseFontCommandOptions(FFFontOptions* options, const char* key, const char* value); +void ffDestroyFontOptions(FFFontOptions* options); +void ffParseFontJsonObject(yyjson_val* module); diff --git a/src/modules/font/option.h b/src/modules/font/option.h new file mode 100644 index 0000000000..9318bac4b6 --- /dev/null +++ b/src/modules/font/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFFontOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFFontOptions; diff --git a/src/modules/gamepad.c b/src/modules/gamepad.c deleted file mode 100644 index 6bcb332f8b..0000000000 --- a/src/modules/gamepad.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "common/printing.h" -#include "detection/gamepad/gamepad.h" - -#define FF_GAMEPAD_MODULE_NAME "Gamepad" -#define FF_GAMEPAD_NUM_FORMAT_ARGS 2 - -static void printDevice(FFinstance* instance, const FFGamepadDevice* device, uint8_t index) -{ - if(instance->config.gamepad.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_GAMEPAD_MODULE_NAME, index, &instance->config.gamepad.key); - ffStrbufPutTo(&device->name, stdout); - } - else - { - ffPrintFormat(instance, FF_GAMEPAD_MODULE_NAME, index, &instance->config.gamepad, FF_GAMEPAD_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->identifier}, - }); - } -} - -void ffPrintGamepad(FFinstance* instance) -{ - FF_LIST_AUTO_DESTROY result; - ffListInit(&result, sizeof(FFGamepadDevice)); - const char* error = ffDetectGamepad(instance, &result); - - if(error) - { - ffPrintError(instance, FF_GAMEPAD_MODULE_NAME, 0, &instance->config.gamepad, "%s", error); - return; - } - - if(!result.length) - { - ffPrintError(instance, FF_GAMEPAD_MODULE_NAME, 0, &instance->config.gamepad, "No devices detected"); - return; - } - - uint8_t index = 0; - FF_LIST_FOR_EACH(FFGamepadDevice, device, result) - { - printDevice(instance, device, result.length > 1 ? ++index : 0); - ffStrbufDestroy(&device->identifier); - ffStrbufDestroy(&device->name); - } -} diff --git a/src/modules/gamepad/gamepad.c b/src/modules/gamepad/gamepad.c new file mode 100644 index 0000000000..e5f28704cc --- /dev/null +++ b/src/modules/gamepad/gamepad.c @@ -0,0 +1,96 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/gamepad/gamepad.h" +#include "modules/gamepad/gamepad.h" +#include "util/stringUtils.h" + +#define FF_GAMEPAD_NUM_FORMAT_ARGS 2 + +static void printDevice(FFGamepadOptions* options, const FFGamepadDevice* device, uint8_t index) +{ + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_GAMEPAD_MODULE_NAME, index, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufPutTo(&device->name, stdout); + } + else + { + ffPrintFormat(FF_GAMEPAD_MODULE_NAME, index, &options->moduleArgs, FF_GAMEPAD_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->identifier}, + }); + } +} + +void ffPrintGamepad(FFGamepadOptions* options) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFGamepadDevice)); + + const char* error = ffDetectGamepad(&result); + + if(error) + { + ffPrintError(FF_GAMEPAD_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(!result.length) + { + ffPrintError(FF_GAMEPAD_MODULE_NAME, 0, &options->moduleArgs, "No devices detected"); + return; + } + + uint8_t index = 0; + FF_LIST_FOR_EACH(FFGamepadDevice, device, result) + { + printDevice(options, device, result.length > 1 ? ++index : 0); + ffStrbufDestroy(&device->identifier); + ffStrbufDestroy(&device->name); + } +} + +void ffInitGamepadOptions(FFGamepadOptions* options) +{ + options->moduleName = FF_GAMEPAD_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseGamepadCommandOptions(FFGamepadOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_GAMEPAD_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyGamepadOptions(FFGamepadOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseGamepadJsonObject(yyjson_val* module) +{ + FFGamepadOptions __attribute__((__cleanup__(ffDestroyGamepadOptions))) options; + ffInitGamepadOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_GAMEPAD_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintGamepad(&options); +} diff --git a/src/modules/gamepad/gamepad.h b/src/modules/gamepad/gamepad.h new file mode 100644 index 0000000000..df81768d78 --- /dev/null +++ b/src/modules/gamepad/gamepad.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_GAMEPAD_MODULE_NAME "Gamepad" + +void ffPrintGamepad(FFGamepadOptions* options); +void ffInitGamepadOptions(FFGamepadOptions* options); +bool ffParseGamepadCommandOptions(FFGamepadOptions* options, const char* key, const char* value); +void ffDestroyGamepadOptions(FFGamepadOptions* options); +void ffParseGamepadJsonObject(yyjson_val* module); diff --git a/src/modules/gamepad/option.h b/src/modules/gamepad/option.h new file mode 100644 index 0000000000..6cca7f2fdc --- /dev/null +++ b/src/modules/gamepad/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFGamepadOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFGamepadOptions; diff --git a/src/modules/gpu.c b/src/modules/gpu.c deleted file mode 100644 index 0033d33beb..0000000000 --- a/src/modules/gpu.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "fastfetch.h" -#include "common/bar.h" -#include "common/parsing.h" -#include "common/printing.h" -#include "detection/host/host.h" -#include "detection/gpu/gpu.h" - -#include - -#define FF_GPU_MODULE_NAME "GPU" -#define FF_GPU_NUM_FORMAT_ARGS 6 - -static void printGPUResult(FFinstance* instance, uint8_t index, const FFGPUResult* gpu) -{ - if(instance->config.gpu.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu.key); - - FF_STRBUF_AUTO_DESTROY output; - ffStrbufInitA(&output, gpu->vendor.length + 1 + gpu->name.length); - - if(gpu->vendor.length > 0 && !ffStrbufStartsWith(&gpu->name, &gpu->vendor)) - { - ffStrbufAppend(&output, &gpu->vendor); - ffStrbufAppendC(&output, ' '); - } - - ffStrbufAppend(&output, &gpu->name); - - if(gpu->coreCount != FF_GPU_CORE_COUNT_UNSET) - ffStrbufAppendF(&output, " (%d)", gpu->coreCount); - - if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET - ffStrbufAppendF(&output, " - %.1f°C", gpu->temperature); - - if(gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET && gpu->dedicated.total != 0) - { - ffStrbufAppendS(&output, " ("); - - if(gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET) - { - ffParseSize(gpu->dedicated.used, instance->config.binaryPrefixType, &output); - ffStrbufAppendS(&output, " / "); - } - ffParseSize(gpu->dedicated.total, instance->config.binaryPrefixType, &output); - if(gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET) - { - ffStrbufAppendS(&output, ", "); - ffAppendPercentNum(instance, &output, (uint8_t) (gpu->dedicated.used * 100 / gpu->dedicated.total), 50, 80, false); - } - ffStrbufAppendC(&output, ')'); - } - - ffStrbufPutTo(&output, stdout); - } - else - { - const char* type; - if(gpu->type == FF_GPU_TYPE_INTEGRATED) - type = "Integrated"; - else if(gpu->type == FF_GPU_TYPE_DISCRETE) - type = "Discrete"; - else - type = "Unknown"; - - ffPrintFormat(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->driver}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &gpu->temperature}, - {FF_FORMAT_ARG_TYPE_INT, &gpu->coreCount}, - {FF_FORMAT_ARG_TYPE_STRING, type}, - }); - } -} - -void ffPrintGPU(FFinstance* instance) -{ - const FFlist* gpus = ffDetectGPU(instance); - - FFlist selectedGpus; - ffListInitA(&selectedGpus, sizeof(const FFGPUResult*), gpus->length); - - for(uint32_t i = 0; i < gpus->length; i++) - { - const FFGPUResult* gpu = ffListGet(gpus, i); - - if(gpu->type == FF_GPU_TYPE_INTEGRATED && instance->config.gpuHideIntegrated) - continue; - - if(gpu->type == FF_GPU_TYPE_DISCRETE && instance->config.gpuHideDiscrete) - continue; - - * (const FFGPUResult**) ffListAdd(&selectedGpus) = gpu; - } - - for(uint32_t i = 0; i < selectedGpus.length; i++) - printGPUResult(instance, selectedGpus.length == 1 ? 0 : (uint8_t) (i + 1), * (const FFGPUResult**) ffListGet(&selectedGpus, i)); - - if(selectedGpus.length == 0) - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpu, "No GPUs found"); - - ffListDestroy(&selectedGpus); -} diff --git a/src/modules/gpu/gpu.c b/src/modules/gpu/gpu.c new file mode 100644 index 0000000000..84a379f29a --- /dev/null +++ b/src/modules/gpu/gpu.c @@ -0,0 +1,220 @@ +#include "common/bar.h" +#include "common/parsing.h" +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/parsing.h" +#include "detection/host/host.h" +#include "detection/gpu/gpu.h" +#include "modules/gpu/gpu.h" +#include "util/stringUtils.h" + +#include + +#define FF_GPU_NUM_FORMAT_ARGS 6 + +static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResult* gpu) +{ + const char* type; + switch (gpu->type) + { + case FF_GPU_TYPE_INTEGRATED: type = "Integrated"; break; + case FF_GPU_TYPE_DISCRETE: type = "Discrete"; break; + default: type = "Unknown"; break; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_GPU_MODULE_NAME, index, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + FF_STRBUF_AUTO_DESTROY output = ffStrbufCreateA(gpu->vendor.length + 1 + gpu->name.length); + + if(gpu->vendor.length > 0 && !ffStrbufStartsWith(&gpu->name, &gpu->vendor)) + { + ffStrbufAppend(&output, &gpu->vendor); + ffStrbufAppendC(&output, ' '); + } + + ffStrbufAppend(&output, &gpu->name); + + if(gpu->coreCount != FF_GPU_CORE_COUNT_UNSET) + ffStrbufAppendF(&output, " (%d)", gpu->coreCount); + + if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET + { + ffStrbufAppendS(&output, " - "); + ffParseTemperature(gpu->temperature, &output); + } + + if(gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET && gpu->dedicated.total != 0) + { + ffStrbufAppendS(&output, " ("); + + if(gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET) + { + ffParseSize(gpu->dedicated.used, &output); + ffStrbufAppendS(&output, " / "); + } + ffParseSize(gpu->dedicated.total, &output); + if(gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET) + { + ffStrbufAppendS(&output, ", "); + ffAppendPercentNum(&output, (uint8_t) (gpu->dedicated.used * 100 / gpu->dedicated.total), 50, 80, false); + } + ffStrbufAppendC(&output, ')'); + } + + if (gpu->type != FF_GPU_TYPE_UNKNOWN) + ffStrbufAppendF(&output, " [%s]", type); + + ffStrbufPutTo(&output, stdout); + } + else + { + ffPrintFormat(FF_GPU_MODULE_NAME, index, &options->moduleArgs, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->driver}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &gpu->temperature}, + {FF_FORMAT_ARG_TYPE_INT, &gpu->coreCount}, + {FF_FORMAT_ARG_TYPE_STRING, type}, + }); + } +} + +void ffPrintGPU(FFGPUOptions* options) +{ + FF_LIST_AUTO_DESTROY gpus = ffListCreate(sizeof (FFGPUResult)); + const char* error = ffDetectGPU(options, &gpus); + if (error) + { + ffPrintError(FF_GPU_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + FF_LIST_AUTO_DESTROY selectedGPUs; + ffListInitA(&selectedGPUs, sizeof(const FFGPUResult*), gpus.length); + + FF_LIST_FOR_EACH(FFGPUResult, gpu, gpus) + { + if(gpu->type == FF_GPU_TYPE_INTEGRATED && options->hideType == FF_GPU_TYPE_INTEGRATED) + continue; + + if(gpu->type == FF_GPU_TYPE_DISCRETE && options->hideType == FF_GPU_TYPE_DISCRETE) + continue; + + * (const FFGPUResult**) ffListAdd(&selectedGPUs) = gpu; + } + + for(uint32_t i = 0; i < selectedGPUs.length; i++) + printGPUResult(options, selectedGPUs.length == 1 ? 0 : (uint8_t) (i + 1), * (const FFGPUResult**) ffListGet(&selectedGPUs, i)); + + if(selectedGPUs.length == 0) + ffPrintError(FF_GPU_MODULE_NAME, 0, &options->moduleArgs, "No GPUs found"); + + FF_LIST_FOR_EACH(FFGPUResult, gpu, gpus) + { + ffStrbufDestroy(&gpu->vendor); + ffStrbufDestroy(&gpu->name); + ffStrbufDestroy(&gpu->driver); + } +} + +void ffInitGPUOptions(FFGPUOptions* options) +{ + options->moduleName = FF_GPU_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + options->forceVulkan = false; + options->temp = false; + options->hideType = FF_GPU_TYPE_UNKNOWN; +} + +bool ffParseGPUCommandOptions(FFGPUOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_GPU_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffStrEqualsIgnCase(subKey, "force-vulkan")) + { + options->forceVulkan = ffOptionParseBoolean(value); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "temp")) + { + options->temp = ffOptionParseBoolean(value); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "hide-type")) + { + options->hideType = (FFGPUType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "none", FF_GPU_TYPE_UNKNOWN }, + { "intergrated", FF_GPU_TYPE_INTEGRATED }, + { "discrete", FF_GPU_TYPE_DISCRETE }, + {}, + }); + } + + return false; +} + +void ffDestroyGPUOptions(FFGPUOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseGPUJsonObject(yyjson_val* module) +{ + FFGPUOptions __attribute__((__cleanup__(ffDestroyGPUOptions))) options; + ffInitGPUOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (ffStrEqualsIgnCase(key, "temp")) + { + options.temp = yyjson_get_bool(val); + continue; + } + + if (ffStrEqualsIgnCase(key, "forceVulkan")) + { + options.forceVulkan = yyjson_get_bool(val); + continue; + } + + if (ffStrEqualsIgnCase(key, "hideType")) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "none", FF_GPU_TYPE_UNKNOWN }, + { "intergrated", FF_GPU_TYPE_INTEGRATED }, + { "discrete", FF_GPU_TYPE_DISCRETE }, + {}, + }); + if (error) + ffPrintError(FF_GPU_MODULE_NAME, 0, &options.moduleArgs, "Invalid %s value: %s", key, error); + else + options.hideType = (FFGPUType) value; + continue; + } + + ffPrintError(FF_GPU_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintGPU(&options); +} diff --git a/src/modules/gpu/gpu.h b/src/modules/gpu/gpu.h new file mode 100644 index 0000000000..9462e5fa07 --- /dev/null +++ b/src/modules/gpu/gpu.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_GPU_MODULE_NAME "GPU" + +void ffPrintGPU(FFGPUOptions* options); +void ffInitGPUOptions(FFGPUOptions* options); +bool ffParseGPUCommandOptions(FFGPUOptions* options, const char* key, const char* value); +void ffDestroyGPUOptions(FFGPUOptions* options); +void ffParseGPUJsonObject(yyjson_val* module); diff --git a/src/modules/gpu/option.h b/src/modules/gpu/option.h new file mode 100644 index 0000000000..0aaa6a6f7d --- /dev/null +++ b/src/modules/gpu/option.h @@ -0,0 +1,22 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFGPUType +{ + FF_GPU_TYPE_UNKNOWN, + FF_GPU_TYPE_INTEGRATED, + FF_GPU_TYPE_DISCRETE, +} FFGPUType; + +typedef struct FFGPUOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFGPUType hideType; + bool temp; + bool forceVulkan; +} FFGPUOptions; diff --git a/src/modules/host.c b/src/modules/host.c deleted file mode 100644 index 9fa3bafeed..0000000000 --- a/src/modules/host.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/host/host.h" - -#define FF_HOST_MODULE_NAME "Host" -#define FF_HOST_NUM_FORMAT_ARGS 5 - -void ffPrintHost(FFinstance* instance) -{ - const FFHostResult* host = ffDetectHost(); - - if(host->error.length > 0) - { - ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host, "%*s", host->error.length, host->error.chars); - return; - } - - if(host->productFamily.length == 0 && host->productName.length == 0) - { - ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host, "neither product_family nor product_name is set by O.E.M."); - return; - } - - if(instance->config.host.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host.key); - - FFstrbuf output; - ffStrbufInit(&output); - - if(host->productName.length > 0) - ffStrbufAppend(&output, &host->productName); - else - ffStrbufAppend(&output, &host->productFamily); - - if(host->productVersion.length > 0 && !ffStrbufIgnCaseEqualS(&host->productVersion, "none")) - { - ffStrbufAppendF(&output, " (%s)", host->productVersion.chars); - } - - ffStrbufPutTo(&output, stdout); - - ffStrbufDestroy(&output); - } - else - { - ffPrintFormat(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host, FF_HOST_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productFamily}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productSku}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->sysVendor} - }); - } -} diff --git a/src/modules/host/host.c b/src/modules/host/host.c new file mode 100644 index 0000000000..53526f9ee8 --- /dev/null +++ b/src/modules/host/host.c @@ -0,0 +1,112 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/host/host.h" +#include "modules/host/host.h" +#include "util/stringUtils.h" + +#define FF_HOST_NUM_FORMAT_ARGS 5 + +void ffPrintHost(FFHostOptions* options) +{ + FFHostResult host; + ffStrbufInit(&host.productFamily); + ffStrbufInit(&host.productName); + ffStrbufInit(&host.productVersion); + ffStrbufInit(&host.productSku); + ffStrbufInit(&host.sysVendor); + const char* error = ffDetectHost(&host); + + if(error) + { + ffPrintError(FF_HOST_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + goto exit; + } + + if(host.productFamily.length == 0 && host.productName.length == 0) + { + ffPrintError(FF_HOST_MODULE_NAME, 0, &options->moduleArgs, "neither product_family nor product_name is set by O.E.M."); + goto exit; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_HOST_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + FF_STRBUF_AUTO_DESTROY output = ffStrbufCreate(); + + if(host.productName.length > 0) + ffStrbufAppend(&output, &host.productName); + else + ffStrbufAppend(&output, &host.productFamily); + + if(host.productVersion.length > 0 && !ffStrbufIgnCaseEqualS(&host.productVersion, "none")) + { + ffStrbufAppendF(&output, " (%s)", host.productVersion.chars); + } + + ffStrbufPutTo(&output, stdout); + } + else + { + ffPrintFormat(FF_HOST_MODULE_NAME, 0, &options->moduleArgs, FF_HOST_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &host.productFamily}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host.productName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host.productVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host.productSku}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host.sysVendor} + }); + } + +exit: + ffStrbufDestroy(&host.productFamily); + ffStrbufDestroy(&host.productName); + ffStrbufDestroy(&host.productVersion); + ffStrbufDestroy(&host.productSku); + ffStrbufDestroy(&host.sysVendor); +} + +void ffInitHostOptions(FFHostOptions* options) +{ + options->moduleName = FF_HOST_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseHostCommandOptions(FFHostOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_HOST_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyHostOptions(FFHostOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseHostJsonObject(yyjson_val* module) +{ + FFHostOptions __attribute__((__cleanup__(ffDestroyHostOptions))) options; + ffInitHostOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_HOST_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintHost(&options); +} diff --git a/src/modules/host/host.h b/src/modules/host/host.h new file mode 100644 index 0000000000..9c9368a27e --- /dev/null +++ b/src/modules/host/host.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_HOST_MODULE_NAME "Host" + +void ffPrintHost(FFHostOptions* options); +void ffInitHostOptions(FFHostOptions* options); +bool ffParseHostCommandOptions(FFHostOptions* options, const char* key, const char* value); +void ffDestroyHostOptions(FFHostOptions* options); +void ffParseHostJsonObject(yyjson_val* module); diff --git a/src/modules/host/option.h b/src/modules/host/option.h new file mode 100644 index 0000000000..59073e934e --- /dev/null +++ b/src/modules/host/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFHostOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFHostOptions; diff --git a/src/modules/icons.c b/src/modules/icons.c deleted file mode 100644 index d6851b9732..0000000000 --- a/src/modules/icons.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/icons/icons.h" - -#define FF_ICONS_MODULE_NAME "Icons" -#define FF_ICONS_NUM_FORMAT_ARGS 1 - -void ffPrintIcons(FFinstance* instance) -{ - FF_STRBUF_AUTO_DESTROY icons; - ffStrbufInit(&icons); - const char* error = ffDetectIcons(instance, &icons); - - if(error) - { - ffPrintError(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.icons, "%s", error); - return; - } - - if(instance->config.icons.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.icons.key); - ffStrbufPutTo(&icons, stdout); - } - else - { - ffPrintFormat(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.icons, FF_ICONS_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &icons} - }); - } -} diff --git a/src/modules/icons/icons.c b/src/modules/icons/icons.c new file mode 100644 index 0000000000..e1defe320a --- /dev/null +++ b/src/modules/icons/icons.c @@ -0,0 +1,77 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/icons/icons.h" +#include "modules/icons/icons.h" +#include "util/stringUtils.h" + +#define FF_ICONS_NUM_FORMAT_ARGS 1 + +void ffPrintIcons(FFIconsOptions* options) +{ + FF_STRBUF_AUTO_DESTROY icons = ffStrbufCreate(); + const char* error = ffDetectIcons(&icons); + + if(error) + { + ffPrintError(FF_ICONS_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_ICONS_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufPutTo(&icons, stdout); + } + else + { + ffPrintFormat(FF_ICONS_MODULE_NAME, 0, &options->moduleArgs, FF_ICONS_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &icons} + }); + } +} + +void ffInitIconsOptions(FFIconsOptions* options) +{ + options->moduleName = FF_ICONS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseIconsCommandOptions(FFIconsOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_ICONS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyIconsOptions(FFIconsOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseIconsJsonObject(yyjson_val* module) +{ + FFIconsOptions __attribute__((__cleanup__(ffDestroyIconsOptions))) options; + ffInitIconsOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_ICONS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintIcons(&options); +} diff --git a/src/modules/icons/icons.h b/src/modules/icons/icons.h new file mode 100644 index 0000000000..3d4bd7e0d4 --- /dev/null +++ b/src/modules/icons/icons.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_ICONS_MODULE_NAME "Icons" + +void ffPrintIcons(FFIconsOptions* options); +void ffInitIconsOptions(FFIconsOptions* options); +bool ffParseIconsCommandOptions(FFIconsOptions* options, const char* key, const char* value); +void ffDestroyIconsOptions(FFIconsOptions* options); +void ffParseIconsJsonObject(yyjson_val* module); diff --git a/src/modules/icons/option.h b/src/modules/icons/option.h new file mode 100644 index 0000000000..fc6427aa41 --- /dev/null +++ b/src/modules/icons/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFIconsOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFIconsOptions; diff --git a/src/modules/kernel.c b/src/modules/kernel.c deleted file mode 100644 index bc11398338..0000000000 --- a/src/modules/kernel.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" - -#define FF_KERNEL_MODULE_NAME "Kernel" -#define FF_KERNEL_NUM_FORMAT_ARGS 4 - -void ffPrintKernel(FFinstance* instance) -{ - if(instance->config.kernel.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel.key); - ffStrbufWriteTo(&instance->state.platform.systemRelease, stdout); - - #ifdef _WIN32 - if(instance->state.platform.systemVersion.length > 0) - printf(" (%s)", instance->state.platform.systemVersion.chars); - #endif - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel, FF_KERNEL_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemRelease}, - {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemArchitecture} - }); - } -} diff --git a/src/modules/kernel/kernel.c b/src/modules/kernel/kernel.c new file mode 100644 index 0000000000..8cef1ae069 --- /dev/null +++ b/src/modules/kernel/kernel.c @@ -0,0 +1,77 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "modules/kernel/kernel.h" +#include "util/stringUtils.h" + +#define FF_KERNEL_NUM_FORMAT_ARGS 4 + +void ffPrintKernel(FFKernelOptions* options) +{ + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_KERNEL_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufWriteTo(&instance.state.platform.systemRelease, stdout); + + #ifdef _WIN32 + if(instance.state.platform.systemVersion.length > 0) + printf(" (%s)", instance.state.platform.systemVersion.chars); + #endif + + putchar('\n'); + } + else + { + ffPrintFormat(FF_KERNEL_MODULE_NAME, 0, &options->moduleArgs, FF_KERNEL_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemRelease}, + {FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemArchitecture} + }); + } +} + +void ffInitKernelOptions(FFKernelOptions* options) +{ + options->moduleName = FF_KERNEL_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseKernelCommandOptions(FFKernelOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_KERNEL_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyKernelOptions(FFKernelOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseKernelJsonObject(yyjson_val* module) +{ + FFKernelOptions __attribute__((__cleanup__(ffDestroyKernelOptions))) options; + ffInitKernelOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_KERNEL_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintKernel(&options); +} diff --git a/src/modules/kernel/kernel.h b/src/modules/kernel/kernel.h new file mode 100644 index 0000000000..906a89c11c --- /dev/null +++ b/src/modules/kernel/kernel.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_KERNEL_MODULE_NAME "Kernel" + +void ffPrintKernel(FFKernelOptions* options); +void ffInitKernelOptions(FFKernelOptions* options); +bool ffParseKernelCommandOptions(FFKernelOptions* options, const char* key, const char* value); +void ffDestroyKernelOptions(FFKernelOptions* options); +void ffParseKernelJsonObject(yyjson_val* module); diff --git a/src/modules/kernel/option.h b/src/modules/kernel/option.h new file mode 100644 index 0000000000..434c3069de --- /dev/null +++ b/src/modules/kernel/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFKernelOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFKernelOptions; diff --git a/src/modules/lm/lm.c b/src/modules/lm/lm.c new file mode 100644 index 0000000000..adaf7d0949 --- /dev/null +++ b/src/modules/lm/lm.c @@ -0,0 +1,96 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/lm/lm.h" +#include "modules/lm/lm.h" +#include "util/stringUtils.h" + +#define FF_LM_NUM_FORMAT_ARGS 3 + +void ffPrintLM(FFLMOptions* options) +{ + FFLMResult result; + ffStrbufInit(&result.service); + ffStrbufInit(&result.type); + ffStrbufInit(&result.version); + const char* error = ffDetectLM(&result); + + if(error) + { + ffPrintError(FF_LM_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(result.service.length == 0) + { + ffPrintError(FF_LM_MODULE_NAME, 0, &options->moduleArgs, "No LM service found"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_LM_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufWriteTo(&result.service, stdout); + if(result.version.length) + printf(" %s", result.version.chars); + if(result.type.length) + printf(" (%s)", result.type.chars); + putchar('\n'); + } + else + { + ffPrintFormat(FF_LM_MODULE_NAME, 0, &options->moduleArgs, FF_LM_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result.service}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.type}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.version}, + }); + } + ffStrbufDestroy(&result.service); + ffStrbufDestroy(&result.type); + ffStrbufDestroy(&result.version); +} + +void ffInitLMOptions(FFLMOptions* options) +{ + options->moduleName = FF_LM_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseLMCommandOptions(FFLMOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_LM_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyLMOptions(FFLMOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseLMJsonObject(yyjson_val* module) +{ + FFLMOptions __attribute__((__cleanup__(ffDestroyLMOptions))) options; + ffInitLMOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_LM_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintLM(&options); +} diff --git a/src/modules/lm/lm.h b/src/modules/lm/lm.h new file mode 100644 index 0000000000..788405bed9 --- /dev/null +++ b/src/modules/lm/lm.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_LM_MODULE_NAME "LM" + +void ffPrintLM(FFLMOptions* options); +void ffInitLMOptions(FFLMOptions* options); +bool ffParseLMCommandOptions(FFLMOptions* options, const char* key, const char* value); +void ffDestroyLMOptions(FFLMOptions* options); +void ffParseLMJsonObject(yyjson_val* module); diff --git a/src/modules/lm/option.h b/src/modules/lm/option.h new file mode 100644 index 0000000000..2a788186cb --- /dev/null +++ b/src/modules/lm/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFLMOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFLMOptions; diff --git a/src/modules/locale.c b/src/modules/locale.c deleted file mode 100644 index 8c56b06387..0000000000 --- a/src/modules/locale.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/locale/locale.h" - -#define FF_LOCALE_MODULE_NAME "Locale" -#define FF_LOCALE_NUM_FORMAT_ARGS 1 - -void ffPrintLocale(FFinstance* instance) -{ - FFstrbuf locale; - ffStrbufInit(&locale); - - ffDetectLocale(&locale); - if(locale.length == 0) - { - ffPrintError(instance, FF_LOCALE_MODULE_NAME, 0, &instance->config.locale, "No locale found"); - return; - } - - if(instance->config.locale.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_LOCALE_MODULE_NAME, 0, &instance->config.locale.key); - ffStrbufPutTo(&locale, stdout); - } - else - { - ffPrintFormat(instance, FF_LOCALE_MODULE_NAME, 0, &instance->config.locale, FF_LOCALE_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &locale} - }); - } - - ffStrbufDestroy(&locale); -} diff --git a/src/modules/locale/locale.c b/src/modules/locale/locale.c new file mode 100644 index 0000000000..46b4377a46 --- /dev/null +++ b/src/modules/locale/locale.c @@ -0,0 +1,77 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/locale/locale.h" +#include "modules/locale/locale.h" +#include "util/stringUtils.h" + +#define FF_LOCALE_NUM_FORMAT_ARGS 1 + +void ffPrintLocale(FFLocaleOptions* options) +{ + FF_STRBUF_AUTO_DESTROY locale = ffStrbufCreate(); + + ffDetectLocale(&locale); + if(locale.length == 0) + { + ffPrintError(FF_LOCALE_MODULE_NAME, 0, &options->moduleArgs, "No locale found"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_LOCALE_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufPutTo(&locale, stdout); + } + else + { + ffPrintFormat(FF_LOCALE_MODULE_NAME, 0, &options->moduleArgs, FF_LOCALE_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &locale} + }); + } +} + +void ffInitLocaleOptions(FFLocaleOptions* options) +{ + options->moduleName = FF_LOCALE_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseLocaleCommandOptions(FFLocaleOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_LOCALE_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyLocaleOptions(FFLocaleOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseLocaleJsonObject(yyjson_val* module) +{ + FFLocaleOptions __attribute__((__cleanup__(ffDestroyLocaleOptions))) options; + ffInitLocaleOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_LOCALE_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintLocale(&options); +} diff --git a/src/modules/locale/locale.h b/src/modules/locale/locale.h new file mode 100644 index 0000000000..91e4968785 --- /dev/null +++ b/src/modules/locale/locale.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_LOCALE_MODULE_NAME "Locale" + +void ffPrintLocale(FFLocaleOptions* options); +void ffInitLocaleOptions(FFLocaleOptions* options); +bool ffParseLocaleCommandOptions(FFLocaleOptions* options, const char* key, const char* value); +void ffDestroyLocaleOptions(FFLocaleOptions* options); +void ffParseLocaleJsonObject(yyjson_val* module); diff --git a/src/modules/locale/option.h b/src/modules/locale/option.h new file mode 100644 index 0000000000..3e32530372 --- /dev/null +++ b/src/modules/locale/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFLocaleOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFLocaleOptions; diff --git a/src/modules/localip.c b/src/modules/localip.c deleted file mode 100644 index 5d6de0bad9..0000000000 --- a/src/modules/localip.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/localip/localip.h" - -#define FF_LOCALIP_MODULE_NAME "Local IP" -#define FF_LOCALIP_NUM_FORMAT_ARGS 2 - -static int sortIps(const FFLocalIpResult* left, const FFLocalIpResult* right) -{ - return ffStrbufComp(&left->name, &right->name); -} - -static void formatKey(const FFinstance* instance, const FFLocalIpResult* ip, FFstrbuf* key) -{ - if(instance->config.localIP.key.length == 0) - { - if(ip->name.length) - ffStrbufSetF(key, FF_LOCALIP_MODULE_NAME " (%*s)", ip->name.length, ip->name.chars); - else - ffStrbufSetS(key, FF_LOCALIP_MODULE_NAME); - } - else - { - ffStrbufClear(key); - ffParseFormatString(key, &instance->config.localIP.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &ip->name} - }); - } -} - -static void printIp(FFLocalIpResult* ip) -{ - bool flag = false; - if (ip->ipv4.length) - { - ffStrbufWriteTo(&ip->ipv4, stdout); - flag = true; - } - if (ip->ipv6.length) - { - if (flag) putchar(' '); - ffStrbufWriteTo(&ip->ipv6, stdout); - flag = true; - } - if (ip->mac.length) - { - if (flag) - printf(" (%s)", ip->mac.chars); - else - ffStrbufWriteTo(&ip->mac, stdout); - } -} - -void ffPrintLocalIp(FFinstance* instance) -{ - FF_LIST_AUTO_DESTROY results; - ffListInit(&results, sizeof(FFLocalIpResult)); - - const char* error = ffDetectLocalIps(instance, &results); - - if(error) - { - ffPrintError(instance, FF_LOCALIP_MODULE_NAME, 0, &instance->config.localIP, "%s", error); - return; - } - - if(results.length == 0) - { - ffPrintError(instance, FF_LOCALIP_MODULE_NAME, 0, &instance->config.localIP, "Failed to detect any IPs"); - return; - } - - ffListSort(&results, (void*) sortIps); - - if (instance->config.localIpShowType & FF_LOCALIP_TYPE_COMPACT_BIT) - { - ffPrintLogoAndKey(instance, FF_LOCALIP_MODULE_NAME, 0, &instance->config.localIP.key); - - FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) - { - if ((void*) ip != (void*) results.data) - fputs(" - ", stdout); - printIp(ip); - } - } - else - { - FF_STRBUF_AUTO_DESTROY key; - ffStrbufInit(&key); - - FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) - { - formatKey(instance, ip, &key); - if(instance->config.localIP.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - printIp(ip); - putchar('\n'); - } - else - { - ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.localIP.outputFormat, FF_LOCALIP_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &ip->ipv4}, - {FF_FORMAT_ARG_TYPE_STRBUF, &ip->ipv6}, - {FF_FORMAT_ARG_TYPE_STRBUF, &ip->mac}, - {FF_FORMAT_ARG_TYPE_STRBUF, &ip->name}, - }); - } - } - } - - FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) - { - ffStrbufDestroy(&ip->name); - ffStrbufDestroy(&ip->ipv4); - ffStrbufDestroy(&ip->ipv6); - ffStrbufDestroy(&ip->mac); - } -} diff --git a/src/modules/localip/localip.c b/src/modules/localip/localip.c new file mode 100644 index 0000000000..d3aeb3cba3 --- /dev/null +++ b/src/modules/localip/localip.c @@ -0,0 +1,299 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/localip/localip.h" +#include "modules/localip/localip.h" +#include "util/stringUtils.h" + +#define FF_LOCALIP_DISPLAY_NAME "Local IP" +#define FF_LOCALIP_NUM_FORMAT_ARGS 2 +#pragma GCC diagnostic ignored "-Wsign-conversion" + +static int sortIps(const FFLocalIpResult* left, const FFLocalIpResult* right) +{ + return ffStrbufComp(&left->name, &right->name); +} + +static void formatKey(const FFLocalIpOptions* options, const FFLocalIpResult* ip, FFstrbuf* key) +{ + if(options->moduleArgs.key.length == 0) + { + if(ip->name.length) + ffStrbufSetF(key, FF_LOCALIP_DISPLAY_NAME " (%s)", ip->name.chars); + else + ffStrbufSetS(key, FF_LOCALIP_DISPLAY_NAME); + } + else + { + ffStrbufClear(key); + ffParseFormatString(key, &options->moduleArgs.key, 2, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->name}, + }); + } +} + +static void printIp(FFLocalIpResult* ip, bool markDefaultRoute) +{ + bool flag = false; + if (ip->ipv4.length) + { + ffStrbufWriteTo(&ip->ipv4, stdout); + flag = true; + } + if (ip->ipv6.length) + { + if (flag) putchar(' '); + ffStrbufWriteTo(&ip->ipv6, stdout); + flag = true; + } + if (ip->mac.length) + { + if (flag) + printf(" (%s)", ip->mac.chars); + else + ffStrbufWriteTo(&ip->mac, stdout); + } + if (markDefaultRoute && flag && ip->defaultRoute) + fputs(" *", stdout); +} + +void ffPrintLocalIp(FFLocalIpOptions* options) +{ + FF_LIST_AUTO_DESTROY results = ffListCreate(sizeof(FFLocalIpResult)); + + const char* error = ffDetectLocalIps(options, &results); + + if(error) + { + ffPrintError(FF_LOCALIP_DISPLAY_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(results.length == 0) + { + ffPrintError(FF_LOCALIP_DISPLAY_NAME, 0, &options->moduleArgs, "Failed to detect any IPs"); + return; + } + + ffListSort(&results, (const void*) sortIps); + + if (options->showType & FF_LOCALIP_TYPE_COMPACT_BIT) + { + ffPrintLogoAndKey(FF_LOCALIP_DISPLAY_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + bool flag = false; + + FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) + { + if (options->defaultRouteOnly && !ip->defaultRoute) + continue; + + if (flag) + fputs(" - ", stdout); + else + flag = true; + printIp(ip, false); + } + putchar('\n'); + } + else + { + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); + + FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) + { + if (options->defaultRouteOnly && !ip->defaultRoute) + continue; + + formatKey(options, ip, &key); + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(key.chars, 0, NULL, &options->moduleArgs.keyColor); + printIp(ip, !options->defaultRouteOnly); + putchar('\n'); + } + else + { + ffPrintFormatString(key.chars, 0, NULL, &options->moduleArgs.keyColor, &options->moduleArgs.outputFormat, FF_LOCALIP_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->ipv4}, + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->ipv6}, + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->mac}, + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->name}, + {FF_FORMAT_ARG_TYPE_BOOL, &ip->defaultRoute}, + }); + } + } + } + + FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) + { + ffStrbufDestroy(&ip->name); + ffStrbufDestroy(&ip->ipv4); + ffStrbufDestroy(&ip->ipv6); + ffStrbufDestroy(&ip->mac); + } +} + +void ffInitLocalIpOptions(FFLocalIpOptions* options) +{ + options->moduleName = FF_LOCALIP_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + options->showType = FF_LOCALIP_TYPE_IPV4_BIT; + ffStrbufInit(&options->namePrefix); + options->defaultRouteOnly = false; +} + +bool ffParseLocalIpCommandOptions(FFLocalIpOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_LOCALIP_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffStrEqualsIgnCase(subKey, "show-ipv4")) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_IPV4_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_IPV4_BIT; + return true; + } + + if (ffStrEqualsIgnCase(subKey, "show-ipv6")) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_IPV6_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_IPV6_BIT; + return true; + } + + if (ffStrEqualsIgnCase(subKey, "show-mac")) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_MAC_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_MAC_BIT; + return true; + } + + if (ffStrEqualsIgnCase(subKey, "show-loop")) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_LOOP_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_LOOP_BIT; + return true; + } + + if(ffStrEqualsIgnCase(subKey, "compact")) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_COMPACT_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_COMPACT_BIT; + return true; + } + + if (ffStrEqualsIgnCase(subKey, "name-prefix")) + { + ffOptionParseString(key, value, &options->namePrefix); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "default-route-only")) + { + options->defaultRouteOnly = ffOptionParseBoolean(value); + return true; + } + + return false; +} + +void ffDestroyLocalIpOptions(FFLocalIpOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + ffStrbufDestroy(&options->namePrefix); +} + +void ffParseLocalIpJsonObject(yyjson_val* module) +{ + FFLocalIpOptions __attribute__((__cleanup__(ffDestroyLocalIpOptions))) options; + ffInitLocalIpOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (ffStrEqualsIgnCase(key, "showIpv4")) + { + if (yyjson_get_bool(val)) + options.showType |= FF_LOCALIP_TYPE_IPV4_BIT; + else + options.showType &= ~FF_LOCALIP_TYPE_IPV4_BIT; + continue; + } + + if (ffStrEqualsIgnCase(key, "showIpv6")) + { + if (yyjson_get_bool(val)) + options.showType |= FF_LOCALIP_TYPE_IPV6_BIT; + else + options.showType &= ~FF_LOCALIP_TYPE_IPV6_BIT; + continue; + } + + if (ffStrEqualsIgnCase(key, "showMac")) + { + if (yyjson_get_bool(val)) + options.showType |= FF_LOCALIP_TYPE_MAC_BIT; + else + options.showType &= ~FF_LOCALIP_TYPE_MAC_BIT; + continue; + } + + if (ffStrEqualsIgnCase(key, "showLoop")) + { + if (yyjson_get_bool(val)) + options.showType |= FF_LOCALIP_TYPE_LOOP_BIT; + else + options.showType &= ~FF_LOCALIP_TYPE_LOOP_BIT; + continue; + } + + if (ffStrEqualsIgnCase(key, "compact")) + { + if (yyjson_get_bool(val)) + options.showType |= FF_LOCALIP_TYPE_COMPACT_BIT; + else + options.showType &= ~FF_LOCALIP_TYPE_COMPACT_BIT; + continue; + } + + if (ffStrEqualsIgnCase(key, "namePrefix")) + { + ffStrbufSetS(&options.namePrefix, yyjson_get_str(val)); + continue; + } + + if (ffStrEqualsIgnCase(key, "defaultRouteOnly")) + { + options.defaultRouteOnly = yyjson_get_bool(val); + continue; + } + + ffPrintError(FF_LOCALIP_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintLocalIp(&options); +} diff --git a/src/modules/localip/localip.h b/src/modules/localip/localip.h new file mode 100644 index 0000000000..8d1270c23d --- /dev/null +++ b/src/modules/localip/localip.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_LOCALIP_MODULE_NAME "LocalIp" + +void ffPrintLocalIp(FFLocalIpOptions* options); +void ffInitLocalIpOptions(FFLocalIpOptions* options); +bool ffParseLocalIpCommandOptions(FFLocalIpOptions* options, const char* key, const char* value); +void ffDestroyLocalIpOptions(FFLocalIpOptions* options); +void ffParseLocalIpJsonObject(yyjson_val* module); diff --git a/src/modules/localip/option.h b/src/modules/localip/option.h new file mode 100644 index 0000000000..8d58b82358 --- /dev/null +++ b/src/modules/localip/option.h @@ -0,0 +1,26 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFLocalIpType +{ + FF_LOCALIP_TYPE_NONE, + FF_LOCALIP_TYPE_LOOP_BIT = 1 << 0, + FF_LOCALIP_TYPE_IPV4_BIT = 1 << 1, + FF_LOCALIP_TYPE_IPV6_BIT = 1 << 2, + FF_LOCALIP_TYPE_MAC_BIT = 1 << 3, + + FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10, +} FFLocalIpType; + +typedef struct FFLocalIpOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFLocalIpType showType; + FFstrbuf namePrefix; + bool defaultRouteOnly; +} FFLocalIpOptions; diff --git a/src/modules/media.c b/src/modules/media/media.c similarity index 53% rename from src/modules/media.c rename to src/modules/media/media.c index eb0eaeeb27..f28852e8c1 100644 --- a/src/modules/media.c +++ b/src/modules/media/media.c @@ -1,13 +1,14 @@ -#include "fastfetch.h" #include "common/printing.h" +#include "common/jsonconfig.h" #include "detection/media/media.h" +#include "modules/media/media.h" +#include "util/stringUtils.h" #include -#define FF_MEDIA_MODULE_NAME "Media" #define FF_MEDIA_NUM_FORMAT_ARGS 5 -static bool shouldIgoreChar(char c) +static inline bool shouldIgnoreChar(char c) { return isblank(c) || c == '-' || c == '.'; } @@ -19,10 +20,10 @@ static bool artistInSongTitle(const FFstrbuf* song, const FFstrbuf* artist) while(true) { - while(shouldIgoreChar(song->chars[songIndex])) + while(shouldIgnoreChar(song->chars[songIndex])) ++songIndex; - while(shouldIgoreChar(artist->chars[artistIndex])) + while(shouldIgnoreChar(artist->chars[artistIndex])) ++artistIndex; if(artist->chars[artistIndex] == '\0') @@ -42,18 +43,17 @@ static bool artistInSongTitle(const FFstrbuf* song, const FFstrbuf* artist) return false; } -void ffPrintMedia(FFinstance* instance) +void ffPrintMedia(FFMediaOptions* options) { - const FFMediaResult* media = ffDetectMedia(instance); + const FFMediaResult* media = ffDetectMedia(); if(media->error.length > 0) { - ffPrintError(instance, FF_MEDIA_MODULE_NAME, 0, &instance->config.media, "%s", media->error.chars); + ffPrintError(FF_MEDIA_MODULE_NAME, 0, &options->moduleArgs, "%s", media->error.chars); return; } - FFstrbuf songPretty; - ffStrbufInitCopy(&songPretty, &media->song); + FF_STRBUF_AUTO_DESTROY songPretty = ffStrbufCreateCopy(&media->song); const char* removeStrings[] = { "(Official Music Video)", "(Official Video)", "(Music Video)", "(Official HD Video)", "[Official Music Video]", "[Official Video]", "[Music Video]", "[Official HD Video]", @@ -63,17 +63,16 @@ void ffPrintMedia(FFinstance* instance) "[Lyric Video]", "[Official Lyric Video]", "[Lyrics]", "| Lyric Video", "| Official Lyric Video", "| Lyrics", }; - ffStrbufRemoveStringsA(&songPretty, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings); + ffStrbufRemoveStrings(&songPretty, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings); ffStrbufTrimRight(&songPretty, ' '); if(songPretty.length == 0) ffStrbufAppend(&songPretty, &media->song); - if(instance->config.media.outputFormat.length == 0) + if(options->moduleArgs.outputFormat.length == 0) { //We don't expose artistPretty to the format, as it might be empty (when the think that the artist is already in the song title) - FFstrbuf artistPretty; - ffStrbufInitCopy(&artistPretty, &media->artist); + FF_STRBUF_AUTO_DESTROY artistPretty = ffStrbufCreateCopy(&media->artist); ffStrbufRemoveIgnCaseEndS(&artistPretty, " - Topic"); ffStrbufRemoveIgnCaseEndS(&artistPretty, "VEVO"); ffStrbufTrimRight(&artistPretty, ' '); @@ -81,7 +80,7 @@ void ffPrintMedia(FFinstance* instance) if(artistInSongTitle(&songPretty, &artistPretty)) ffStrbufClear(&artistPretty); - ffPrintLogoAndKey(instance, FF_MEDIA_MODULE_NAME, 0, &instance->config.media.key); + ffPrintLogoAndKey(FF_MEDIA_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); if(artistPretty.length > 0) { @@ -93,12 +92,10 @@ void ffPrintMedia(FFinstance* instance) ffStrbufAppendF(&songPretty, " (%s)", media->status.chars); ffStrbufPutTo(&songPretty, stdout); - - ffStrbufDestroy(&artistPretty); } else { - ffPrintFormat(instance, FF_MEDIA_MODULE_NAME, 0, &instance->config.media, FF_MEDIA_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintFormat(FF_MEDIA_MODULE_NAME, 0, &options->moduleArgs, FF_MEDIA_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &songPretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &media->song}, {FF_FORMAT_ARG_TYPE_STRBUF, &media->artist}, @@ -106,6 +103,50 @@ void ffPrintMedia(FFinstance* instance) {FF_FORMAT_ARG_TYPE_STRBUF, &media->status} }); } +} + +void ffInitMediaOptions(FFMediaOptions* options) +{ + options->moduleName = FF_MEDIA_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseMediaCommandOptions(FFMediaOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_MEDIA_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyMediaOptions(FFMediaOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseMediaJsonObject(yyjson_val* module) +{ + FFMediaOptions __attribute__((__cleanup__(ffDestroyMediaOptions))) options; + ffInitMediaOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_MEDIA_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } - ffStrbufDestroy(&songPretty); + ffPrintMedia(&options); } diff --git a/src/modules/media/media.h b/src/modules/media/media.h new file mode 100644 index 0000000000..52fb6ba50b --- /dev/null +++ b/src/modules/media/media.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_MEDIA_MODULE_NAME "Media" + +void ffPrintMedia(FFMediaOptions* options); +void ffInitMediaOptions(FFMediaOptions* options); +bool ffParseMediaCommandOptions(FFMediaOptions* options, const char* key, const char* value); +void ffDestroyMediaOptions(FFMediaOptions* options); +void ffParseMediaJsonObject(yyjson_val* module); diff --git a/src/modules/media/option.h b/src/modules/media/option.h new file mode 100644 index 0000000000..8498c6e9bb --- /dev/null +++ b/src/modules/media/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFMediaOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFMediaOptions; diff --git a/src/modules/memory.c b/src/modules/memory.c deleted file mode 100644 index 3c82b1a7b3..0000000000 --- a/src/modules/memory.c +++ /dev/null @@ -1,67 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/parsing.h" -#include "common/bar.h" -#include "detection/memory/memory.h" - -#define FF_MEMORY_MODULE_NAME "Memory" -#define FF_MEMORY_NUM_FORMAT_ARGS 3 - -void ffPrintMemory(FFinstance* instance) -{ - FFMemoryResult storage; - const char* error = ffDetectMemory(&storage); - - if(error) - { - ffPrintError(instance, FF_MEMORY_MODULE_NAME, 0, &instance->config.memory, "%s", error); - return; - } - - FF_STRBUF_AUTO_DESTROY usedPretty; - ffStrbufInit(&usedPretty); - ffParseSize(storage.bytesUsed, instance->config.binaryPrefixType, &usedPretty); - - FF_STRBUF_AUTO_DESTROY totalPretty; - ffStrbufInit(&totalPretty); - ffParseSize(storage.bytesTotal, instance->config.binaryPrefixType, &totalPretty); - - uint8_t percentage = storage.bytesTotal == 0 - ? 0 - : (uint8_t) (((long double) storage.bytesUsed / (long double) storage.bytesTotal) * 100.0); - - if(instance->config.memory.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_MEMORY_MODULE_NAME, 0, &instance->config.memory.key); - if (storage.bytesTotal == 0) - puts("Disabled"); - else - { - FF_STRBUF_AUTO_DESTROY str; - ffStrbufInit(&str); - - if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) - { - ffAppendPercentBar(instance, &str, percentage, 0, 5, 8); - ffStrbufAppendC(&str, ' '); - } - - if(!(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) - ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); - - if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) - ffAppendPercentNum(instance, &str, (uint8_t) percentage, 50, 80, str.length > 0); - - ffStrbufTrimRight(&str, ' '); - ffStrbufPutTo(&str, stdout); - } - } - else - { - ffPrintFormat(instance, FF_MEMORY_MODULE_NAME, 0, &instance->config.memory, FF_MEMORY_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, - }); - } -} diff --git a/src/modules/memory/memory.c b/src/modules/memory/memory.c new file mode 100644 index 0000000000..8bd1e7e8f5 --- /dev/null +++ b/src/modules/memory/memory.c @@ -0,0 +1,111 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/parsing.h" +#include "common/bar.h" +#include "detection/memory/memory.h" +#include "modules/memory/memory.h" +#include "util/stringUtils.h" + +#define FF_MEMORY_NUM_FORMAT_ARGS 3 + +void ffPrintMemory(FFMemoryOptions* options) +{ + FFMemoryResult storage; + const char* error = ffDetectMemory(&storage); + + if(error) + { + ffPrintError(FF_MEMORY_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate(); + ffParseSize(storage.bytesUsed, &usedPretty); + + FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate(); + ffParseSize(storage.bytesTotal, &totalPretty); + + uint8_t percentage = storage.bytesTotal == 0 + ? 0 + : (uint8_t) (((long double) storage.bytesUsed / (long double) storage.bytesTotal) * 100.0); + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_MEMORY_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + if (storage.bytesTotal == 0) + puts("Disabled"); + else + { + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + + if(instance.config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffAppendPercentBar(&str, percentage, 0, 5, 8); + ffStrbufAppendC(&str, ' '); + } + + if(!(instance.config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); + + if(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffAppendPercentNum(&str, (uint8_t) percentage, 50, 80, str.length > 0); + + ffStrbufTrimRight(&str, ' '); + ffStrbufPutTo(&str, stdout); + } + } + else + { + ffPrintFormat(FF_MEMORY_MODULE_NAME, 0, &options->moduleArgs, FF_MEMORY_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, + {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, + }); + } +} + +void ffInitMemoryOptions(FFMemoryOptions* options) +{ + options->moduleName = FF_MEMORY_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseMemoryCommandOptions(FFMemoryOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_MEMORY_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyMemoryOptions(FFMemoryOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseMemoryJsonObject(yyjson_val* module) +{ + FFMemoryOptions __attribute__((__cleanup__(ffDestroyMemoryOptions))) options; + ffInitMemoryOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_MEMORY_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintMemory(&options); +} diff --git a/src/modules/memory/memory.h b/src/modules/memory/memory.h new file mode 100644 index 0000000000..e63a45e282 --- /dev/null +++ b/src/modules/memory/memory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_MEMORY_MODULE_NAME "Memory" + +void ffPrintMemory(FFMemoryOptions* options); +void ffInitMemoryOptions(FFMemoryOptions* options); +bool ffParseMemoryCommandOptions(FFMemoryOptions* options, const char* key, const char* value); +void ffDestroyMemoryOptions(FFMemoryOptions* options); +void ffParseMemoryJsonObject(yyjson_val* module); diff --git a/src/modules/memory/option.h b/src/modules/memory/option.h new file mode 100644 index 0000000000..1f8b30bf19 --- /dev/null +++ b/src/modules/memory/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFMemoryOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFMemoryOptions; diff --git a/src/modules/modules.h b/src/modules/modules.h new file mode 100644 index 0000000000..c5e75e525c --- /dev/null +++ b/src/modules/modules.h @@ -0,0 +1,58 @@ +#pragma once + +// For "fastfetch.c" and "flashfetch.c" + +#include "modules/battery/battery.h" +#include "modules/bios/bios.h" +#include "modules/bluetooth/bluetooth.h" +#include "modules/brightness/brightness.h" +#include "modules/board/board.h" +#include "modules/break/break.h" +#include "modules/chassis/chassis.h" +#include "modules/cpu/cpu.h" +#include "modules/cpuusage/cpuusage.h" +#include "modules/command/command.h" +#include "modules/colors/colors.h" +#include "modules/cursor/cursor.h" +#include "modules/custom/custom.h" +#include "modules/datetime/datetime.h" +#include "modules/disk/disk.h" +#include "modules/display/display.h" +#include "modules/de/de.h" +#include "modules/font/font.h" +#include "modules/gamepad/gamepad.h" +#include "modules/gpu/gpu.h" +#include "modules/host/host.h" +#include "modules/icons/icons.h" +#include "modules/kernel/kernel.h" +#include "modules/lm/lm.h" +#include "modules/locale/locale.h" +#include "modules/localip/localip.h" +#include "modules/media/media.h" +#include "modules/memory/memory.h" +#include "modules/monitor/monitor.h" +#include "modules/opengl/opengl.h" +#include "modules/opencl/opencl.h" +#include "modules/os/os.h" +#include "modules/packages/packages.h" +#include "modules/player/player.h" +#include "modules/poweradapter/poweradapter.h" +#include "modules/processes/processes.h" +#include "modules/publicip/publicip.h" +#include "modules/separator/separator.h" +#include "modules/shell/shell.h" +#include "modules/sound/sound.h" +#include "modules/swap/swap.h" +#include "modules/terminal/terminal.h" +#include "modules/terminalfont/terminalfont.h" +#include "modules/terminalsize/terminalsize.h" +#include "modules/theme/theme.h" +#include "modules/title/title.h" +#include "modules/uptime/uptime.h" +#include "modules/users/users.h" +#include "modules/vulkan/vulkan.h" +#include "modules/wallpaper/wallpaper.h" +#include "modules/weather/weather.h" +#include "modules/wifi/wifi.h" +#include "modules/wm/wm.h" +#include "modules/wmtheme/wmtheme.h" diff --git a/src/modules/monitor/monitor.c b/src/modules/monitor/monitor.c new file mode 100644 index 0000000000..9802234810 --- /dev/null +++ b/src/modules/monitor/monitor.c @@ -0,0 +1,118 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/monitor/monitor.h" +#include "modules/monitor/monitor.h" +#include "util/stringUtils.h" + +#include + +#define FF_MONITOR_NUM_FORMAT_ARGS 7 + +void ffPrintMonitor(FFMonitorOptions* options) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFMonitorResult)); + + const char* error = ffDetectMonitor(&result); + + if(error) + { + ffPrintError(FF_MONITOR_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(!result.length) + { + ffPrintError(FF_MONITOR_MODULE_NAME, 0, &options->moduleArgs, "No physical display detected"); + return; + } + + uint8_t index = 0; + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); + FF_LIST_FOR_EACH(FFMonitorResult, display, result) + { + double inch = sqrt(display->physicalWidth * display->physicalWidth + display->physicalHeight * display->physicalHeight) / 25.4; + double ppi = sqrt(display->width * display->width + display->height * display->height) / inch; + + if(options->moduleArgs.outputFormat.length == 0) + { + ffStrbufClear(&key); + if(options->moduleArgs.key.length == 0) + { + ffStrbufAppendF(&key, "%s (%s)", FF_MONITOR_MODULE_NAME, display->name.chars); + } + else + { + ffParseFormatString(&key, &options->moduleArgs.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &display->name}, + }); + } + ffPrintLogoAndKey(key.chars, 0, NULL, &options->moduleArgs.keyColor); + + printf("%ux%u px", display->width, display->height); + if (inch > 0) + printf(" - %ux%u mm (%.2f inches, %.2f ppi)\n", display->physicalWidth, display->physicalHeight, inch, ppi); + else + putchar('\n'); + } + else + { + ffPrintFormat(FF_MONITOR_MODULE_NAME, index, &options->moduleArgs, FF_MONITOR_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &display->name}, + {FF_FORMAT_ARG_TYPE_UINT, &display->width}, + {FF_FORMAT_ARG_TYPE_UINT, &display->height}, + {FF_FORMAT_ARG_TYPE_UINT, &display->physicalWidth}, + {FF_FORMAT_ARG_TYPE_UINT, &display->physicalHeight}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &inch}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &ppi}, + }); + } + + ffStrbufDestroy(&display->name); + } +} + +void ffInitMonitorOptions(FFMonitorOptions* options) +{ + options->moduleName = FF_MONITOR_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseMonitorCommandOptions(FFMonitorOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_MONITOR_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyMonitorOptions(FFMonitorOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseMonitorJsonObject(yyjson_val* module) +{ + FFMonitorOptions __attribute__((__cleanup__(ffDestroyMonitorOptions))) options; + ffInitMonitorOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_MONITOR_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintMonitor(&options); +} diff --git a/src/modules/monitor/monitor.h b/src/modules/monitor/monitor.h new file mode 100644 index 0000000000..a95a3fa740 --- /dev/null +++ b/src/modules/monitor/monitor.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_MONITOR_MODULE_NAME "Monitor" + +void ffPrintMonitor(FFMonitorOptions* options); +void ffInitMonitorOptions(FFMonitorOptions* options); +bool ffParseMonitorCommandOptions(FFMonitorOptions* options, const char* key, const char* value); +void ffDestroyMonitorOptions(FFMonitorOptions* options); +void ffParseMonitorJsonObject(yyjson_val* module); diff --git a/src/modules/monitor/option.h b/src/modules/monitor/option.h new file mode 100644 index 0000000000..ee2efc964a --- /dev/null +++ b/src/modules/monitor/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFMonitorOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFMonitorOptions; diff --git a/src/modules/opencl.c b/src/modules/opencl.c deleted file mode 100644 index c9d33b10d3..0000000000 --- a/src/modules/opencl.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/opencl/opencl.h" - -#define FF_OPENCL_MODULE_NAME "OpenCL" -#define FF_OPENCL_NUM_FORMAT_ARGS 3 - -void ffPrintOpenCL(FFinstance* instance) -{ - FFOpenCLResult opencl; - ffStrbufInit(&opencl.version); - ffStrbufInit(&opencl.device); - ffStrbufInit(&opencl.vendor); - - const char* error = ffDetectOpenCL(instance, &opencl); - - if(error != NULL) - ffPrintError(instance, FF_OPENCL_MODULE_NAME, 0, &instance->config.openCL, "%s", error); - else - { - if(instance->config.openCL.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_OPENCL_MODULE_NAME, 0, &instance->config.openCL.key); - ffStrbufPutTo(&opencl.version, stdout); - } - else - { - ffPrintFormat(instance, FF_OPENCL_MODULE_NAME, 0, &instance->config.openCL, FF_OPENCL_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.version}, - {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.device}, - {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.vendor}, - }); - } - } - - ffStrbufDestroy(&opencl.version); - ffStrbufDestroy(&opencl.device); - ffStrbufDestroy(&opencl.vendor); -} diff --git a/src/modules/opencl/opencl.c b/src/modules/opencl/opencl.c new file mode 100644 index 0000000000..3fd3ce1ebd --- /dev/null +++ b/src/modules/opencl/opencl.c @@ -0,0 +1,86 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/opencl/opencl.h" +#include "modules/opencl/opencl.h" +#include "util/stringUtils.h" + +#define FF_OPENCL_NUM_FORMAT_ARGS 3 + +void ffPrintOpenCL(FFOpenCLOptions* options) +{ + FFOpenCLResult opencl; + ffStrbufInit(&opencl.version); + ffStrbufInit(&opencl.device); + ffStrbufInit(&opencl.vendor); + + const char* error = ffDetectOpenCL(&opencl); + + if(error != NULL) + ffPrintError(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + else + { + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufPutTo(&opencl.version, stdout); + } + else + { + ffPrintFormat(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_OPENCL_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.version}, + {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.device}, + {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.vendor}, + }); + } + } + + ffStrbufDestroy(&opencl.version); + ffStrbufDestroy(&opencl.device); + ffStrbufDestroy(&opencl.vendor); +} + +void ffInitOpenCLOptions(FFOpenCLOptions* options) +{ + options->moduleName = FF_OPENCL_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseOpenCLCommandOptions(FFOpenCLOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_OPENCL_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyOpenCLOptions(FFOpenCLOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseOpenCLJsonObject(yyjson_val* module) +{ + FFOpenCLOptions __attribute__((__cleanup__(ffDestroyOpenCLOptions))) options; + ffInitOpenCLOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_OPENCL_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintOpenCL(&options); +} diff --git a/src/modules/opencl/opencl.h b/src/modules/opencl/opencl.h new file mode 100644 index 0000000000..b01a2a4803 --- /dev/null +++ b/src/modules/opencl/opencl.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_OPENCL_MODULE_NAME "OpenCL" + +void ffPrintOpenCL(FFOpenCLOptions* options); +void ffInitOpenCLOptions(FFOpenCLOptions* options); +bool ffParseOpenCLCommandOptions(FFOpenCLOptions* options, const char* key, const char* value); +void ffDestroyOpenCLOptions(FFOpenCLOptions* options); +void ffParseOpenCLJsonObject(yyjson_val* module); diff --git a/src/modules/opencl/option.h b/src/modules/opencl/option.h new file mode 100644 index 0000000000..addac5245d --- /dev/null +++ b/src/modules/opencl/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFOpenCLOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFOpenCLOptions; diff --git a/src/modules/opengl.c b/src/modules/opengl.c deleted file mode 100644 index 61e78451b0..0000000000 --- a/src/modules/opengl.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/opengl/opengl.h" - -#define FF_OPENGL_MODULE_NAME "OpenGL" -#define FF_OPENGL_NUM_FORMAT_ARGS 4 - -void ffPrintOpenGL(FFinstance* instance) -{ - FFOpenGLResult result; - ffStrbufInit(&result.version); - ffStrbufInit(&result.renderer); - ffStrbufInit(&result.vendor); - ffStrbufInit(&result.slv); - - const char* error = ffDetectOpenGL(instance, &result); - if(error) - { - ffPrintError(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL, "%s", error); - return; - } - - if(instance->config.openGL.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL.key); - puts(result.version.chars); - } - else - { - ffPrintFormat(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL, FF_OPENGL_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result.version}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.renderer}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.vendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.slv} - }); - } - - ffStrbufDestroy(&result.version); - ffStrbufDestroy(&result.renderer); - ffStrbufDestroy(&result.vendor); - ffStrbufDestroy(&result.slv); -} diff --git a/src/modules/opengl/opengl.c b/src/modules/opengl/opengl.c new file mode 100644 index 0000000000..e5f5bc9fcf --- /dev/null +++ b/src/modules/opengl/opengl.c @@ -0,0 +1,125 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/opengl/opengl.h" +#include "modules/opengl/opengl.h" +#include "util/stringUtils.h" + +#define FF_OPENGL_NUM_FORMAT_ARGS 4 + +void ffPrintOpenGL(FFOpenGLOptions* options) +{ + FFOpenGLResult result; + ffStrbufInit(&result.version); + ffStrbufInit(&result.renderer); + ffStrbufInit(&result.vendor); + ffStrbufInit(&result.slv); + + const char* error = ffDetectOpenGL(&result); + if(error) + { + ffPrintError(FF_OPENGL_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_OPENGL_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + puts(result.version.chars); + } + else + { + ffPrintFormat(FF_OPENGL_MODULE_NAME, 0, &options->moduleArgs, FF_OPENGL_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.version}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.renderer}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.vendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.slv} + }); + } + + ffStrbufDestroy(&result.version); + ffStrbufDestroy(&result.renderer); + ffStrbufDestroy(&result.vendor); + ffStrbufDestroy(&result.slv); +} + +void ffInitOpenGLOptions(FFOpenGLOptions* options) +{ + options->moduleName = FF_OPENGL_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + #if defined(__linux__) || defined(__FreeBSD__) + options->library = FF_OPENGL_LIBRARY_AUTO; + #endif +} + +bool ffParseOpenGLCommandOptions(FFOpenGLOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_OPENGL_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + #if defined(__linux__) || defined(__FreeBSD__) + if (ffStrEqualsIgnCase(key, "library")) + { + options->library = (FFOpenGLLibrary) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "auto", FF_OPENGL_LIBRARY_AUTO }, + { "egl", FF_OPENGL_LIBRARY_EGL }, + { "glx", FF_OPENGL_LIBRARY_GLX }, + { "osmesa", FF_OPENGL_LIBRARY_OSMESA }, + {} + }); + } + #endif + + return false; +} + +void ffDestroyOpenGLOptions(FFOpenGLOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseOpenGLJsonObject(yyjson_val* module) +{ + FFOpenGLOptions __attribute__((__cleanup__(ffDestroyOpenGLOptions))) options; + ffInitOpenGLOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + #if defined(__linux__) || defined(__FreeBSD__) + if (ffStrEqualsIgnCase(key, "library")) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "auto", FF_OPENGL_LIBRARY_AUTO }, + { "egl", FF_OPENGL_LIBRARY_EGL }, + { "glx", FF_OPENGL_LIBRARY_GLX }, + { "osmesa", FF_OPENGL_LIBRARY_OSMESA }, + {}, + }); + if (error) + ffPrintError(FF_OPENGL_MODULE_NAME, 0, &options.moduleArgs, "Invalid %s value: %s", key, error); + else + options.library = (FFOpenGLLibrary) value; + continue; + } + #endif + + ffPrintError(FF_OPENGL_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintOpenGL(&options); +} diff --git a/src/modules/opengl/opengl.h b/src/modules/opengl/opengl.h new file mode 100644 index 0000000000..5d4f1ab88a --- /dev/null +++ b/src/modules/opengl/opengl.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_OPENGL_MODULE_NAME "OpenGL" + +void ffPrintOpenGL(FFOpenGLOptions* options); +void ffInitOpenGLOptions(FFOpenGLOptions* options); +bool ffParseOpenGLCommandOptions(FFOpenGLOptions* options, const char* key, const char* value); +void ffDestroyOpenGLOptions(FFOpenGLOptions* options); +void ffParseOpenGLJsonObject(yyjson_val* module); diff --git a/src/modules/opengl/option.h b/src/modules/opengl/option.h new file mode 100644 index 0000000000..712374d935 --- /dev/null +++ b/src/modules/opengl/option.h @@ -0,0 +1,25 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +#if defined(__linux__) || defined(__FreeBSD__) +typedef enum FFOpenGLLibrary +{ + FF_OPENGL_LIBRARY_AUTO, + FF_OPENGL_LIBRARY_EGL, + FF_OPENGL_LIBRARY_GLX, + FF_OPENGL_LIBRARY_OSMESA +} FFOpenGLLibrary; +#endif + +typedef struct FFOpenGLOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + #if defined(__linux__) || defined(__FreeBSD__) + FFOpenGLLibrary library; + #endif +} FFOpenGLOptions; diff --git a/src/modules/options.h b/src/modules/options.h new file mode 100644 index 0000000000..fbd845d3af --- /dev/null +++ b/src/modules/options.h @@ -0,0 +1,57 @@ +#pragma once + +// For "fastfetch.h" + +#include "modules/battery/option.h" +#include "modules/bios/option.h" +#include "modules/bluetooth/option.h" +#include "modules/board/option.h" +#include "modules/brightness/option.h" +#include "modules/chassis/option.h" +#include "modules/cpu/option.h" +#include "modules/cpuusage/option.h" +#include "modules/colors/option.h" +#include "modules/cursor/option.h" +#include "modules/custom/option.h" +#include "modules/command/option.h" +#include "modules/datetime/option.h" +#include "modules/de/option.h" +#include "modules/disk/option.h" +#include "modules/display/option.h" +#include "modules/font/option.h" +#include "modules/host/option.h" +#include "modules/gamepad/option.h" +#include "modules/gpu/option.h" +#include "modules/icons/option.h" +#include "modules/kernel/option.h" +#include "modules/locale/option.h" +#include "modules/lm/option.h" +#include "modules/localip/option.h" +#include "modules/media/option.h" +#include "modules/memory/option.h" +#include "modules/monitor/option.h" +#include "modules/opengl/option.h" +#include "modules/opencl/option.h" +#include "modules/os/option.h" +#include "modules/packages/option.h" +#include "modules/player/option.h" +#include "modules/poweradapter/option.h" +#include "modules/processes/option.h" +#include "modules/publicip/option.h" +#include "modules/separator/option.h" +#include "modules/shell/option.h" +#include "modules/sound/option.h" +#include "modules/swap/option.h" +#include "modules/terminal/option.h" +#include "modules/terminalfont/option.h" +#include "modules/terminalsize/option.h" +#include "modules/theme/option.h" +#include "modules/title/option.h" +#include "modules/uptime/option.h" +#include "modules/users/option.h" +#include "modules/vulkan/option.h" +#include "modules/wallpaper/option.h" +#include "modules/weather/option.h" +#include "modules/wifi/option.h" +#include "modules/wm/option.h" +#include "modules/wmtheme/option.h" diff --git a/src/modules/os/option.h b/src/modules/os/option.h new file mode 100644 index 0000000000..be1bfda1fc --- /dev/null +++ b/src/modules/os/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFOSOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFOSOptions; diff --git a/src/modules/os.c b/src/modules/os/os.c similarity index 54% rename from src/modules/os.c rename to src/modules/os/os.c index 140cfdbbe8..1193067426 100644 --- a/src/modules/os.c +++ b/src/modules/os/os.c @@ -1,13 +1,15 @@ -#include "fastfetch.h" #include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/option.h" #include "detection/os/os.h" +#include "modules/os/os.h" +#include "util/stringUtils.h" #include -#define FF_OS_MODULE_NAME "OS" #define FF_OS_NUM_FORMAT_ARGS 12 -static void buildOutputDefault(const FFinstance* instance, const FFOSResult* os, FFstrbuf* result) +static void buildOutputDefault(const FFOSResult* os, FFstrbuf* result) { //Create the basic output if(os->name.length > 0) @@ -17,7 +19,7 @@ static void buildOutputDefault(const FFinstance* instance, const FFOSResult* os, else if(os->id.length > 0) ffStrbufAppend(result, &os->id); else - ffStrbufAppend(result, &instance->state.platform.systemName); + ffStrbufAppend(result, &instance.state.platform.systemName); #ifdef __APPLE__ if(os->codename.length > 0) @@ -62,14 +64,14 @@ static void buildOutputDefault(const FFinstance* instance, const FFOSResult* os, } //Append architecture if it is missing - if(ffStrbufFirstIndex(result, &instance->state.platform.systemArchitecture) == result->length) + if(ffStrbufFirstIndex(result, &instance.state.platform.systemArchitecture) == result->length) { ffStrbufAppendC(result, ' '); - ffStrbufAppend(result, &instance->state.platform.systemArchitecture); + ffStrbufAppend(result, &instance.state.platform.systemArchitecture); } } -static void buildOutputNixOS(const FFinstance* instance, const FFOSResult* os, FFstrbuf* result) +static void buildOutputNixOS(const FFOSResult* os, FFstrbuf* result) { ffStrbufAppendS(result, "NixOS"); @@ -87,41 +89,39 @@ static void buildOutputNixOS(const FFinstance* instance, const FFOSResult* os, F ffStrbufAppendC(result, ')'); } - if(instance->state.platform.systemArchitecture.length > 0) + if(instance.state.platform.systemArchitecture.length > 0) { ffStrbufAppendC(result, ' '); - ffStrbufAppend(result, &instance->state.platform.systemArchitecture); + ffStrbufAppend(result, &instance.state.platform.systemArchitecture); } } -void ffPrintOS(FFinstance* instance) +void ffPrintOS(FFOSOptions* options) { - const FFOSResult* os = ffDetectOS(instance); + const FFOSResult* os = ffDetectOS(); if(os->name.length == 0 && os->prettyName.length == 0 && os->id.length == 0) { - ffPrintError(instance, FF_OS_MODULE_NAME, 0, &instance->config.os, "Could not detect OS"); + ffPrintError(FF_OS_MODULE_NAME, 0, &options->moduleArgs, "Could not detect OS"); return; } - if(instance->config.os.outputFormat.length == 0) + if(options->moduleArgs.outputFormat.length == 0) { - FFstrbuf result; - ffStrbufInit(&result); + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate(); if(ffStrbufIgnCaseCompS(&os->id, "nixos") == 0) - buildOutputNixOS(instance, os, &result); + buildOutputNixOS(os, &result); else - buildOutputDefault(instance, os, &result); + buildOutputDefault(os, &result); - ffPrintLogoAndKey(instance, FF_OS_MODULE_NAME, 0, &instance->config.os.key); + ffPrintLogoAndKey(FF_OS_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); ffStrbufPutTo(&result, stdout); - ffStrbufDestroy(&result); } else { - ffPrintFormat(instance, FF_OS_MODULE_NAME, 0, &instance->config.os, FF_OS_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemName}, + ffPrintFormat(FF_OS_MODULE_NAME, 0, &options->moduleArgs, FF_OS_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemName}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->name}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->prettyName}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->id}, @@ -132,7 +132,53 @@ void ffPrintOS(FFinstance* instance) {FF_FORMAT_ARG_TYPE_STRBUF, &os->versionID}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->codename}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->buildID}, - {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemArchitecture} + {FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemArchitecture} }); } } + +void ffInitOSOptions(FFOSOptions* options) +{ + options->moduleName = FF_OS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseOSCommandOptions(FFOSOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_OS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyOSOptions(FFOSOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseOSJsonObject(yyjson_val* module) +{ + FFOSOptions __attribute__((__cleanup__(ffDestroyOSOptions))) options; + ffInitOSOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_OS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintOS(&options); +} diff --git a/src/modules/os/os.h b/src/modules/os/os.h new file mode 100644 index 0000000000..36856d9b1a --- /dev/null +++ b/src/modules/os/os.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_OS_MODULE_NAME "OS" + +void ffPrintOS(FFOSOptions* options); +void ffInitOSOptions(FFOSOptions* options); +bool ffParseOSCommandOptions(FFOSOptions* options, const char* key, const char* value); +void ffDestroyOSOptions(FFOSOptions* options); +void ffParseOSJsonObject(yyjson_val* module); diff --git a/src/modules/packages.c b/src/modules/packages.c deleted file mode 100644 index a7e5d60b95..0000000000 --- a/src/modules/packages.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/packages/packages.h" - -#define FF_PACKAGES_MODULE_NAME "Packages" -#define FF_PACKAGES_NUM_FORMAT_ARGS 22 - -void ffPrintPackages(FFinstance* instance) -{ - const FFPackagesResult* counts = ffDetectPackages(instance); - uint32_t all = counts->all; //Copy it, so we can substract from it in FF_PRINT_PACKAGE - - if(all == 0) - { - ffPrintError(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packages, "No packages from known package managers found"); - return; - } - - if(instance->config.packages.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packages.key); - - #define FF_PRINT_PACKAGE_NAME(var, name) \ - if(counts->var > 0) \ - { \ - printf("%u (%s)", counts->var, (name)); \ - if((all -= counts->var) > 0) \ - printf(", "); \ - }; - - #define FF_PRINT_PACKAGE(name) FF_PRINT_PACKAGE_NAME(name, #name) - - if(counts->pacman > 0) - { - printf("%u (pacman)", counts->pacman); - if(counts->pacmanBranch.length > 0) - printf("[%s]", counts->pacmanBranch.chars); - if((all -= counts->pacman) > 0) - printf(", "); - }; - - FF_PRINT_PACKAGE(dpkg) - FF_PRINT_PACKAGE(rpm) - FF_PRINT_PACKAGE(emerge) - FF_PRINT_PACKAGE(eopkg) - FF_PRINT_PACKAGE(xbps) - FF_PRINT_PACKAGE_NAME(nixSystem, "nix-system") - FF_PRINT_PACKAGE_NAME(nixUser, "nix-user") - FF_PRINT_PACKAGE_NAME(nixDefault, "nix-default") - FF_PRINT_PACKAGE(apk) - FF_PRINT_PACKAGE(pkg) - FF_PRINT_PACKAGE_NAME(flatpakSystem, counts->flatpakUser ? "flatpak-system" : "flatpak") - FF_PRINT_PACKAGE_NAME(flatpakUser, "flatpak-user") - FF_PRINT_PACKAGE(snap) - FF_PRINT_PACKAGE(brew) - FF_PRINT_PACKAGE_NAME(brewCask, "brew-cask") - FF_PRINT_PACKAGE(port) - FF_PRINT_PACKAGE(scoop) - FF_PRINT_PACKAGE(choco) - FF_PRINT_PACKAGE(pkgtool) - - //Fix linter warning of unused value of all - (void) all; - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packages, FF_PACKAGES_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_UINT, &all}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->pacman}, - {FF_FORMAT_ARG_TYPE_STRBUF, &counts->pacmanBranch}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->dpkg}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->rpm}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->emerge}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->eopkg}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->xbps}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->nixSystem}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->nixUser}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->nixDefault}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->apk}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->pkg}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->flatpakSystem}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->flatpakUser}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->snap}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->brew}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->brewCask}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->port}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->scoop}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->choco}, - {FF_FORMAT_ARG_TYPE_UINT, &counts->pkgtool}, - }); - } -} diff --git a/src/modules/packages/option.h b/src/modules/packages/option.h new file mode 100644 index 0000000000..e06b8403b3 --- /dev/null +++ b/src/modules/packages/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFPackagesOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFPackagesOptions; diff --git a/src/modules/packages/packages.c b/src/modules/packages/packages.c new file mode 100644 index 0000000000..0fa86f31ce --- /dev/null +++ b/src/modules/packages/packages.c @@ -0,0 +1,144 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/packages/packages.h" +#include "modules/packages/packages.h" +#include "util/stringUtils.h" + +#define FF_PACKAGES_NUM_FORMAT_ARGS 22 + +void ffPrintPackages(FFPackagesOptions* options) +{ + FFPackagesResult counts = {}; + ffStrbufInit(&counts.pacmanBranch); + + const char* error = ffDetectPackages(&counts); + + if(error) + { + ffPrintError(FF_PACKAGES_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_PACKAGES_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + #define FF_PRINT_PACKAGE_NAME(var, name) \ + if(counts.var > 0) \ + { \ + printf("%u (%s)", counts.var, (name)); \ + if((all -= counts.var) > 0) \ + printf(", "); \ + }; + + #define FF_PRINT_PACKAGE(name) FF_PRINT_PACKAGE_NAME(name, #name) + + uint32_t all = counts.all; + if(counts.pacman > 0) + { + printf("%u (pacman)", counts.pacman); + if(counts.pacmanBranch.length > 0) + printf("[%s]", counts.pacmanBranch.chars); + if((all -= counts.pacman) > 0) + printf(", "); + }; + + FF_PRINT_PACKAGE(dpkg) + FF_PRINT_PACKAGE(rpm) + FF_PRINT_PACKAGE(emerge) + FF_PRINT_PACKAGE(eopkg) + FF_PRINT_PACKAGE(xbps) + FF_PRINT_PACKAGE_NAME(nixSystem, "nix-system") + FF_PRINT_PACKAGE_NAME(nixUser, "nix-user") + FF_PRINT_PACKAGE_NAME(nixDefault, "nix-default") + FF_PRINT_PACKAGE(apk) + FF_PRINT_PACKAGE(pkg) + FF_PRINT_PACKAGE_NAME(flatpakSystem, counts.flatpakUser ? "flatpak-system" : "flatpak") + FF_PRINT_PACKAGE_NAME(flatpakUser, "flatpak-user") + FF_PRINT_PACKAGE(snap) + FF_PRINT_PACKAGE(brew) + FF_PRINT_PACKAGE_NAME(brewCask, "brew-cask") + FF_PRINT_PACKAGE(port) + FF_PRINT_PACKAGE(scoop) + FF_PRINT_PACKAGE(choco) + FF_PRINT_PACKAGE(pkgtool) + FF_PRINT_PACKAGE(paludis) + + putchar('\n'); + } + else + { + ffPrintFormat(FF_PACKAGES_MODULE_NAME, 0, &options->moduleArgs, FF_PACKAGES_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT, &counts.all}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.pacman}, + {FF_FORMAT_ARG_TYPE_STRBUF, &counts.pacmanBranch}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.dpkg}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.rpm}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.emerge}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.eopkg}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.xbps}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.nixSystem}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.nixUser}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.nixDefault}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.apk}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.pkg}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.flatpakSystem}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.flatpakUser}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.snap}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.brew}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.brewCask}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.port}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.scoop}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.choco}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.pkgtool}, + }); + } + + ffStrbufDestroy(&counts.pacmanBranch); +} + +void ffInitPackagesOptions(FFPackagesOptions* options) +{ + options->moduleName = FF_PACKAGES_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_PACKAGES_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyPackagesOptions(FFPackagesOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParsePackagesJsonObject(yyjson_val* module) +{ + FFPackagesOptions __attribute__((__cleanup__(ffDestroyPackagesOptions))) options; + ffInitPackagesOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_PACKAGES_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintPackages(&options); +} diff --git a/src/modules/packages/packages.h b/src/modules/packages/packages.h new file mode 100644 index 0000000000..87516579a4 --- /dev/null +++ b/src/modules/packages/packages.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_PACKAGES_MODULE_NAME "Packages" + +void ffPrintPackages(FFPackagesOptions* options); +void ffInitPackagesOptions(FFPackagesOptions* options); +bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key, const char* value); +void ffDestroyPackagesOptions(FFPackagesOptions* options); +void ffParsePackagesJsonObject(yyjson_val* module); diff --git a/src/modules/player/option.h b/src/modules/player/option.h new file mode 100644 index 0000000000..e270560550 --- /dev/null +++ b/src/modules/player/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFPlayerOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFPlayerOptions; diff --git a/src/modules/player.c b/src/modules/player/player.c similarity index 51% rename from src/modules/player.c rename to src/modules/player/player.c index 32eecde0ff..1503a9cad5 100644 --- a/src/modules/player.c +++ b/src/modules/player/player.c @@ -1,24 +1,25 @@ -#include "fastfetch.h" #include "common/printing.h" +#include "common/jsonconfig.h" #include "detection/media/media.h" +#include "modules/player/player.h" +#include "util/stringUtils.h" #include -#define FF_PLAYER_MODULE_NAME "Media Player" +#define FF_PLAYER_DISPLAY_NAME "Media Player" #define FF_PLAYER_NUM_FORMAT_ARGS 4 -void ffPrintPlayer(FFinstance* instance) +void ffPrintPlayer(FFPlayerOptions* options) { - const FFMediaResult* media = ffDetectMedia(instance); + const FFMediaResult* media = ffDetectMedia(); if(media->error.length > 0) { - ffPrintError(instance, FF_PLAYER_MODULE_NAME, 0, &instance->config.player, "%s", media->error.chars); + ffPrintError(FF_PLAYER_DISPLAY_NAME, 0, &options->moduleArgs, "%s", media->error.chars); return; } - FFstrbuf playerPretty; - ffStrbufInit(&playerPretty); + FF_STRBUF_AUTO_DESTROY playerPretty = ffStrbufCreate(); //If we are on a website, prepend the website name if( @@ -56,20 +57,64 @@ void ffPrintPlayer(FFinstance* instance) if(playerPrettyIsCustom) ffStrbufAppendC(&playerPretty, ')'); - if(instance->config.player.outputFormat.length == 0) + if(options->moduleArgs.outputFormat.length == 0) { - ffPrintLogoAndKey(instance, FF_PLAYER_MODULE_NAME, 0, &instance->config.player.key); + ffPrintLogoAndKey(FF_PLAYER_DISPLAY_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); ffStrbufPutTo(&playerPretty, stdout); } else { - ffPrintFormat(instance, FF_PLAYER_MODULE_NAME, 0, &instance->config.player, FF_PLAYER_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintFormat(FF_PLAYER_DISPLAY_NAME, 0, &options->moduleArgs, FF_PLAYER_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &playerPretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &media->player}, {FF_FORMAT_ARG_TYPE_STRBUF, &media->playerId}, {FF_FORMAT_ARG_TYPE_STRBUF, &media->url} }); } +} + +void ffInitPlayerOptions(FFPlayerOptions* options) +{ + options->moduleName = FF_PLAYER_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParsePlayerCommandOptions(FFPlayerOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_PLAYER_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyPlayerOptions(FFPlayerOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParsePlayerJsonObject(yyjson_val* module) +{ + FFPlayerOptions __attribute__((__cleanup__(ffDestroyPlayerOptions))) options; + ffInitPlayerOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_PLAYER_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } - ffStrbufDestroy(&playerPretty); + ffPrintPlayer(&options); } diff --git a/src/modules/player/player.h b/src/modules/player/player.h new file mode 100644 index 0000000000..6f09b425f0 --- /dev/null +++ b/src/modules/player/player.h @@ -0,0 +1,12 @@ + +#pragma once + +#include "fastfetch.h" + +#define FF_PLAYER_MODULE_NAME "Player" + +void ffPrintPlayer(FFPlayerOptions* options); +void ffInitPlayerOptions(FFPlayerOptions* options); +bool ffParsePlayerCommandOptions(FFPlayerOptions* options, const char* key, const char* value); +void ffDestroyPlayerOptions(FFPlayerOptions* options); +void ffParsePlayerJsonObject(yyjson_val* module); diff --git a/src/modules/poweradapter.c b/src/modules/poweradapter.c deleted file mode 100644 index c2cd7550d6..0000000000 --- a/src/modules/poweradapter.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/poweradapter/poweradapter.h" - -#define FF_POWER_ADAPTER_MODULE_NAME "Power Adapter" -#define FF_POWER_ADAPTER_MODULE_ARGS 5 - -static void printPowerAdapter(FFinstance* instance, const PowerAdapterResult* result, uint8_t index) -{ - if(result->watts != FF_POWER_ADAPTER_UNSET) - { - if(instance->config.powerAdapter.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_POWER_ADAPTER_MODULE_NAME, index, &instance->config.powerAdapter.key); - - if(result->name.length > 0) - puts(result->name.chars); - else if(result->watts == FF_POWER_ADAPTER_NOT_CONNECTED) - puts("not connected"); - else - printf("%dW\n", result->watts); - } - else - { - ffPrintFormat(instance, FF_POWER_ADAPTER_MODULE_NAME, index, &instance->config.powerAdapter, FF_POWER_ADAPTER_MODULE_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_INT, &result->watts}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->description}, - }); - } - } -} - -void ffPrintPowerAdapter(FFinstance* instance) -{ - FFlist results; - ffListInitA(&results, sizeof(PowerAdapterResult), 0); - - const char* error = ffDetectPowerAdapterImpl(instance, &results); - - if (error) - { - ffPrintError(instance, FF_POWER_ADAPTER_MODULE_NAME, 0, &instance->config.powerAdapter, "%s", error); - } - else if(results.length == 0) - { - ffPrintError(instance, FF_POWER_ADAPTER_MODULE_NAME, 0, &instance->config.powerAdapter, "No power adapters found"); - } - else - { - for(uint8_t i = 0; i < (uint8_t) results.length; i++) - { - PowerAdapterResult* result = ffListGet(&results, i); - printPowerAdapter(instance, result, i); - - ffStrbufDestroy(&result->manufacturer); - ffStrbufDestroy(&result->description); - ffStrbufDestroy(&result->modelName); - ffStrbufDestroy(&result->name); - } - } - - ffListDestroy(&results); -} diff --git a/src/modules/poweradapter/option.h b/src/modules/poweradapter/option.h new file mode 100644 index 0000000000..7acaf29ee7 --- /dev/null +++ b/src/modules/poweradapter/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFPowerAdapterOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFPowerAdapterOptions; diff --git a/src/modules/poweradapter/poweradapter.c b/src/modules/poweradapter/poweradapter.c new file mode 100644 index 0000000000..629a096b16 --- /dev/null +++ b/src/modules/poweradapter/poweradapter.c @@ -0,0 +1,110 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/poweradapter/poweradapter.h" +#include "modules/poweradapter/poweradapter.h" +#include "util/stringUtils.h" + +#define FF_POWERADAPTER_DISPLAY_NAME "Power Adapter" +#define FF_POWERADAPTER_MODULE_ARGS 5 + +void ffPrintPowerAdapter(FFPowerAdapterOptions* options) +{ + FFlist results; + ffListInit(&results, sizeof(PowerAdapterResult)); + + const char* error = ffDetectPowerAdapterImpl(&results); + + if (error) + { + ffPrintError(FF_POWERADAPTER_DISPLAY_NAME, 0, &options->moduleArgs, "%s", error); + } + else if(results.length == 0) + { + ffPrintError(FF_POWERADAPTER_DISPLAY_NAME, 0, &options->moduleArgs, "No power adapters found"); + } + else + { + for(uint8_t i = 0; i < (uint8_t) results.length; i++) + { + PowerAdapterResult* result = ffListGet(&results, i); + + if(result->watts != FF_POWERADAPTER_UNSET) + { + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_POWERADAPTER_DISPLAY_NAME, i, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + if(result->name.length > 0) + puts(result->name.chars); + else if(result->watts == FF_POWERADAPTER_NOT_CONNECTED) + puts("not connected"); + else + printf("%dW\n", result->watts); + } + else + { + ffPrintFormat(FF_POWERADAPTER_DISPLAY_NAME, i, &options->moduleArgs, FF_POWERADAPTER_MODULE_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_INT, &result->watts}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->description}, + }); + } + } + + ffStrbufDestroy(&result->manufacturer); + ffStrbufDestroy(&result->description); + ffStrbufDestroy(&result->modelName); + ffStrbufDestroy(&result->name); + } + } + + ffListDestroy(&results); +} + +void ffInitPowerAdapterOptions(FFPowerAdapterOptions* options) +{ + options->moduleName = FF_POWERADAPTER_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParsePowerAdapterCommandOptions(FFPowerAdapterOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_POWERADAPTER_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyPowerAdapterOptions(FFPowerAdapterOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParsePowerAdapterJsonObject(yyjson_val* module) +{ + FFPowerAdapterOptions __attribute__((__cleanup__(ffDestroyPowerAdapterOptions))) options; + ffInitPowerAdapterOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_POWERADAPTER_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintPowerAdapter(&options); +} diff --git a/src/modules/poweradapter/poweradapter.h b/src/modules/poweradapter/poweradapter.h new file mode 100644 index 0000000000..93c6a77046 --- /dev/null +++ b/src/modules/poweradapter/poweradapter.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_POWERADAPTER_MODULE_NAME "PowerAdapter" + +void ffPrintPowerAdapter(FFPowerAdapterOptions* options); +void ffInitPowerAdapterOptions(FFPowerAdapterOptions* options); +bool ffParsePowerAdapterCommandOptions(FFPowerAdapterOptions* options, const char* key, const char* value); +void ffDestroyPowerAdapterOptions(FFPowerAdapterOptions* options); +void ffParsePowerAdapterJsonObject(yyjson_val* module); diff --git a/src/modules/processes.c b/src/modules/processes.c deleted file mode 100644 index 70a64ad832..0000000000 --- a/src/modules/processes.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/processes/processes.h" - -#define FF_PROCESSES_MODULE_NAME "Processes" -#define FF_PROCESSES_NUM_FORMAT_ARGS 1 - -void ffPrintProcesses(FFinstance* instance) -{ - uint32_t numProcesses = 0; - const char* error = ffDetectProcesses(&numProcesses); - - if(error) - { - ffPrintError(instance, FF_PROCESSES_MODULE_NAME, 0, &instance->config.processes, "%s", error); - return; - } - - if(instance->config.processes.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_PROCESSES_MODULE_NAME, 0, &instance->config.processes.key); - - printf("%u\n", numProcesses); - } - else - { - ffPrintFormat(instance, FF_PROCESSES_MODULE_NAME, 0, &instance->config.processes, FF_PROCESSES_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_UINT, &numProcesses} - }); - } -} diff --git a/src/modules/processes/option.h b/src/modules/processes/option.h new file mode 100644 index 0000000000..9d2cd80866 --- /dev/null +++ b/src/modules/processes/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFProcessesOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFProcessesOptions; diff --git a/src/modules/processes/processes.c b/src/modules/processes/processes.c new file mode 100644 index 0000000000..bc5cf63b90 --- /dev/null +++ b/src/modules/processes/processes.c @@ -0,0 +1,78 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/processes/processes.h" +#include "modules/processes/processes.h" +#include "util/stringUtils.h" + +#define FF_PROCESSES_NUM_FORMAT_ARGS 1 + +void ffPrintProcesses(FFProcessesOptions* options) +{ + uint32_t numProcesses = 0; + const char* error = ffDetectProcesses(&numProcesses); + + if(error) + { + ffPrintError(FF_PROCESSES_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_PROCESSES_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + printf("%u\n", numProcesses); + } + else + { + ffPrintFormat(FF_PROCESSES_MODULE_NAME, 0, &options->moduleArgs, FF_PROCESSES_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT, &numProcesses} + }); + } +} + +void ffInitProcessesOptions(FFProcessesOptions* options) +{ + options->moduleName = FF_PROCESSES_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseProcessesCommandOptions(FFProcessesOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_PROCESSES_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyProcessesOptions(FFProcessesOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseProcessesJsonObject(yyjson_val* module) +{ + FFProcessesOptions __attribute__((__cleanup__(ffDestroyProcessesOptions))) options; + ffInitProcessesOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_PROCESSES_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintProcesses(&options); +} diff --git a/src/modules/processes/processes.h b/src/modules/processes/processes.h new file mode 100644 index 0000000000..84696356d0 --- /dev/null +++ b/src/modules/processes/processes.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_PROCESSES_MODULE_NAME "Processes" + +void ffPrintProcesses(FFProcessesOptions* options); +void ffInitProcessesOptions(FFProcessesOptions* options); +bool ffParseProcessesCommandOptions(FFProcessesOptions* options, const char* key, const char* value); +void ffDestroyProcessesOptions(FFProcessesOptions* options); +void ffParseProcessesJsonObject(yyjson_val* module); diff --git a/src/modules/publicip.c b/src/modules/publicip.c deleted file mode 100644 index 61c85698e5..0000000000 --- a/src/modules/publicip.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/networking.h" - -#define FF_PUBLICIP_MODULE_NAME "Public IP" -#define FF_PUBLICIP_NUM_FORMAT_ARGS 1 - -static FFNetworkingState state; -static int status = -1; - -void ffPreparePublicIp(FFinstance* instance) -{ - if(instance->config.publicIpUrl.length == 0) - status = ffNetworkingSendHttpRequest(&state, "ipinfo.io", "/ip", NULL); - else - { - FFstrbuf host; - ffStrbufInitCopy(&host, &instance->config.publicIpUrl); - ffStrbufSubstrAfterFirstS(&host, "://"); - uint32_t pathStartIndex = ffStrbufFirstIndexC(&host, '/'); - - FFstrbuf path; - ffStrbufInit(&path); - if(pathStartIndex != host.length) - { - ffStrbufAppendNS(&path, pathStartIndex, host.chars + (host.length - pathStartIndex)); - host.length = pathStartIndex; - host.chars[pathStartIndex] = '\0'; - } - - status = ffNetworkingSendHttpRequest(&state, host.chars, path.length == 0 ? "/" : path.chars, NULL); - - ffStrbufDestroy(&path); - ffStrbufDestroy(&host); - } -} - -void ffPrintPublicIp(FFinstance* instance) -{ - if(status == -1) - ffPreparePublicIp(instance); - - if(status == 0) - { - ffPrintError(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP, "Failed to connect to an IP detection server"); - return; - } - - FFstrbuf result; - ffStrbufInitA(&result, 4096); - bool success = ffNetworkingRecvHttpResponse(&state, &result, instance->config.publicIpTimeout); - if(success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n"); - - if(!success || result.length == 0) - { - ffPrintError(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP, "Failed to receive the server response"); - ffStrbufDestroy(&result); - return; - } - - if(instance->config.publicIP.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP.key); - ffStrbufPutTo(&result, stdout); - } - else - { - ffPrintFormat(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP, FF_PUBLICIP_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result} - }); - } - - ffStrbufDestroy(&result); -} diff --git a/src/modules/publicip/option.h b/src/modules/publicip/option.h new file mode 100644 index 0000000000..aef383fc5e --- /dev/null +++ b/src/modules/publicip/option.h @@ -0,0 +1,14 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFPublicIpOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFstrbuf url; + uint32_t timeout; +} FFPublicIpOptions; diff --git a/src/modules/publicip/publicip.c b/src/modules/publicip/publicip.c new file mode 100644 index 0000000000..24d65ea3cf --- /dev/null +++ b/src/modules/publicip/publicip.c @@ -0,0 +1,165 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/networking.h" +#include "modules/publicip/publicip.h" +#include "util/stringUtils.h" + +#define FF_PUBLICIP_DISPLAY_NAME "Public IP" +#define FF_PUBLICIP_NUM_FORMAT_ARGS 1 + +static FFNetworkingState state; +static int status = -1; + +static inline void wrapYyjsonFree(yyjson_doc** doc) +{ + assert(doc); + if (*doc) + yyjson_doc_free(*doc); +} + +void ffPreparePublicIp(FFPublicIpOptions* options) +{ + if (options->url.length == 0) + status = ffNetworkingSendHttpRequest(&state, "ipinfo.io", "/json", NULL); + else + { + FF_STRBUF_AUTO_DESTROY host = ffStrbufCreateCopy(&options->url); + ffStrbufSubstrAfterFirstS(&host, "://"); + uint32_t pathStartIndex = ffStrbufFirstIndexC(&host, '/'); + + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + if(pathStartIndex != host.length) + { + ffStrbufAppendNS(&path, pathStartIndex, host.chars + (host.length - pathStartIndex)); + host.length = pathStartIndex; + host.chars[pathStartIndex] = '\0'; + } + + status = ffNetworkingSendHttpRequest(&state, host.chars, path.length == 0 ? "/" : path.chars, NULL); + } +} + +void ffPrintPublicIp(FFPublicIpOptions* options) +{ + if (status == -1) + ffPreparePublicIp(options); + + if (status == 0) + { + ffPrintError(FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs, "Failed to connect to an IP detection server"); + return; + } + + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(4096); + bool success = ffNetworkingRecvHttpResponse(&state, &result, options->timeout); + if (success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n"); + + if (!success || result.length == 0) + { + ffPrintError(FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs, "Failed to receive the server response"); + return; + } + + if (options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + if (options->url.length == 0) + { + yyjson_doc* __attribute__((__cleanup__(wrapYyjsonFree))) doc = yyjson_read_opts(result.chars, result.length, 0, NULL, NULL); + if (doc) + { + yyjson_val* root = yyjson_doc_get_root(doc); + printf("%s (%s, %s)\n", + yyjson_get_str(yyjson_obj_get(root, "ip")), + yyjson_get_str(yyjson_obj_get(root, "city")), + yyjson_get_str(yyjson_obj_get(root, "country")) + ); + return; + } + } + + ffStrbufPutTo(&result, stdout); + } + else + { + ffPrintFormat(FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs, FF_PUBLICIP_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result} + }); + } +} + +void ffInitPublicIpOptions(FFPublicIpOptions* options) +{ + options->moduleName = FF_PUBLICIP_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + ffStrbufInit(&options->url); + options->timeout = 0; +} + +bool ffParsePublicIpCommandOptions(FFPublicIpOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_PUBLICIP_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffStrEqualsIgnCase(subKey, "url")) + { + ffOptionParseString(key, value, &options->url); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "timeout")) + { + options->timeout = ffOptionParseUInt32(key, value); + return true; + } + + return false; +} + +void ffDestroyPublicIpOptions(FFPublicIpOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + + ffStrbufDestroy(&options->url); +} + +void ffParsePublicIpJsonObject(yyjson_val* module) +{ + FFPublicIpOptions __attribute__((__cleanup__(ffDestroyPublicIpOptions))) options; + ffInitPublicIpOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (ffStrEqualsIgnCase(key, "url")) + { + ffStrbufSetS(&options.url, yyjson_get_str(val)); + continue; + } + + if (ffStrEqualsIgnCase(key, "timeout")) + { + options.timeout = (uint32_t) yyjson_get_uint(val); + continue; + } + + ffPrintError(FF_PUBLICIP_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintPublicIp(&options); +} diff --git a/src/modules/publicip/publicip.h b/src/modules/publicip/publicip.h new file mode 100644 index 0000000000..8328023f50 --- /dev/null +++ b/src/modules/publicip/publicip.h @@ -0,0 +1,13 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_PUBLICIP_MODULE_NAME "PublicIp" + +void ffPreparePublicIp(FFPublicIpOptions* options); + +void ffPrintPublicIp(FFPublicIpOptions* options); +void ffInitPublicIpOptions(FFPublicIpOptions* options); +bool ffParsePublicIpCommandOptions(FFPublicIpOptions* options, const char* key, const char* value); +void ffDestroyPublicIpOptions(FFPublicIpOptions* options); +void ffParsePublicIpJsonObject(yyjson_val* module); diff --git a/src/modules/separator.c b/src/modules/separator.c deleted file mode 100644 index 879bc5bb85..0000000000 --- a/src/modules/separator.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" - -void ffPrintSeparator(FFinstance* instance) -{ - uint32_t titleLength = instance->state.platform.userName.length + 1 + (instance->config.titleFQDN ? - instance->state.platform.domainName.length : - instance->state.platform.hostName.length - ); - - ffLogoPrintLine(instance); - - if(instance->config.separatorString.length == 0) - { - for(uint32_t i = 0; i < titleLength; i++) - putchar('-'); - } - else - { - //Write the whole separator as often as it fits fully into titleLength - for(uint32_t i = 0; i < titleLength / instance->config.separatorString.length; i++) - ffStrbufWriteTo(&instance->config.separatorString, stdout); - - //Write as much of the separator as needed to fill titleLength - for(uint32_t i = 0; i < titleLength % instance->config.separatorString.length; i++) - putchar(instance->config.separatorString.chars[i]); - } - putchar('\n'); -} diff --git a/src/modules/separator/option.h b/src/modules/separator/option.h new file mode 100644 index 0000000000..10f5effdf2 --- /dev/null +++ b/src/modules/separator/option.h @@ -0,0 +1,12 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFSeparatorOptions +{ + const char* moduleName; + + FFstrbuf string; +} FFSeparatorOptions; diff --git a/src/modules/separator/separator.c b/src/modules/separator/separator.c new file mode 100644 index 0000000000..a8d1d212c1 --- /dev/null +++ b/src/modules/separator/separator.c @@ -0,0 +1,129 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "modules/separator/separator.h" +#include "util/stringUtils.h" +#include "util/mallocHelper.h" +#include "util/wcwidth.h" + +static inline uint32_t max(uint32_t a, uint32_t b) +{ + return a > b ? a : b; +} + +static inline uint32_t getWcsWidth(const FFstrbuf* mbstr, wchar_t* wstr, mbstate_t* state) +{ + const char* str = mbstr->chars; + uint32_t wstrLength = (uint32_t) mbsrtowcs(wstr, &str, mbstr->length, state); + int result = mk_wcswidth(wstr, wstrLength); + return result > 0 ? (uint32_t) result : mbstr->length; +} + +void ffPrintSeparator(FFSeparatorOptions* options) +{ + mbstate_t state = {}; + bool fqdn = instance.config.title.fqdn; + const FFPlatform* platform = &instance.state.platform; + + FF_AUTO_FREE wchar_t* wstr = malloc((max( + platform->userName.length, options->string.length) + 1) * sizeof(*wstr)); + + uint32_t titleLength = 1 // @ + + getWcsWidth(&platform->userName, wstr, &state) // user name + + (fqdn ? platform->domainName.length : platform->hostName.length); // host name + ffLogoPrintLine(); + + if(options->string.length == 0) + { + ffPrintCharTimes('-', titleLength); + } + else + { + uint32_t wcsLength = getWcsWidth(&options->string, wstr, &state); + + int remaining = (int) titleLength; + //Write the whole separator as often as it fits fully into titleLength + for (; remaining >= (int) wcsLength; remaining -= (int) wcsLength) + ffStrbufWriteTo(&options->string, stdout); + + if (remaining > 0) + { + //Write as much of the separator as needed to fill titleLength + if (wcsLength != options->string.length) + { + // Unicode chars + for(int i = 0; remaining > 0; ++i) + { + #ifdef __linux__ + // https://stackoverflow.com/questions/75126743/i-have-difficulties-with-putwchar-in-c#answer-75137784 + char wch[16] = ""; + uint32_t wchLength = (uint32_t) wcrtomb(wch, wstr[i], &state); + fwrite(wch, wchLength, 1, stdout); + #else + putwchar(wstr[i]); + #endif + int width = mk_wcwidth(wstr[i]); + remaining -= width < 0 ? 0 : width; + } + } + else + { + for(int i = 0; i < remaining; i++) + putchar(options->string.chars[i]); + } + } + } + putchar('\n'); +} + +void ffInitSeparatorOptions(FFSeparatorOptions* options) +{ + options->moduleName = FF_SEPARATOR_MODULE_NAME; + ffStrbufInit(&options->string); +} + +bool ffParseSeparatorCommandOptions(FFSeparatorOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_SEPARATOR_MODULE_NAME); + if (!subKey) return false; + + if (ffStrEqualsIgnCase(subKey, "string")) + { + ffOptionParseString(key, value, &options->string); + return true; + } + + return false; +} + +void ffDestroySeparatorOptions(FFSeparatorOptions* options) +{ + ffStrbufDestroy(&options->string); +} + +void ffParseSeparatorJsonObject(yyjson_val* module) +{ + FFSeparatorOptions __attribute__((__cleanup__(ffDestroySeparatorOptions))) options; + ffInitSeparatorOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffStrEqualsIgnCase(key, "string")) + { + ffStrbufSetS(&options.string, yyjson_get_str(val)); + continue; + } + + ffPrintErrorString(FF_SEPARATOR_MODULE_NAME, 0, NULL, NULL, "Unknown JSON key %s", key); + } + } + + ffPrintSeparator(&options); +} diff --git a/src/modules/separator/separator.h b/src/modules/separator/separator.h new file mode 100644 index 0000000000..3e97ac4640 --- /dev/null +++ b/src/modules/separator/separator.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_SEPARATOR_MODULE_NAME "Separator" + +void ffPrintSeparator(FFSeparatorOptions* options); +void ffInitSeparatorOptions(FFSeparatorOptions* options); +bool ffParseSeparatorCommandOptions(FFSeparatorOptions* options, const char* key, const char* value); +void ffDestroySeparatorOptions(FFSeparatorOptions* options); +void ffParseSeparatorJsonObject(yyjson_val* module); diff --git a/src/modules/shell.c b/src/modules/shell.c deleted file mode 100644 index 607f5ec69c..0000000000 --- a/src/modules/shell.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/terminalshell/terminalshell.h" - -#define FF_SHELL_MODULE_NAME "Shell" -#define FF_SHELL_NUM_FORMAT_ARGS 7 - -void ffPrintShell(FFinstance* instance) -{ - const FFTerminalShellResult* result = ffDetectTerminalShell(instance); - - if(result->shellProcessName.length == 0) - { - ffPrintError(instance, FF_SHELL_MODULE_NAME, 0, &instance->config.shell, "Couldn't detect shell"); - return; - } - - if(instance->config.shell.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_SHELL_MODULE_NAME, 0, &instance->config.shell.key); - ffStrbufWriteTo(&result->shellPrettyName, stdout); - - if(result->shellVersion.length > 0) - { - putchar(' '); - ffStrbufWriteTo(&result->shellVersion, stdout); - } - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_SHELL_MODULE_NAME, 0, &instance->config.shell, FF_SHELL_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellProcessName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellExe}, - {FF_FORMAT_ARG_TYPE_STRING, result->shellExeName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellExe}, - {FF_FORMAT_ARG_TYPE_STRING, result->userShellExeName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellVersion} - }); - } -} diff --git a/src/modules/shell/option.h b/src/modules/shell/option.h new file mode 100644 index 0000000000..dd6223a366 --- /dev/null +++ b/src/modules/shell/option.h @@ -0,0 +1,13 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFShellOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + bool version; +} FFShellOptions; diff --git a/src/modules/shell/shell.c b/src/modules/shell/shell.c new file mode 100644 index 0000000000..efaca74410 --- /dev/null +++ b/src/modules/shell/shell.c @@ -0,0 +1,90 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/terminalshell/terminalshell.h" +#include "modules/shell/shell.h" +#include "util/stringUtils.h" + +#define FF_SHELL_NUM_FORMAT_ARGS 7 + +void ffPrintShell(FFShellOptions* options) +{ + const FFTerminalShellResult* result = ffDetectTerminalShell(); + + if(result->shellProcessName.length == 0) + { + ffPrintError(FF_SHELL_MODULE_NAME, 0, &options->moduleArgs, "Couldn't detect shell"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_SHELL_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufWriteTo(&result->shellPrettyName, stdout); + + if(result->shellVersion.length > 0) + { + putchar(' '); + ffStrbufWriteTo(&result->shellVersion, stdout); + } + + putchar('\n'); + } + else + { + ffPrintFormat(FF_SHELL_MODULE_NAME, 0, &options->moduleArgs, FF_SHELL_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellProcessName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellExe}, + {FF_FORMAT_ARG_TYPE_STRING, result->shellExeName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellExe}, + {FF_FORMAT_ARG_TYPE_STRING, result->userShellExeName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellVersion} + }); + } +} + +void ffInitShellOptions(FFShellOptions* options) +{ + options->moduleName = FF_SHELL_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseShellCommandOptions(FFShellOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_SHELL_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyShellOptions(FFShellOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseShellJsonObject(yyjson_val* module) +{ + FFShellOptions __attribute__((__cleanup__(ffDestroyShellOptions))) options; + ffInitShellOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_SHELL_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintShell(&options); +} diff --git a/src/modules/shell/shell.h b/src/modules/shell/shell.h new file mode 100644 index 0000000000..b2579cd49d --- /dev/null +++ b/src/modules/shell/shell.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_SHELL_MODULE_NAME "Shell" + +void ffPrintShell(FFShellOptions* options); +void ffInitShellOptions(FFShellOptions* options); +bool ffParseShellCommandOptions(FFShellOptions* options, const char* key, const char* value); +void ffDestroyShellOptions(FFShellOptions* options); +void ffParseShellJsonObject(yyjson_val* module); diff --git a/src/modules/sound.c b/src/modules/sound.c deleted file mode 100644 index ffc4aee76d..0000000000 --- a/src/modules/sound.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "common/printing.h" -#include "detection/sound/sound.h" - -#define FF_SOUND_MODULE_NAME "Sound" -#define FF_SOUND_NUM_FORMAT_ARGS 4 - -static void printDevice(FFinstance* instance, const FFSoundDevice* device, uint8_t index) -{ - if(instance->config.sound.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_SOUND_MODULE_NAME, index, &instance->config.sound.key); - ffStrbufWriteTo(&device->name, stdout); - - if(device->volume != FF_SOUND_VOLUME_UNKNOWN) - { - if(device->volume > 0) - printf(" (%d%%)", device->volume); - else - fputs(" (muted)", stdout); - } - - if(device->main && index > 0) - fputs(" (*)", stdout); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_SOUND_MODULE_NAME, index, &instance->config.sound, FF_SOUND_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_BOOL, &device->main}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, - {FF_FORMAT_ARG_TYPE_UINT8, &device->volume}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->identifier} - }); - } -} - -static void printSound(FFinstance* instance, FFlist* devices) -{ - FF_LIST_AUTO_DESTROY filtered; - ffListInit(&filtered, sizeof(FFSoundDevice*)); - - FF_LIST_FOR_EACH(FFSoundDevice, device, *devices) - { - switch (instance->config.soundType) - { - case FF_SOUND_TYPE_MAIN: if (!device->main) continue; break; - case FF_SOUND_TYPE_ACTIVE: if (!device->active) continue; break; - case FF_SOUND_TYPE_ALL: break; - } - - *(FFSoundDevice**)ffListAdd(&filtered) = device; - } - - if(filtered.length == 0) - { - ffPrintError(instance, FF_SOUND_MODULE_NAME, 0, &instance->config.sound, "No active sound devices found"); - return; - } - - uint8_t index = 1; - FF_LIST_FOR_EACH(FFSoundDevice*, device, filtered) - printDevice(instance, *device, filtered.length == 1 ? 0 : index++); -} - -void ffPrintSound(FFinstance* instance) -{ - FF_LIST_AUTO_DESTROY result; - ffListInit(&result, sizeof(FFSoundDevice)); - const char* error = ffDetectSound(instance, &result); - - if(error) - { - ffPrintError(instance, FF_SOUND_MODULE_NAME, 0, &instance->config.sound, "%s", error); - return; - } - - printSound(instance, &result); - - FF_LIST_FOR_EACH(FFSoundDevice, device, result) - { - ffStrbufDestroy(&device->identifier); - ffStrbufDestroy(&device->name); - } -} diff --git a/src/modules/sound/option.h b/src/modules/sound/option.h new file mode 100644 index 0000000000..b0586036bb --- /dev/null +++ b/src/modules/sound/option.h @@ -0,0 +1,20 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFSoundType +{ + FF_SOUND_TYPE_MAIN, + FF_SOUND_TYPE_ACTIVE, + FF_SOUND_TYPE_ALL, +} FFSoundType; + +typedef struct FFSoundOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFSoundType soundType; +} FFSoundOptions; diff --git a/src/modules/sound/sound.c b/src/modules/sound/sound.c new file mode 100644 index 0000000000..2955c8f5b1 --- /dev/null +++ b/src/modules/sound/sound.c @@ -0,0 +1,159 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/sound/sound.h" +#include "modules/sound/sound.h" +#include "util/stringUtils.h" + +#define FF_SOUND_NUM_FORMAT_ARGS 4 + +static void printDevice(FFSoundOptions* options, const FFSoundDevice* device, uint8_t index) +{ + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_SOUND_MODULE_NAME, index, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufWriteTo(&device->name, stdout); + + if(device->volume != FF_SOUND_VOLUME_UNKNOWN) + { + if(device->volume > 0) + printf(" (%d%%)", device->volume); + else + fputs(" (muted)", stdout); + } + + if(device->main && index > 0) + fputs(" (*)", stdout); + + putchar('\n'); + } + else + { + ffPrintFormat(FF_SOUND_MODULE_NAME, index, &options->moduleArgs, FF_SOUND_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_BOOL, &device->main}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, + {FF_FORMAT_ARG_TYPE_UINT8, &device->volume}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->identifier} + }); + } +} + +void ffPrintSound(FFSoundOptions* options) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFSoundDevice)); + + const char* error = ffDetectSound(&result); + + if(error) + { + ffPrintError(FF_SOUND_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + FF_LIST_AUTO_DESTROY filtered = ffListCreate(sizeof(FFSoundDevice*)); + + FF_LIST_FOR_EACH(FFSoundDevice, device, result) + { + switch (options->soundType) + { + case FF_SOUND_TYPE_MAIN: if (!device->main) continue; break; + case FF_SOUND_TYPE_ACTIVE: if (!device->active) continue; break; + case FF_SOUND_TYPE_ALL: break; + } + + *(FFSoundDevice**)ffListAdd(&filtered) = device; + } + + if(filtered.length == 0) + { + ffPrintError(FF_SOUND_MODULE_NAME, 0, &options->moduleArgs, "No active sound devices found"); + return; + } + + uint8_t index = 1; + FF_LIST_FOR_EACH(FFSoundDevice*, device, filtered) + { + printDevice(options, *device, filtered.length == 1 ? 0 : index++); + } + + FF_LIST_FOR_EACH(FFSoundDevice, device, result) + { + ffStrbufDestroy(&device->identifier); + ffStrbufDestroy(&device->name); + } +} + + +void ffInitSoundOptions(FFSoundOptions* options) +{ + options->moduleName = FF_SOUND_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + options->soundType = FF_SOUND_TYPE_MAIN; +} + +bool ffParseSoundCommandOptions(FFSoundOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_SOUND_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffStrEqualsIgnCase(subKey, "sound-type")) + { + options->soundType = (FFSoundType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "main", FF_SOUND_TYPE_MAIN }, + { "active", FF_SOUND_TYPE_ACTIVE }, + { "all", FF_SOUND_TYPE_ALL }, + {}, + }); + return true; + } + + return false; +} + +void ffDestroySoundOptions(FFSoundOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseSoundJsonObject(yyjson_val* module) +{ + FFSoundOptions __attribute__((__cleanup__(ffDestroySoundOptions))) options; + ffInitSoundOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (ffStrEqualsIgnCase(key, "soundType")) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "main", FF_SOUND_TYPE_MAIN }, + { "active", FF_SOUND_TYPE_ACTIVE }, + { "all", FF_SOUND_TYPE_ALL }, + {}, + }); + if (error) + ffPrintError(FF_SOUND_MODULE_NAME, 0, &options.moduleArgs, "Invalid %s value: %s", key, error); + else + options.soundType = (FFSoundType) value; + continue; + } + + ffPrintError(FF_SOUND_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintSound(&options); +} diff --git a/src/modules/sound/sound.h b/src/modules/sound/sound.h new file mode 100644 index 0000000000..4b02f4d24a --- /dev/null +++ b/src/modules/sound/sound.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_SOUND_MODULE_NAME "Sound" + +void ffPrintSound(FFSoundOptions* options); +void ffInitSoundOptions(FFSoundOptions* options); +bool ffParseSoundCommandOptions(FFSoundOptions* options, const char* key, const char* value); +void ffDestroySoundOptions(FFSoundOptions* options); +void ffParseSoundJsonObject(yyjson_val* module); diff --git a/src/modules/swap.c b/src/modules/swap.c deleted file mode 100644 index 1f6175b15c..0000000000 --- a/src/modules/swap.c +++ /dev/null @@ -1,67 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/parsing.h" -#include "common/bar.h" -#include "detection/swap/swap.h" - -#define FF_SWAP_MODULE_NAME "Swap" -#define FF_SWAP_NUM_FORMAT_ARGS 3 - -void ffPrintSwap(FFinstance* instance) -{ - FFSwapResult storage; - const char* error = ffDetectSwap(&storage); - - if(error) - { - ffPrintError(instance, FF_SWAP_MODULE_NAME, 0, &instance->config.swap, "%s", error); - return; - } - - FF_STRBUF_AUTO_DESTROY usedPretty; - ffStrbufInit(&usedPretty); - ffParseSize(storage.bytesUsed, instance->config.binaryPrefixType, &usedPretty); - - FF_STRBUF_AUTO_DESTROY totalPretty; - ffStrbufInit(&totalPretty); - ffParseSize(storage.bytesTotal, instance->config.binaryPrefixType, &totalPretty); - - uint8_t percentage = storage.bytesTotal == 0 - ? 0 - : (uint8_t) (((long double) storage.bytesUsed / (long double) storage.bytesTotal) * 100.0); - - if(instance->config.swap.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_SWAP_MODULE_NAME, 0, &instance->config.swap.key); - if (storage.bytesTotal == 0) - puts("Disabled"); - else - { - FF_STRBUF_AUTO_DESTROY str; - ffStrbufInit(&str); - - if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) - { - ffAppendPercentBar(instance, &str, percentage, 0, 5, 8); - ffStrbufAppendC(&str, ' '); - } - - if(!(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) - ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); - - if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) - ffAppendPercentNum(instance, &str, (uint8_t) percentage, 50, 80, str.length > 0); - - ffStrbufTrimRight(&str, ' '); - ffStrbufPutTo(&str, stdout); - } - } - else - { - ffPrintFormat(instance, FF_SWAP_MODULE_NAME, 0, &instance->config.swap, FF_SWAP_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, - }); - } -} diff --git a/src/modules/swap/option.h b/src/modules/swap/option.h new file mode 100644 index 0000000000..4053cfbe10 --- /dev/null +++ b/src/modules/swap/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFSwapOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFSwapOptions; diff --git a/src/modules/swap/swap.c b/src/modules/swap/swap.c new file mode 100644 index 0000000000..5f13b286e0 --- /dev/null +++ b/src/modules/swap/swap.c @@ -0,0 +1,111 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/parsing.h" +#include "common/bar.h" +#include "detection/swap/swap.h" +#include "modules/swap/swap.h" +#include "util/stringUtils.h" + +#define FF_SWAP_NUM_FORMAT_ARGS 3 + +void ffPrintSwap(FFSwapOptions* options) +{ + FFSwapResult storage; + const char* error = ffDetectSwap(&storage); + + if(error) + { + ffPrintError(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate(); + ffParseSize(storage.bytesUsed, &usedPretty); + + FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate(); + ffParseSize(storage.bytesTotal, &totalPretty); + + uint8_t percentage = storage.bytesTotal == 0 + ? 0 + : (uint8_t) (((long double) storage.bytesUsed / (long double) storage.bytesTotal) * 100.0); + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + if (storage.bytesTotal == 0) + puts("Disabled"); + else + { + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + + if(instance.config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffAppendPercentBar(&str, percentage, 0, 5, 8); + ffStrbufAppendC(&str, ' '); + } + + if(!(instance.config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); + + if(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffAppendPercentNum(&str, (uint8_t) percentage, 50, 80, str.length > 0); + + ffStrbufTrimRight(&str, ' '); + ffStrbufPutTo(&str, stdout); + } + } + else + { + ffPrintFormat(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_SWAP_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, + {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, + }); + } +} + +void ffInitSwapOptions(FFSwapOptions* options) +{ + options->moduleName = FF_SWAP_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseSwapCommandOptions(FFSwapOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_SWAP_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroySwapOptions(FFSwapOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseSwapJsonObject(yyjson_val* module) +{ + FFSwapOptions __attribute__((__cleanup__(ffDestroySwapOptions))) options; + ffInitSwapOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_SWAP_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintSwap(&options); +} diff --git a/src/modules/swap/swap.h b/src/modules/swap/swap.h new file mode 100644 index 0000000000..3cd4f5b14e --- /dev/null +++ b/src/modules/swap/swap.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_SWAP_MODULE_NAME "Swap" + +void ffPrintSwap(FFSwapOptions* options); +void ffInitSwapOptions(FFSwapOptions* options); +bool ffParseSwapCommandOptions(FFSwapOptions* options, const char* key, const char* value); +void ffDestroySwapOptions(FFSwapOptions* options); +void ffParseSwapJsonObject(yyjson_val* module); diff --git a/src/modules/terminal.c b/src/modules/terminal.c deleted file mode 100644 index 28e8d14a5b..0000000000 --- a/src/modules/terminal.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/terminalshell/terminalshell.h" - -#include - -#define FF_TERMINAL_MODULE_NAME "Terminal" -#define FF_TERMINAL_NUM_FORMAT_ARGS 10 - -void ffPrintTerminal(FFinstance* instance) -{ - const FFTerminalShellResult* result = ffDetectTerminalShell(instance); - - if(result->terminalProcessName.length == 0) - { - ffPrintError(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminal, "Couldn't detect terminal"); - return; - } - - if(instance->config.terminal.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminal.key); - - if(result->terminalVersion.length) - printf("%s %s\n", result->terminalPrettyName.chars, result->terminalVersion.chars); - else - ffStrbufPutTo(&result->terminalPrettyName, stdout); - } - else - { - ffPrintFormat(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminal, FF_TERMINAL_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalProcessName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalExe}, - {FF_FORMAT_ARG_TYPE_STRING, result->terminalExeName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellProcessName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellExe}, - {FF_FORMAT_ARG_TYPE_STRING, result->shellExeName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellExe}, - {FF_FORMAT_ARG_TYPE_STRING, result->userShellExeName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellVersion} - }); - } -} diff --git a/src/modules/terminal/option.h b/src/modules/terminal/option.h new file mode 100644 index 0000000000..151129e130 --- /dev/null +++ b/src/modules/terminal/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFTerminalOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFTerminalOptions; diff --git a/src/modules/terminal/terminal.c b/src/modules/terminal/terminal.c new file mode 100644 index 0000000000..315ede3bcc --- /dev/null +++ b/src/modules/terminal/terminal.c @@ -0,0 +1,91 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/terminalshell/terminalshell.h" +#include "modules/terminal/terminal.h" +#include "util/stringUtils.h" + +#include + +#define FF_TERMINAL_NUM_FORMAT_ARGS 10 + +void ffPrintTerminal(FFTerminalOptions* options) +{ + const FFTerminalShellResult* result = ffDetectTerminalShell(); + + if(result->terminalProcessName.length == 0) + { + ffPrintError(FF_TERMINAL_MODULE_NAME, 0, &options->moduleArgs, "Couldn't detect terminal"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_TERMINAL_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + if(result->terminalVersion.length) + printf("%s %s\n", result->terminalPrettyName.chars, result->terminalVersion.chars); + else + ffStrbufPutTo(&result->terminalPrettyName, stdout); + } + else + { + ffPrintFormat(FF_TERMINAL_MODULE_NAME, 0, &options->moduleArgs, FF_TERMINAL_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalProcessName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalExe}, + {FF_FORMAT_ARG_TYPE_STRING, result->terminalExeName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellProcessName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellExe}, + {FF_FORMAT_ARG_TYPE_STRING, result->shellExeName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellExe}, + {FF_FORMAT_ARG_TYPE_STRING, result->userShellExeName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellVersion} + }); + } +} + +void ffInitTerminalOptions(FFTerminalOptions* options) +{ + options->moduleName = FF_TERMINAL_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseTerminalCommandOptions(FFTerminalOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_TERMINAL_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyTerminalOptions(FFTerminalOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseTerminalJsonObject(yyjson_val* module) +{ + FFTerminalOptions __attribute__((__cleanup__(ffDestroyTerminalOptions))) options; + ffInitTerminalOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_TERMINAL_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintTerminal(&options); +} diff --git a/src/modules/terminal/terminal.h b/src/modules/terminal/terminal.h new file mode 100644 index 0000000000..45372754dc --- /dev/null +++ b/src/modules/terminal/terminal.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_TERMINAL_MODULE_NAME "Terminal" + +void ffPrintTerminal(FFTerminalOptions* options); +void ffInitTerminalOptions(FFTerminalOptions* options); +bool ffParseTerminalCommandOptions(FFTerminalOptions* options, const char* key, const char* value); +void ffDestroyTerminalOptions(FFTerminalOptions* options); +void ffParseTerminalJsonObject(yyjson_val* module); diff --git a/src/modules/terminalfont.c b/src/modules/terminalfont.c deleted file mode 100644 index 1809c4f390..0000000000 --- a/src/modules/terminalfont.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/terminalfont/terminalfont.h" - -#define FF_TERMFONT_MODULE_NAME "Terminal Font" -#define FF_TERMFONT_NUM_FORMAT_ARGS 4 - -void ffPrintTerminalFont(FFinstance* instance) -{ - const FFTerminalFontResult* terminalFont = ffDetectTerminalFont(instance); - - if(terminalFont->error.length > 0) - { - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "%s", terminalFont->error.chars); - return; - } - - if(instance->config.terminalFont.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont.key); - ffStrbufPutTo(&terminalFont->font.pretty, stdout); - } - else - { - ffPrintFormat(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, FF_TERMFONT_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.pretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.size}, - {FF_FORMAT_ARG_TYPE_LIST, &terminalFont->font.styles} - }); - } -} diff --git a/src/modules/terminalfont/option.h b/src/modules/terminalfont/option.h new file mode 100644 index 0000000000..ba62efbb5e --- /dev/null +++ b/src/modules/terminalfont/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFTerminalFontOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFTerminalFontOptions; diff --git a/src/modules/terminalfont/terminalfont.c b/src/modules/terminalfont/terminalfont.c new file mode 100644 index 0000000000..9e9b683d87 --- /dev/null +++ b/src/modules/terminalfont/terminalfont.c @@ -0,0 +1,94 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/terminalfont/terminalfont.h" +#include "modules/terminalfont/terminalfont.h" +#include "util/stringUtils.h" + +#define FF_TERMINALFONT_DISPLAY_NAME "Terminal Font" +#define FF_TERMINALFONT_NUM_FORMAT_ARGS 4 + +void ffPrintTerminalFont(FFTerminalFontOptions* options) +{ + FFTerminalFontResult terminalFont; + ffFontInit(&terminalFont.font); + ffFontInit(&terminalFont.fallback); + ffStrbufInit(&terminalFont.error); + + if(!ffDetectTerminalFont(&terminalFont)) + { + ffPrintError(FF_TERMINALFONT_DISPLAY_NAME, 0, &options->moduleArgs, "%s", terminalFont.error.chars); + } + else + { + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_TERMINALFONT_DISPLAY_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufWriteTo(&terminalFont.font.pretty, stdout); + if(terminalFont.fallback.pretty.length) + { + fputs(" / ", stdout); + ffStrbufWriteTo(&terminalFont.fallback.pretty, stdout); + } + putchar('\n'); + } + else + { + ffPrintFormat(FF_TERMINALFONT_DISPLAY_NAME, 0, &options->moduleArgs, FF_TERMINALFONT_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont.font.pretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont.font.name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont.font.size}, + {FF_FORMAT_ARG_TYPE_LIST, &terminalFont.font.styles} + }); + } + } + + ffStrbufDestroy(&terminalFont.error); + ffFontDestroy(&terminalFont.font); + ffFontDestroy(&terminalFont.fallback); +} + +void ffInitTerminalFontOptions(FFTerminalFontOptions* options) +{ + options->moduleName = FF_TERMINALFONT_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseTerminalFontCommandOptions(FFTerminalFontOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_TERMINALFONT_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyTerminalFontOptions(FFTerminalFontOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseTerminalFontJsonObject(yyjson_val* module) +{ + FFTerminalFontOptions __attribute__((__cleanup__(ffDestroyTerminalFontOptions))) options; + ffInitTerminalFontOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_TERMINALFONT_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintTerminalFont(&options); +} diff --git a/src/modules/terminalfont/terminalfont.h b/src/modules/terminalfont/terminalfont.h new file mode 100644 index 0000000000..a538cd0d7e --- /dev/null +++ b/src/modules/terminalfont/terminalfont.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_TERMINALFONT_MODULE_NAME "TerminalFont" + +void ffPrintTerminalFont(FFTerminalFontOptions* options); +void ffInitTerminalFontOptions(FFTerminalFontOptions* options); +bool ffParseTerminalFontCommandOptions(FFTerminalFontOptions* options, const char* key, const char* value); +void ffDestroyTerminalFontOptions(FFTerminalFontOptions* options); +void ffParseTerminalFontJsonObject(yyjson_val* module); diff --git a/src/modules/terminalsize/option.h b/src/modules/terminalsize/option.h new file mode 100644 index 0000000000..16f4824665 --- /dev/null +++ b/src/modules/terminalsize/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFTerminalSizeOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFTerminalSizeOptions; diff --git a/src/modules/terminalsize/terminalsize.c b/src/modules/terminalsize/terminalsize.c new file mode 100644 index 0000000000..e33966eb56 --- /dev/null +++ b/src/modules/terminalsize/terminalsize.c @@ -0,0 +1,86 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/terminalsize/terminalsize.h" +#include "modules/terminalsize/terminalsize.h" +#include "util/stringUtils.h" + +#define FF_TERMINALSIZE_DISPLAY_NAME "Terminal Size" +#define FF_TERMINALSIZE_NUM_FORMAT_ARGS 4 + +void ffPrintTerminalSize(FFTerminalSizeOptions* options) +{ + FFTerminalSizeResult result = {}; + + if(!ffDetectTerminalSize(&result)) + { + ffPrintError(FF_TERMINALSIZE_DISPLAY_NAME, 0, &options->moduleArgs, "Failed to detect terminal size"); + } + else + { + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_TERMINALSIZE_DISPLAY_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + printf("%u columns x %u rows", result.columns, result.rows); + + if (result.width != 0 && result.height != 0) + printf(" (%upx x %upx)", result.width, result.height); + + putchar('\n'); + } + else + { + ffPrintFormat(FF_TERMINALSIZE_DISPLAY_NAME, 0, &options->moduleArgs, FF_TERMINALSIZE_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT16, &result.rows}, + {FF_FORMAT_ARG_TYPE_UINT16, &result.columns}, + {FF_FORMAT_ARG_TYPE_UINT16, &result.width}, + {FF_FORMAT_ARG_TYPE_UINT16, &result.height} + }); + } + } +} + +void ffInitTerminalSizeOptions(FFTerminalSizeOptions* options) +{ + options->moduleName = FF_TERMINALSIZE_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseTerminalSizeCommandOptions(FFTerminalSizeOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_TERMINALSIZE_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyTerminalSizeOptions(FFTerminalSizeOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseTerminalSizeJsonObject(yyjson_val* module) +{ + FFTerminalSizeOptions __attribute__((__cleanup__(ffDestroyTerminalSizeOptions))) options; + ffInitTerminalSizeOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_TERMINALSIZE_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintTerminalSize(&options); +} diff --git a/src/modules/terminalsize/terminalsize.h b/src/modules/terminalsize/terminalsize.h new file mode 100644 index 0000000000..0b1b37d32a --- /dev/null +++ b/src/modules/terminalsize/terminalsize.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_TERMINALSIZE_MODULE_NAME "TerminalSize" + +void ffPrintTerminalSize(FFTerminalSizeOptions* options); +void ffInitTerminalSizeOptions(FFTerminalSizeOptions* options); +bool ffParseTerminalSizeCommandOptions(FFTerminalSizeOptions* options, const char* key, const char* value); +void ffDestroyTerminalSizeOptions(FFTerminalSizeOptions* options); +void ffParseTerminalSizeJsonObject(yyjson_val* module); diff --git a/src/modules/theme.c b/src/modules/theme.c deleted file mode 100644 index b89f093d4f..0000000000 --- a/src/modules/theme.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/theme/theme.h" - -#define FF_THEME_MODULE_NAME "Theme" -#define FF_THEME_NUM_FORMAT_ARGS 1 - -void ffPrintTheme(FFinstance* instance) -{ - FF_STRBUF_AUTO_DESTROY theme; - ffStrbufInit(&theme); - const char* error = ffDetectTheme(instance, &theme); - if (error) - { - ffPrintError(instance, FF_THEME_MODULE_NAME, 0, &instance->config.theme, "%s", error); - return; - } - - if(instance->config.theme.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_THEME_MODULE_NAME, 0, &instance->config.theme.key); - ffStrbufPutTo(&theme, stdout); - } - else - { - ffPrintFormat(instance, FF_THEME_MODULE_NAME, 0, &instance->config.theme, FF_THEME_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &theme} - }); - } -} diff --git a/src/modules/theme/option.h b/src/modules/theme/option.h new file mode 100644 index 0000000000..f322c3a62d --- /dev/null +++ b/src/modules/theme/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFThemeOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFThemeOptions; diff --git a/src/modules/theme/theme.c b/src/modules/theme/theme.c new file mode 100644 index 0000000000..741e47c724 --- /dev/null +++ b/src/modules/theme/theme.c @@ -0,0 +1,77 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/theme/theme.h" +#include "modules/theme/theme.h" +#include "util/stringUtils.h" + +#define FF_THEME_NUM_FORMAT_ARGS 1 + +void ffPrintTheme(FFThemeOptions* options) +{ + FF_STRBUF_AUTO_DESTROY theme = ffStrbufCreate(); + const char* error = ffDetectTheme(&theme); + + if(error) + { + ffPrintError(FF_THEME_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_THEME_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufPutTo(&theme, stdout); + } + else + { + ffPrintFormat(FF_THEME_MODULE_NAME, 0, &options->moduleArgs, FF_THEME_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &theme} + }); + } +} + +void ffInitThemeOptions(FFThemeOptions* options) +{ + options->moduleName = FF_THEME_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseThemeCommandOptions(FFThemeOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_THEME_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyThemeOptions(FFThemeOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseThemeJsonObject(yyjson_val* module) +{ + FFThemeOptions __attribute__((__cleanup__(ffDestroyThemeOptions))) options; + ffInitThemeOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_THEME_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintTheme(&options); +} diff --git a/src/modules/theme/theme.h b/src/modules/theme/theme.h new file mode 100644 index 0000000000..37a006dd48 --- /dev/null +++ b/src/modules/theme/theme.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_THEME_MODULE_NAME "Theme" + +void ffPrintTheme(FFThemeOptions* options); +void ffInitThemeOptions(FFThemeOptions* options); +bool ffParseThemeCommandOptions(FFThemeOptions* options, const char* key, const char* value); +void ffDestroyThemeOptions(FFThemeOptions* options); +void ffParseThemeJsonObject(yyjson_val* module); diff --git a/src/modules/time.c b/src/modules/time.c deleted file mode 100644 index 523e4fa19e..0000000000 --- a/src/modules/time.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/datetime/datetime.h" - -#define FF_TIME_MODULE_NAME "Time" - -void ffPrintTime(FFinstance* instance) -{ - if(instance->config.time.outputFormat.length > 0) - { - ffPrintDateTimeFormat(instance, FF_TIME_MODULE_NAME, &instance->config.time); - return; - } - - const FFDateTimeResult* datetime = ffDetectDateTime(instance); - ffPrintLogoAndKey(instance, FF_TIME_MODULE_NAME, 0, &instance->config.time.key); - - //hh:mm:ss - printf("%s:%s:%s\n", datetime->hourPretty.chars, datetime->minutePretty.chars, datetime->secondPretty.chars); -} diff --git a/src/modules/title.c b/src/modules/title.c deleted file mode 100644 index 4e509fbe51..0000000000 --- a/src/modules/title.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "util/textModifier.h" - -static inline void printTitlePart(FFinstance* instance, const FFstrbuf* content) -{ - if(!instance->config.pipe) - { - fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); - ffPrintColor(&instance->config.colorTitle); - } - - ffStrbufWriteTo(content, stdout); - - if(!instance->config.pipe) - fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); -} - -void ffPrintTitle(FFinstance* instance) -{ - ffLogoPrintLine(instance); - - printTitlePart(instance, &instance->state.platform.userName); - putchar('@'); - printTitlePart(instance, instance->config.titleFQDN ? - &instance->state.platform.domainName : - &instance->state.platform.hostName - ); - putchar('\n'); -} diff --git a/src/modules/title/option.h b/src/modules/title/option.h new file mode 100644 index 0000000000..b44aef8ed5 --- /dev/null +++ b/src/modules/title/option.h @@ -0,0 +1,16 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFTitleOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + bool fqdn; + FFstrbuf colorUser; + FFstrbuf colorAt; + FFstrbuf colorHost; +} FFTitleOptions; diff --git a/src/modules/title/title.c b/src/modules/title/title.c new file mode 100644 index 0000000000..ef3d7abe46 --- /dev/null +++ b/src/modules/title/title.c @@ -0,0 +1,150 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "modules/title/title.h" +#include "util/textModifier.h" +#include "util/stringUtils.h" + +#define FF_TITLE_NUM_FORMAT_ARGS 2 + +static inline void printTitlePart(const FFstrbuf* content, const FFstrbuf* color) +{ + if(!instance.config.pipe) + { + if (instance.config.brightColor) + fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); + ffPrintColor(color->length > 0 ? color : &instance.config.colorTitle); + } + + ffStrbufWriteTo(content, stdout); + + if(!instance.config.pipe) + fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); +} + +void ffPrintTitle(FFTitleOptions* options) +{ + FFstrbuf* host = options->fqdn ? + &instance.state.platform.domainName : + &instance.state.platform.hostName; + + if (options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(options->moduleArgs.key.length == 0 ? NULL : FF_TITLE_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + printTitlePart(&instance.state.platform.userName, &options->colorUser); + + if (!instance.config.pipe && options->colorAt.length > 0) + ffPrintColor(&options->colorAt); + putchar('@'); + + printTitlePart(host, &options->colorHost); + putchar('\n'); + } + else + { + ffPrintFormat(FF_TITLE_MODULE_NAME, 0, &options->moduleArgs, FF_TITLE_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.userName}, + {FF_FORMAT_ARG_TYPE_STRBUF, host}, + }); + } +} + +void ffInitTitleOptions(FFTitleOptions* options) +{ + options->moduleName = FF_TITLE_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + options->fqdn = false; + ffStrbufInit(&options->colorUser); + ffStrbufInit(&options->colorAt); + ffStrbufInit(&options->colorHost); +} + +bool ffParseTitleCommandOptions(FFTitleOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_TITLE_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffStrEqualsIgnCase(subKey, "fqdn")) + { + options->fqdn = ffOptionParseBoolean(value); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "color-user")) + { + ffOptionParseColor(value, &options->colorUser); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "color-at")) + { + ffOptionParseColor(value, &options->colorAt); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "color-host")) + { + ffOptionParseColor(value, &options->colorHost); + return true; + } + + return false; +} + +void ffDestroyTitleOptions(FFTitleOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + ffStrbufDestroy(&options->colorUser); + ffStrbufDestroy(&options->colorAt); + ffStrbufDestroy(&options->colorHost); +} + +void ffParseTitleJsonObject(yyjson_val* module) +{ + FFTitleOptions __attribute__((__cleanup__(ffDestroyTitleOptions))) options; + ffInitTitleOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (ffStrEqualsIgnCase(key, "fqdn")) + { + options.fqdn = yyjson_get_bool(val); + continue; + } + + if (ffStrEqualsIgnCase(key, "color")) + { + if (!yyjson_is_obj(val)) + continue; + + yyjson_val* color = yyjson_obj_get(val, "user"); + if (color) + ffOptionParseColor(yyjson_get_str(color), &options.colorUser); + color = yyjson_obj_get(val, "at"); + if (color) + ffOptionParseColor(yyjson_get_str(color), &options.colorAt); + color = yyjson_obj_get(val, "host"); + if (color) + ffOptionParseColor(yyjson_get_str(color), &options.colorHost); + continue; + } + + ffPrintErrorString(FF_TITLE_MODULE_NAME, 0, NULL, NULL, "Unknown JSON key %s", key); + } + } + + ffPrintTitle(&options); +} diff --git a/src/modules/title/title.h b/src/modules/title/title.h new file mode 100644 index 0000000000..7bd4072435 --- /dev/null +++ b/src/modules/title/title.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_TITLE_MODULE_NAME "Title" + +void ffPrintTitle(FFTitleOptions* options); +void ffInitTitleOptions(FFTitleOptions* options); +bool ffParseTitleCommandOptions(FFTitleOptions* options, const char* key, const char* value); +void ffDestroyTitleOptions(FFTitleOptions* options); +void ffParseTitleJsonObject(yyjson_val* module); diff --git a/src/modules/uptime.c b/src/modules/uptime.c deleted file mode 100644 index 48d2b4f4a9..0000000000 --- a/src/modules/uptime.c +++ /dev/null @@ -1,77 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#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 = ffDetectUptime(); - - if(uptime == 0) - { - ffPrintError(instance, FF_UPTIME_MODULE_NAME, 0, &instance->config.uptime, "Uptime could't be detected"); - return; - } - - uint32_t days = (uint32_t) uptime / 86400; - uint32_t hours = (uint32_t) (uptime - (days * 86400)) / 3600; - uint32_t minutes = (uint32_t) (uptime - (days * 86400) - (hours * 3600)) / 60; - uint32_t seconds = (uint32_t) uptime - (days * 86400) - (hours * 3600) - (minutes * 60); - - if(instance->config.uptime.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_UPTIME_MODULE_NAME, 0, &instance->config.uptime.key); - - if(days == 0 && hours == 0 && minutes == 0) - { - printf("%u seconds\n", seconds); - return; - } - - if(days > 0) - { - printf("%u day", days); - - if(days > 1) - putchar('s'); - - if(days >= 100) - fputs("(!)", stdout); - - if(hours > 0 || minutes > 0) - fputs(", ", stdout); - } - - if(hours > 0) - { - printf("%u hour", hours); - - if(hours > 1) - putchar('s'); - - if(minutes > 0) - fputs(", ", stdout); - } - - if(minutes > 0) - { - printf("%u min", minutes); - - if(minutes > 1) - putchar('s'); - } - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_UPTIME_MODULE_NAME, 0, &instance->config.uptime, FF_UPTIME_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_UINT, &days}, - {FF_FORMAT_ARG_TYPE_UINT, &hours}, - {FF_FORMAT_ARG_TYPE_UINT, &minutes}, - {FF_FORMAT_ARG_TYPE_UINT, &seconds} - }); - } -} diff --git a/src/modules/uptime/option.h b/src/modules/uptime/option.h new file mode 100644 index 0000000000..722d236d3f --- /dev/null +++ b/src/modules/uptime/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFUptimeOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFUptimeOptions; diff --git a/src/modules/uptime/uptime.c b/src/modules/uptime/uptime.c new file mode 100644 index 0000000000..f6a4bd424d --- /dev/null +++ b/src/modules/uptime/uptime.c @@ -0,0 +1,126 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/uptime/uptime.h" +#include "modules/uptime/uptime.h" +#include "util/stringUtils.h" + +#define FF_UPTIME_NUM_FORMAT_ARGS 4 + +void ffPrintUptime(FFUptimeOptions* options) +{ + uint64_t uptime; + + const char* error = ffDetectUptime(&uptime); + + if(error) + { + ffPrintError(FF_UPTIME_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + uint32_t days = (uint32_t) uptime / 86400; + uint32_t hours = (uint32_t) (uptime - (days * 86400)) / 3600; + uint32_t minutes = (uint32_t) (uptime - (days * 86400) - (hours * 3600)) / 60; + uint32_t seconds = (uint32_t) uptime - (days * 86400) - (hours * 3600) - (minutes * 60); + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_UPTIME_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + if(days == 0 && hours == 0 && minutes == 0) + { + printf("%u seconds\n", seconds); + return; + } + + if(days > 0) + { + printf("%u day", days); + + if(days > 1) + putchar('s'); + + if(days >= 100) + fputs("(!)", stdout); + + if(hours > 0 || minutes > 0) + fputs(", ", stdout); + } + + if(hours > 0) + { + printf("%u hour", hours); + + if(hours > 1) + putchar('s'); + + if(minutes > 0) + fputs(", ", stdout); + } + + if(minutes > 0) + { + printf("%u min", minutes); + + if(minutes > 1) + putchar('s'); + } + + putchar('\n'); + } + else + { + ffPrintFormat(FF_UPTIME_MODULE_NAME, 0, &options->moduleArgs, FF_UPTIME_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT, &days}, + {FF_FORMAT_ARG_TYPE_UINT, &hours}, + {FF_FORMAT_ARG_TYPE_UINT, &minutes}, + {FF_FORMAT_ARG_TYPE_UINT, &seconds} + }); + } +} + +void ffInitUptimeOptions(FFUptimeOptions* options) +{ + options->moduleName = FF_UPTIME_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseUptimeCommandOptions(FFUptimeOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_UPTIME_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyUptimeOptions(FFUptimeOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseUptimeJsonObject(yyjson_val* module) +{ + FFUptimeOptions __attribute__((__cleanup__(ffDestroyUptimeOptions))) options; + ffInitUptimeOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_UPTIME_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintUptime(&options); +} diff --git a/src/modules/uptime/uptime.h b/src/modules/uptime/uptime.h new file mode 100644 index 0000000000..4708dbd39f --- /dev/null +++ b/src/modules/uptime/uptime.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_UPTIME_MODULE_NAME "Uptime" + +void ffPrintUptime(FFUptimeOptions* options); +void ffInitUptimeOptions(FFUptimeOptions* options); +bool ffParseUptimeCommandOptions(FFUptimeOptions* options, const char* key, const char* value); +void ffDestroyUptimeOptions(FFUptimeOptions* options); +void ffParseUptimeJsonObject(yyjson_val* module); diff --git a/src/modules/users.c b/src/modules/users.c deleted file mode 100644 index 1c78571b2e..0000000000 --- a/src/modules/users.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/users/users.h" - -#define FF_USERS_MODULE_NAME "Users" -#define FF_USERS_NUM_FORMAT_ARGS 1 - -void ffPrintUsers(FFinstance* instance) -{ - FFlist users; - ffListInit(&users, sizeof(FFstrbuf)); - - FFstrbuf error; - ffStrbufInit(&error); - - ffDetectUsers(&users, &error); - - if(error.length > 0) - { - ffPrintError(instance, FF_USERS_MODULE_NAME, 0, &instance->config.users, "%*s", error.length, error.chars); - ffListDestroy(&users); - ffStrbufDestroy(&error); - return; - } - - FFstrbuf result; - ffStrbufInit(&result); - for(uint32_t i = 0; i < users.length; ++i) - { - if(i > 0) - ffStrbufAppendS(&result, ", "); - FFstrbuf* user = (FFstrbuf*)ffListGet(&users, i); - ffStrbufAppend(&result, user); - ffStrbufDestroy(user); - } - - ffListDestroy(&users); - - if(instance->config.users.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_USERS_MODULE_NAME, 0, &instance->config.users.key); - puts(result.chars); - } - else - { - ffPrintFormat(instance, FF_USERS_MODULE_NAME, 0, &instance->config.users, FF_USERS_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result}, - }); - } - - ffStrbufDestroy(&result); -} diff --git a/src/modules/users/option.h b/src/modules/users/option.h new file mode 100644 index 0000000000..f7f0b099ee --- /dev/null +++ b/src/modules/users/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFUsersOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFUsersOptions; diff --git a/src/modules/users/users.c b/src/modules/users/users.c new file mode 100644 index 0000000000..ed18e7b14e --- /dev/null +++ b/src/modules/users/users.c @@ -0,0 +1,90 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/users/users.h" +#include "modules/users/users.h" +#include "util/stringUtils.h" + +#define FF_USERS_NUM_FORMAT_ARGS 1 + +void ffPrintUsers(FFUsersOptions* options) +{ + FF_LIST_AUTO_DESTROY users = ffListCreate(sizeof(FFstrbuf)); + + FF_STRBUF_AUTO_DESTROY error = ffStrbufCreate(); + + ffDetectUsers(&users, &error); + + if(error.length > 0) + { + ffPrintError(FF_USERS_MODULE_NAME, 0, &options->moduleArgs, "%*s", error.length, error.chars); + return; + } + + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate(); + for(uint32_t i = 0; i < users.length; ++i) + { + if(i > 0) + ffStrbufAppendS(&result, ", "); + FFstrbuf* user = (FFstrbuf*)ffListGet(&users, i); + ffStrbufAppend(&result, user); + ffStrbufDestroy(user); + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_USERS_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + puts(result.chars); + } + else + { + ffPrintFormat(FF_USERS_MODULE_NAME, 0, &options->moduleArgs, FF_USERS_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result}, + }); + } +} + +void ffInitUsersOptions(FFUsersOptions* options) +{ + options->moduleName = FF_USERS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseUsersCommandOptions(FFUsersOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_USERS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyUsersOptions(FFUsersOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseUsersJsonObject(yyjson_val* module) +{ + FFUsersOptions __attribute__((__cleanup__(ffDestroyUsersOptions))) options; + ffInitUsersOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_USERS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintUsers(&options); +} diff --git a/src/modules/users/users.h b/src/modules/users/users.h new file mode 100644 index 0000000000..64aab51b7b --- /dev/null +++ b/src/modules/users/users.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_USERS_MODULE_NAME "Users" + +void ffPrintUsers(FFUsersOptions* options); +void ffInitUsersOptions(FFUsersOptions* options); +bool ffParseUsersCommandOptions(FFUsersOptions* options, const char* key, const char* value); +void ffDestroyUsersOptions(FFUsersOptions* options); +void ffParseUsersJsonObject(yyjson_val* module); diff --git a/src/modules/vulkan.c b/src/modules/vulkan.c deleted file mode 100644 index 23c6f60dfa..0000000000 --- a/src/modules/vulkan.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/vulkan/vulkan.h" - -#define FF_VULKAN_MODULE_NAME "Vulkan" -#define FF_VULKAN_NUM_FORMAT_ARGS 3 - -void ffPrintVulkan(FFinstance* instance) -{ - const FFVulkanResult* vulkan = ffDetectVulkan(instance); - - if(vulkan->error) - { - ffPrintError(instance, FF_VULKAN_MODULE_NAME, 0, &instance->config.vulkan, "%s", vulkan->error); - return; - } - - if(instance->config.vulkan.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_VULKAN_MODULE_NAME, 0, &instance->config.vulkan.key); - - if(vulkan->apiVersion.length > 0) - { - ffStrbufWriteTo(&vulkan->apiVersion, stdout); - - if(vulkan->driver.length > 0) - fputs(" - ", stdout); - } - - if(vulkan->driver.length > 0) - ffStrbufWriteTo(&vulkan->driver, stdout); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_VULKAN_MODULE_NAME, 0, &instance->config.vulkan, FF_VULKAN_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->driver}, - {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->apiVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->conformanceVersion} - }); - } -} diff --git a/src/modules/vulkan/option.h b/src/modules/vulkan/option.h new file mode 100644 index 0000000000..c5efd077b1 --- /dev/null +++ b/src/modules/vulkan/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFVulkanOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFVulkanOptions; diff --git a/src/modules/vulkan/vulkan.c b/src/modules/vulkan/vulkan.c new file mode 100644 index 0000000000..b4e51dfb94 --- /dev/null +++ b/src/modules/vulkan/vulkan.c @@ -0,0 +1,90 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/vulkan/vulkan.h" +#include "modules/vulkan/vulkan.h" +#include "util/stringUtils.h" + +#define FF_VULKAN_NUM_FORMAT_ARGS 3 + +void ffPrintVulkan(FFVulkanOptions* options) +{ + const FFVulkanResult* vulkan = ffDetectVulkan(); + + if(vulkan->error) + { + ffPrintError(FF_VULKAN_MODULE_NAME, 0, &options->moduleArgs, "%s", vulkan->error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_VULKAN_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + if(vulkan->apiVersion.length > 0) + { + ffStrbufWriteTo(&vulkan->apiVersion, stdout); + + if(vulkan->driver.length > 0) + fputs(" - ", stdout); + } + + if(vulkan->driver.length > 0) + ffStrbufWriteTo(&vulkan->driver, stdout); + + putchar('\n'); + } + else + { + ffPrintFormat(FF_VULKAN_MODULE_NAME, 0, &options->moduleArgs, FF_VULKAN_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->driver}, + {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->apiVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->conformanceVersion} + }); + } +} + +void ffInitVulkanOptions(FFVulkanOptions* options) +{ + options->moduleName = FF_VULKAN_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseVulkanCommandOptions(FFVulkanOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_VULKAN_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyVulkanOptions(FFVulkanOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseVulkanJsonObject(yyjson_val* module) +{ + FFVulkanOptions __attribute__((__cleanup__(ffDestroyVulkanOptions))) options; + ffInitVulkanOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_VULKAN_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintVulkan(&options); +} diff --git a/src/modules/vulkan/vulkan.h b/src/modules/vulkan/vulkan.h new file mode 100644 index 0000000000..5b92ff850d --- /dev/null +++ b/src/modules/vulkan/vulkan.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_VULKAN_MODULE_NAME "Vulkan" + +void ffPrintVulkan(FFVulkanOptions* options); +void ffInitVulkanOptions(FFVulkanOptions* options); +bool ffParseVulkanCommandOptions(FFVulkanOptions* options, const char* key, const char* value); +void ffDestroyVulkanOptions(FFVulkanOptions* options); +void ffParseVulkanJsonObject(yyjson_val* module); diff --git a/src/modules/wallpaper.c b/src/modules/wallpaper.c deleted file mode 100644 index 75caa54710..0000000000 --- a/src/modules/wallpaper.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/wallpaper/wallpaper.h" - -#define FF_WALLPAPER_MODULE_NAME "Wallpaper" -#define FF_WALLPAPER_NUM_FORMAT_ARGS 1 - -void ffPrintWallpaper(FFinstance* instance) -{ - FF_STRBUF_AUTO_DESTROY wallpaper; - ffStrbufInit(&wallpaper); - const char* error = ffDetectWallpaper(instance, &wallpaper); - - if(error) - { - ffPrintError(instance, FF_WALLPAPER_MODULE_NAME, 0, &instance->config.wallpaper, "%s", error); - return; - } - - if(instance->config.wallpaper.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_WALLPAPER_MODULE_NAME, 0, &instance->config.wallpaper.key); - ffStrbufPutTo(&wallpaper, stdout); - } - else - { - ffPrintFormat(instance, FF_WALLPAPER_MODULE_NAME, 0, &instance->config.wallpaper, FF_WALLPAPER_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &wallpaper} - }); - } -} diff --git a/src/modules/wallpaper/option.h b/src/modules/wallpaper/option.h new file mode 100644 index 0000000000..ff7aa55fef --- /dev/null +++ b/src/modules/wallpaper/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFWallpaperOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFWallpaperOptions; diff --git a/src/modules/wallpaper/wallpaper.c b/src/modules/wallpaper/wallpaper.c new file mode 100644 index 0000000000..54785f6ca9 --- /dev/null +++ b/src/modules/wallpaper/wallpaper.c @@ -0,0 +1,89 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/wallpaper/wallpaper.h" +#include "modules/wallpaper/wallpaper.h" +#include "util/stringUtils.h" + +#define FF_WALLPAPER_NUM_FORMAT_ARGS 2 + +void ffPrintWallpaper(FFWallpaperOptions* options) +{ + FF_STRBUF_AUTO_DESTROY fullpath = ffStrbufCreate(); + const char* error = ffDetectWallpaper(&fullpath); + + const uint32_t index = ffStrbufLastIndexC(&fullpath, + #ifndef _WIN32 + '/' + #else + '\\' + #endif + ) + 1; + const char* filename = index >= fullpath.length + ? fullpath.chars + : fullpath.chars + index; + + if(error) + { + ffPrintError(FF_WALLPAPER_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_WALLPAPER_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + puts(filename); + } + else + { + ffPrintFormat(FF_WALLPAPER_MODULE_NAME, 0, &options->moduleArgs, FF_WALLPAPER_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRING, filename}, + {FF_FORMAT_ARG_TYPE_STRBUF, &fullpath}, + }); + } +} + +void ffInitWallpaperOptions(FFWallpaperOptions* options) +{ + options->moduleName = FF_WALLPAPER_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseWallpaperCommandOptions(FFWallpaperOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_WALLPAPER_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyWallpaperOptions(FFWallpaperOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseWallpaperJsonObject(yyjson_val* module) +{ + FFWallpaperOptions __attribute__((__cleanup__(ffDestroyWallpaperOptions))) options; + ffInitWallpaperOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_WALLPAPER_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintWallpaper(&options); +} diff --git a/src/modules/wallpaper/wallpaper.h b/src/modules/wallpaper/wallpaper.h new file mode 100644 index 0000000000..b274f037dd --- /dev/null +++ b/src/modules/wallpaper/wallpaper.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_WALLPAPER_MODULE_NAME "Wallpaper" + +void ffPrintWallpaper(FFWallpaperOptions* options); +void ffInitWallpaperOptions(FFWallpaperOptions* options); +bool ffParseWallpaperCommandOptions(FFWallpaperOptions* options, const char* key, const char* value); +void ffDestroyWallpaperOptions(FFWallpaperOptions* options); +void ffParseWallpaperJsonObject(yyjson_val* module); diff --git a/src/modules/weather.c b/src/modules/weather.c deleted file mode 100644 index a6bc63ce96..0000000000 --- a/src/modules/weather.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/networking.h" - -#define FF_WEATHER_MODULE_NAME "Weather" -#define FF_WEATHER_NUM_FORMAT_ARGS 1 - -static FFNetworkingState state; -static int status = -1; - -void ffPrepareWeather(FFinstance* instance) -{ - FFstrbuf path; - ffStrbufInitS(&path, "/?format="); - ffStrbufAppend(&path, &instance->config.weatherOutputFormat); - status = ffNetworkingSendHttpRequest(&state, "wttr.in", path.chars, "User-Agent: curl/0.0.0\r\n"); - ffStrbufDestroy(&path); -} - -void ffPrintWeather(FFinstance* instance) -{ - if(status == -1) - ffPrepareWeather(instance); - - if(status == 0) - { - ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather, "Failed to connect to 'wttr.in'"); - return; - } - - FFstrbuf result; - ffStrbufInitA(&result, 4096); - bool success = ffNetworkingRecvHttpResponse(&state, &result, instance->config.weatherTimeout); - if (success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n"); - - if(!success || result.length == 0) - { - ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather, "Failed to receive the server response"); - ffStrbufDestroy(&result); - return; - } - - if(instance->config.weather.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather.key); - ffStrbufPutTo(&result, stdout); - } - else - { - ffPrintFormat(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather, FF_WEATHER_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result} - }); - } - - ffStrbufDestroy(&result); -} diff --git a/src/modules/weather/option.h b/src/modules/weather/option.h new file mode 100644 index 0000000000..6f82f53888 --- /dev/null +++ b/src/modules/weather/option.h @@ -0,0 +1,15 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFWeatherOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFstrbuf location; + FFstrbuf outputFormat; + uint32_t timeout; +} FFWeatherOptions; diff --git a/src/modules/weather/weather.c b/src/modules/weather/weather.c new file mode 100644 index 0000000000..b80875108e --- /dev/null +++ b/src/modules/weather/weather.c @@ -0,0 +1,142 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/networking.h" +#include "modules/weather/weather.h" +#include "util/stringUtils.h" + +#define FF_WEATHER_NUM_FORMAT_ARGS 1 + +static FFNetworkingState state; +static int status = -1; + +void ffPrepareWeather(FFWeatherOptions* options) +{ + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/"); + if (options->location.length) + ffStrbufAppend(&path, &options->location); + ffStrbufAppendS(&path, "?format="); + ffStrbufAppend(&path, &options->outputFormat); + status = ffNetworkingSendHttpRequest(&state, "wttr.in", path.chars, "User-Agent: curl/0.0.0\r\n"); +} + +void ffPrintWeather(FFWeatherOptions* options) +{ + if(status == -1) + ffPrepareWeather(options); + + if(status == 0) + { + ffPrintError(FF_WEATHER_MODULE_NAME, 0, &options->moduleArgs, "Failed to connect to 'wttr.in'"); + return; + } + + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(4096); + bool success = ffNetworkingRecvHttpResponse(&state, &result, options->timeout); + if (success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n"); + + if(!success || result.length == 0) + { + ffPrintError(FF_WEATHER_MODULE_NAME, 0, &options->moduleArgs, "Failed to receive the server response"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_WEATHER_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + ffStrbufPutTo(&result, stdout); + } + else + { + ffPrintFormat(FF_WEATHER_MODULE_NAME, 0, &options->moduleArgs, FF_WEATHER_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result} + }); + } +} + +void ffInitWeatherOptions(FFWeatherOptions* options) +{ + options->moduleName = FF_WEATHER_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + ffStrbufInit(&options->location); + ffStrbufInitStatic(&options->outputFormat, "%t+-+%C+(%l)"); + options->timeout = 0; +} + +bool ffParseWeatherCommandOptions(FFWeatherOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_WEATHER_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffStrEqualsIgnCase(subKey, "location")) + { + ffOptionParseString(key, value, &options->location); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "output-format")) + { + ffOptionParseString(key, value, &options->outputFormat); + return true; + } + + if (ffStrEqualsIgnCase(subKey, "timeout")) + { + options->timeout = ffOptionParseUInt32(key, value); + return true; + } + + return false; +} + +void ffDestroyWeatherOptions(FFWeatherOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + + ffStrbufDestroy(&options->outputFormat); +} + +void ffParseWeatherJsonObject(yyjson_val* module) +{ + FFWeatherOptions __attribute__((__cleanup__(ffDestroyWeatherOptions))) options; + ffInitWeatherOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (ffStrEqualsIgnCase(key, "location")) + { + ffStrbufSetS(&options.location, yyjson_get_str(val)); + continue; + } + + if (ffStrEqualsIgnCase(key, "outputFormat")) + { + ffStrbufSetS(&options.outputFormat, yyjson_get_str(val)); + continue; + } + + if (ffStrEqualsIgnCase(key, "timeout")) + { + options.timeout = (uint32_t) yyjson_get_uint(val); + continue; + } + + ffPrintError(FF_WEATHER_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintWeather(&options); +} diff --git a/src/modules/weather/weather.h b/src/modules/weather/weather.h new file mode 100644 index 0000000000..640201176e --- /dev/null +++ b/src/modules/weather/weather.h @@ -0,0 +1,13 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_WEATHER_MODULE_NAME "Weather" + +void ffPrepareWeather(FFWeatherOptions* options); + +void ffPrintWeather(FFWeatherOptions* options); +void ffInitWeatherOptions(FFWeatherOptions* options); +bool ffParseWeatherCommandOptions(FFWeatherOptions* options, const char* key, const char* value); +void ffDestroyWeatherOptions(FFWeatherOptions* options); +void ffParseWeatherJsonObject(yyjson_val* module); diff --git a/src/modules/wifi.c b/src/modules/wifi.c deleted file mode 100644 index 06c3768fc3..0000000000 --- a/src/modules/wifi.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/wifi/wifi.h" - -#define FF_WIFI_MODULE_NAME "Wifi" -#define FF_WIFI_NUM_FORMAT_ARGS 10 - -void ffPrintWifi(FFinstance* instance) -{ - FF_LIST_AUTO_DESTROY result; - ffListInit(&result, sizeof(FFWifiResult)); - - const char* error = ffDetectWifi(instance, &result); - if(error) - { - ffPrintError(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wifi, "%s", error); - return; - } - if(!result.length) - { - ffPrintError(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wifi, "No Wifi interfaces found"); - return; - } - - for(uint32_t index = 0; index < result.length; ++index) - { - FFWifiResult* item = (FFWifiResult*)ffListGet(&result, index); - uint8_t moduleIndex = result.length == 1 ? 0 : (uint8_t)(index + 1); - - if(instance->config.wifi.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_WIFI_MODULE_NAME, moduleIndex, &instance->config.wifi.key); - if(item->conn.ssid.length) - { - ffStrbufWriteTo(&item->conn.ssid, stdout); - if(item->conn.protocol.length) - printf(" - %s", item->conn.protocol.chars); - if(item->conn.security.length) - printf(" - %s", item->conn.security.chars); - putchar('\n'); - } - else - { - puts(item->inf.status.chars); - } - } - else - { - ffPrintFormat(instance, FF_WIFI_MODULE_NAME, moduleIndex, &instance->config.wifi, FF_WIFI_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &item->inf.description}, - {FF_FORMAT_ARG_TYPE_STRBUF, &item->inf.status}, - {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.status}, - {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.ssid}, - {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.macAddress}, - {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.protocol}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.signalQuality}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.rxRate}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.txRate}, - {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.security}, - }); - } - - ffStrbufDestroy(&item->inf.description); - ffStrbufDestroy(&item->inf.status); - ffStrbufDestroy(&item->conn.status); - ffStrbufDestroy(&item->conn.ssid); - ffStrbufDestroy(&item->conn.macAddress); - ffStrbufDestroy(&item->conn.protocol); - ffStrbufDestroy(&item->conn.security); - } -} diff --git a/src/modules/wifi/option.h b/src/modules/wifi/option.h new file mode 100644 index 0000000000..4d713b5d87 --- /dev/null +++ b/src/modules/wifi/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFWifiOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFWifiOptions; diff --git a/src/modules/wifi/wifi.c b/src/modules/wifi/wifi.c new file mode 100644 index 0000000000..cda7771414 --- /dev/null +++ b/src/modules/wifi/wifi.c @@ -0,0 +1,117 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/wifi/wifi.h" +#include "modules/wifi/wifi.h" +#include "util/stringUtils.h" + +#define FF_WIFI_NUM_FORMAT_ARGS 10 + +void ffPrintWifi(FFWifiOptions* options) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFWifiResult)); + + const char* error = ffDetectWifi(&result); + if(error) + { + ffPrintError(FF_WIFI_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + if(!result.length) + { + ffPrintError(FF_WIFI_MODULE_NAME, 0, &options->moduleArgs, "No Wifi interfaces found"); + return; + } + + for(uint32_t index = 0; index < result.length; ++index) + { + FFWifiResult* item = (FFWifiResult*)ffListGet(&result, index); + uint8_t moduleIndex = result.length == 1 ? 0 : (uint8_t)(index + 1); + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_WIFI_MODULE_NAME, moduleIndex, &options->moduleArgs.key, &options->moduleArgs.keyColor); + if(item->conn.ssid.length) + { + ffStrbufWriteTo(&item->conn.ssid, stdout); + if(item->conn.protocol.length) + printf(" - %s", item->conn.protocol.chars); + if(item->conn.security.length) + printf(" - %s", item->conn.security.chars); + putchar('\n'); + } + else + { + puts(item->inf.status.chars); + } + } + else + { + ffPrintFormat(FF_WIFI_MODULE_NAME, moduleIndex, &options->moduleArgs, FF_WIFI_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &item->inf.description}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->inf.status}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.status}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.ssid}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.macAddress}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.protocol}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.signalQuality}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.rxRate}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.txRate}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.security}, + }); + } + + ffStrbufDestroy(&item->inf.description); + ffStrbufDestroy(&item->inf.status); + ffStrbufDestroy(&item->conn.status); + ffStrbufDestroy(&item->conn.ssid); + ffStrbufDestroy(&item->conn.macAddress); + ffStrbufDestroy(&item->conn.protocol); + ffStrbufDestroy(&item->conn.security); + } +} + +void ffInitWifiOptions(FFWifiOptions* options) +{ + options->moduleName = FF_WIFI_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseWifiCommandOptions(FFWifiOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_WIFI_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyWifiOptions(FFWifiOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseWifiJsonObject(yyjson_val* module) +{ + FFWifiOptions __attribute__((__cleanup__(ffDestroyWifiOptions))) options; + ffInitWifiOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_WIFI_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintWifi(&options); +} diff --git a/src/modules/wifi/wifi.h b/src/modules/wifi/wifi.h new file mode 100644 index 0000000000..b8291fdfc8 --- /dev/null +++ b/src/modules/wifi/wifi.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_WIFI_MODULE_NAME "Wifi" + +void ffPrintWifi(FFWifiOptions* options); +void ffInitWifiOptions(FFWifiOptions* options); +bool ffParseWifiCommandOptions(FFWifiOptions* options, const char* key, const char* value); +void ffDestroyWifiOptions(FFWifiOptions* options); +void ffParseWifiJsonObject(yyjson_val* module); diff --git a/src/modules/wm.c b/src/modules/wm.c deleted file mode 100644 index 38cf9f5a3b..0000000000 --- a/src/modules/wm.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/displayserver/displayserver.h" - -#define FF_WM_MODULE_NAME "WM" -#define FF_WM_NUM_FORMAT_ARGS 3 - -void ffPrintWM(FFinstance* instance) -{ - #ifdef __ANDROID__ - ffPrintError(instance, FF_WM_MODULE_NAME, 0, &instance->config.wm, "WM detection is not supported on Android"); - return; - #endif - - const FFDisplayServerResult* result = ffConnectDisplayServer(instance); - - if(result->wmPrettyName.length == 0) - { - ffPrintError(instance, FF_WM_MODULE_NAME, 0, &instance->config.wm, "No WM found"); - return; - } - - if(instance->config.wm.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_WM_MODULE_NAME, 0, &instance->config.wm.key); - - ffStrbufWriteTo(&result->wmPrettyName, stdout); - - if(result->wmProtocolName.length > 0) - { - fputs(" (", stdout); - ffStrbufWriteTo(&result->wmProtocolName, stdout); - putchar(')'); - } - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_WM_MODULE_NAME, 0, &instance->config.wm, FF_WM_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProcessName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmPrettyName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProtocolName} - }); - } -} diff --git a/src/modules/wm/option.h b/src/modules/wm/option.h new file mode 100644 index 0000000000..fcc7b0231f --- /dev/null +++ b/src/modules/wm/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFWMOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFWMOptions; diff --git a/src/modules/wm/wm.c b/src/modules/wm/wm.c new file mode 100644 index 0000000000..6f60107ff3 --- /dev/null +++ b/src/modules/wm/wm.c @@ -0,0 +1,88 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/displayserver/displayserver.h" +#include "modules/wm/wm.h" +#include "util/stringUtils.h" + +#define FF_WM_NUM_FORMAT_ARGS 3 + +void ffPrintWM(FFWMOptions* options) +{ + const FFDisplayServerResult* result = ffConnectDisplayServer(); + + if(result->wmPrettyName.length == 0) + { + ffPrintError(FF_WM_MODULE_NAME, 0, &options->moduleArgs, "No WM found"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_WM_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + + ffStrbufWriteTo(&result->wmPrettyName, stdout); + + if(result->wmProtocolName.length > 0) + { + fputs(" (", stdout); + ffStrbufWriteTo(&result->wmProtocolName, stdout); + putchar(')'); + } + + putchar('\n'); + } + else + { + ffPrintFormat(FF_WM_MODULE_NAME, 0, &options->moduleArgs, FF_WM_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProcessName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmPrettyName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProtocolName} + }); + } +} + +void ffInitWMOptions(FFWMOptions* options) +{ + options->moduleName = FF_WM_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseWMCommandOptions(FFWMOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_WM_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyWMOptions(FFWMOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseWMJsonObject(yyjson_val* module) +{ + FFWMOptions __attribute__((__cleanup__(ffDestroyWMOptions))) options; + ffInitWMOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_WM_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintWM(&options); +} diff --git a/src/modules/wm/wm.h b/src/modules/wm/wm.h new file mode 100644 index 0000000000..243d6a6472 --- /dev/null +++ b/src/modules/wm/wm.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_WM_MODULE_NAME "WM" + +void ffPrintWM(FFWMOptions* options); +void ffInitWMOptions(FFWMOptions* options); +bool ffParseWMCommandOptions(FFWMOptions* options, const char* key, const char* value); +void ffDestroyWMOptions(FFWMOptions* options); +void ffParseWMJsonObject(yyjson_val* module); diff --git a/src/modules/wmtheme.c b/src/modules/wmtheme.c deleted file mode 100644 index 4112d83213..0000000000 --- a/src/modules/wmtheme.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/wmtheme/wmtheme.h" - -#define FF_WMTHEME_MODULE_NAME "WM Theme" -#define FF_WMTHEME_NUM_FORMAT_ARGS 1 - -void ffPrintWMTheme(FFinstance* instance) -{ - FFstrbuf themeOrError; - ffStrbufInit(&themeOrError); - if(ffDetectWmTheme(instance, &themeOrError)) - { - if(instance->config.wmTheme.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmTheme.key); - puts(themeOrError.chars); - } - else - { - ffPrintFormat(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmTheme, FF_WMTHEME_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &themeOrError} - }); - } - } - else - { - ffPrintError(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmTheme, "%*s", themeOrError.length, themeOrError.chars); - } - ffStrbufDestroy(&themeOrError); -} diff --git a/src/modules/wmtheme/option.h b/src/modules/wmtheme/option.h new file mode 100644 index 0000000000..11b14458b4 --- /dev/null +++ b/src/modules/wmtheme/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFWMThemeOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFWMThemeOptions; diff --git a/src/modules/wmtheme/wmtheme.c b/src/modules/wmtheme/wmtheme.c new file mode 100644 index 0000000000..da66e8ad88 --- /dev/null +++ b/src/modules/wmtheme/wmtheme.c @@ -0,0 +1,77 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/wmtheme/wmtheme.h" +#include "modules/wmtheme/wmtheme.h" +#include "util/stringUtils.h" + +#define FF_WMTHEME_DISPLAY_NAME "WM Theme" +#define FF_WMTHEME_NUM_FORMAT_ARGS 1 + +void ffPrintWMTheme(FFWMThemeOptions* options) +{ + FF_STRBUF_AUTO_DESTROY themeOrError = ffStrbufCreate(); + if(ffDetectWmTheme(&themeOrError)) + { + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_WMTHEME_DISPLAY_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); + puts(themeOrError.chars); + } + else + { + ffPrintFormat(FF_WMTHEME_DISPLAY_NAME, 0, &options->moduleArgs, FF_WMTHEME_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &themeOrError} + }); + } + } + else + { + ffPrintError(FF_WMTHEME_DISPLAY_NAME, 0, &options->moduleArgs, "%*s", themeOrError.length, themeOrError.chars); + } +} + +void ffInitWMThemeOptions(FFWMThemeOptions* options) +{ + options->moduleName = FF_WMTHEME_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseWMThemeCommandOptions(FFWMThemeOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_WMTHEME_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyWMThemeOptions(FFWMThemeOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseWMThemeJsonObject(yyjson_val* module) +{ + FFWMThemeOptions __attribute__((__cleanup__(ffDestroyWMThemeOptions))) options; + ffInitWMThemeOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_WMTHEME_DISPLAY_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintWMTheme(&options); +} diff --git a/src/modules/wmtheme/wmtheme.h b/src/modules/wmtheme/wmtheme.h new file mode 100644 index 0000000000..0214089453 --- /dev/null +++ b/src/modules/wmtheme/wmtheme.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_WMTHEME_MODULE_NAME "WMTheme" + +void ffPrintWMTheme(FFWMThemeOptions* options); +void ffInitWMThemeOptions(FFWMThemeOptions* options); +bool ffParseWMThemeCommandOptions(FFWMThemeOptions* options, const char* key, const char* value); +void ffDestroyWMThemeOptions(FFWMThemeOptions* options); +void ffParseWMThemeJsonObject(yyjson_val* module); diff --git a/src/util/FFlist.c b/src/util/FFlist.c index bd643014ac..59f5a8b567 100644 --- a/src/util/FFlist.c +++ b/src/util/FFlist.c @@ -55,11 +55,3 @@ bool ffListPop(FFlist* list, void* result) --list->length; return result; } - -void ffListDestroy(FFlist* list) -{ - //Avoid free-after-use. These 3 assignments are cheap so don't remove them - list->capacity = list->length = 0; - free(list->data); - list->data = NULL; -} diff --git a/src/util/FFlist.h b/src/util/FFlist.h index 58612e3470..4961adda3f 100644 --- a/src/util/FFlist.h +++ b/src/util/FFlist.h @@ -31,12 +31,20 @@ bool ffListShift(FFlist* list, void* result); // Removes the last element, and copy its value to `*result` bool ffListPop(FFlist* list, void* result); -void ffListDestroy(FFlist* list); - static inline void ffListInit(FFlist* list, uint32_t elementSize) { assert(elementSize > 0); - ffListInitA(list, elementSize, 0); + list->elementSize = elementSize; + list->capacity = 0; + list->length = 0; + list->data = NULL; +} + +static inline FFlist ffListCreate(uint32_t elementSize) +{ + FFlist result; + ffListInit(&result, elementSize); + return result; } static inline void* ffListGet(const FFlist* list, uint32_t index) @@ -45,11 +53,43 @@ static inline void* ffListGet(const FFlist* list, uint32_t index) return list->data + (index * list->elementSize); } +static inline bool ffListContains(const FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*)) +{ + return ffListFirstIndexComp(list, compElement, compFunc) != list->length; +} + static inline void ffListSort(FFlist* list, int(*compar)(const void*, const void*)) { qsort(list->data, list->length, list->elementSize, compar); } +// Move the contents of `src` into `list`, and left `src` empty +static inline void ffListInitMove(FFlist* list, FFlist* src) +{ + if (src) + { + list->elementSize = src->elementSize; + list->capacity = src->capacity; + list->length = src->length; + list->data = src->data; + ffListInit(src, list->elementSize); + } + else + { + ffListInit(list, 0); + } +} + +static inline void ffListDestroy(FFlist* list) +{ + if (!list->data) return; + + //Avoid free-after-use. These 3 assignments are cheap so don't remove them + list->capacity = list->length = 0; + free(list->data); + list->data = NULL; +} + #define FF_LIST_FOR_EACH(itemType, itemVarName, listVar) \ assert(sizeof(itemType) == (listVar).elementSize); \ for(itemType* itemVarName = (itemType*)(listVar).data; \ diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index bcf9460718..70a2a029df 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -16,35 +16,6 @@ void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate) ffStrbufClear(strbuf); } -void ffStrbufInitCopy(FFstrbuf* strbuf, const FFstrbuf* src) -{ - ffStrbufInitA(strbuf, src->allocated); - ffStrbufAppend(strbuf, src); -} - -void ffStrbufInitMove(FFstrbuf* strbuf, FFstrbuf* src) -{ - if (src) - { - strbuf->allocated = src->allocated; - strbuf->chars = src->chars; - strbuf->length = src->length; - ffStrbufInit(src); - } - else - ffStrbufInit(strbuf); -} - -void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...) -{ - assert(format != NULL); - - va_list arguments; - va_start(arguments, format); - ffStrbufInitVF(strbuf, format, arguments); - va_end(arguments); -} - void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments) { assert(format != NULL); @@ -56,18 +27,9 @@ void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments) strbuf->length = (uint32_t)len; } -uint32_t ffStrbufGetFree(const FFstrbuf* strbuf) -{ - assert(strbuf != NULL); - if(strbuf->allocated == 0) - return 0; - - return strbuf->allocated - strbuf->length - 1; // - 1 for the null byte -} - void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) { - if(ffStrbufGetFree(strbuf) >= free) + if(ffStrbufGetFree(strbuf) >= free && !(strbuf->allocated == 0 && strbuf->length > 0)) return; uint32_t allocate = strbuf->allocated; @@ -79,8 +41,12 @@ void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) if(strbuf->allocated == 0) { - strbuf->chars = malloc(sizeof(*strbuf->chars) * allocate); - strbuf->chars[0] = '\0'; + char* newbuf = malloc(sizeof(*strbuf->chars) * allocate); + if(strbuf->length == 0) + *newbuf = '\0'; + else + memcpy(newbuf, strbuf->chars, strbuf->length + 1); + strbuf->chars = newbuf; } else strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * allocate); @@ -236,7 +202,7 @@ void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value) void ffStrbufTrimLeft(FFstrbuf* strbuf, char c) { - if(strbuf->length == 0) //`allocated == 0` implies `length == 0` + if(strbuf->length == 0) return; uint32_t index = 0; @@ -246,6 +212,14 @@ void ffStrbufTrimLeft(FFstrbuf* strbuf, char c) if(index == 0) return; + if(strbuf->allocated == 0) + { + //static string + strbuf->length -= index; + strbuf->chars += index; + return; + } + memmove(strbuf->chars, strbuf->chars + index, strbuf->length - index); strbuf->length -= index; strbuf->chars[strbuf->length] = '\0'; @@ -259,13 +233,14 @@ void ffStrbufTrimRight(FFstrbuf* strbuf, char c) while(ffStrbufEndsWithC(strbuf, c)) --strbuf->length; - strbuf->chars[strbuf->length] = '\0'; -} + if(strbuf->allocated == 0) + { + //static string + ffStrbufInitNS(strbuf, strbuf->length, strbuf->chars); + return; + } -void ffStrbufTrim(FFstrbuf* strbuf, char c) -{ - ffStrbufTrimRight(strbuf, c); - ffStrbufTrimLeft(strbuf, c); + strbuf->chars[strbuf->length] = '\0'; } void ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endIndex) @@ -279,6 +254,7 @@ void ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endInd return; } + ffStrbufEnsureFree(strbuf, 0); memmove(strbuf->chars + startIndex, strbuf->chars + endIndex, strbuf->length - endIndex); strbuf->length -= (endIndex - startIndex); strbuf->chars[strbuf->length] = '\0'; @@ -292,26 +268,12 @@ void ffStrbufRemoveS(FFstrbuf* strbuf, const char* str) ffStrbufRemoveSubstr(strbuf, i, i + stringLength); } -void ffStrbufRemoveStringsA(FFstrbuf* strbuf, uint32_t numStrings, const char* strings[]) +void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, const char* strings[]) { for(uint32_t i = 0; i < numStrings; i++) ffStrbufRemoveS(strbuf, strings[i]); } -void ffStrbufRemoveStringsV(FFstrbuf* strbuf, uint32_t numStrings, va_list arguments) -{ - for(uint32_t i = 0; i < numStrings; i++) - ffStrbufRemoveS(strbuf, va_arg(arguments, const char*)); -} - -void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, ...) -{ - va_list argp; - va_start(argp, numStrings); - ffStrbufRemoveStringsV(strbuf, numStrings, argp); - va_end(argp); -} - uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c) { assert(start <= strbuf->length); @@ -343,6 +305,10 @@ uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c) void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace) { + if (strbuf->length == 0) + return; + + ffStrbufEnsureFree(strbuf, 0); for (char *current_pos = strchr(strbuf->chars, find); current_pos; current_pos = strchr(current_pos + 1, find)) *current_pos = replace; } @@ -352,20 +318,17 @@ void ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index) if(strbuf->length <= index) return; + if(strbuf->allocated == 0) + { + //static string + ffStrbufInitNS(strbuf, strbuf->length, strbuf->chars); + return; + } + strbuf->length = index; strbuf->chars[strbuf->length] = '\0'; } -void ffStrbufSubstrBeforeFirstC(FFstrbuf* strbuf, char c) -{ - ffStrbufSubstrBefore(strbuf, ffStrbufFirstIndexC(strbuf, c)); -} - -void ffStrbufSubstrBeforeLastC(FFstrbuf* strbuf, char c) -{ - ffStrbufSubstrBefore(strbuf, ffStrbufLastIndexC(strbuf, c)); -} - void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index) { if(index >= strbuf->length) @@ -374,6 +337,14 @@ void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index) return; } + if(strbuf->allocated == 0) + { + //static string + strbuf->length -= index; + strbuf->chars += index; + return; + } + memmove(strbuf->chars, strbuf->chars + index + 1, strbuf->length - index - 1); strbuf->length -= (index + 1); strbuf->chars[strbuf->length] = '\0'; @@ -459,12 +430,14 @@ uint16_t ffStrbufToUInt16(const FFstrbuf* strbuf, uint16_t defaultValue) return str_end == strbuf->chars || result > UINT16_MAX ? defaultValue : (uint16_t)result; } -void ffStrbufDestroy(FFstrbuf* strbuf) +void ffStrbufUpperCase(FFstrbuf* strbuf) { - if(strbuf->allocated == 0) return; + for (uint32_t i = 0; i < strbuf->length; ++i) + strbuf->chars[i] = (char) toupper(strbuf->chars[i]); +} - //Avoid free-after-use. These 3 assignments are cheap so don't remove them - strbuf->allocated = strbuf->length = 0; - free(strbuf->chars); - strbuf->chars = CHAR_NULL_PTR; +void ffStrbufLowerCase(FFstrbuf* strbuf) +{ + for (uint32_t i = 0; i < strbuf->length; ++i) + strbuf->chars[i] = (char) tolower(strbuf->chars[i]); } diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 6f9f80ce7f..9e9bce198d 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -28,18 +28,15 @@ typedef struct FFstrbuf char* chars; } FFstrbuf; +static inline void ffStrbufInit(FFstrbuf* strbuf); void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate); -void ffStrbufInitCopy(FFstrbuf* strbuf, const FFstrbuf* src); -void ffStrbufInitMove(FFstrbuf* strbuf, FFstrbuf* src); -void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...); void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments); void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free); -FF_C_NODISCARD uint32_t ffStrbufGetFree(const FFstrbuf* strbuf); - void ffStrbufClear(FFstrbuf* strbuf); +static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value); void ffStrbufAppendC(FFstrbuf* strbuf, char c); void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value); void ffStrbufAppendNSExludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude); @@ -56,13 +53,10 @@ void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...); void ffStrbufTrimLeft(FFstrbuf* strbuf, char c); void ffStrbufTrimRight(FFstrbuf* strbuf, char c); -void ffStrbufTrim(FFstrbuf* strbuf, char c); void ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endIndex); void ffStrbufRemoveS(FFstrbuf* strbuf, const char* str); -void ffStrbufRemoveStringsA(FFstrbuf* strbuf, uint32_t numStrings, const char* strings[]); -void ffStrbufRemoveStringsV(FFstrbuf* strbuf, uint32_t numStrings, va_list arguments); -void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, ...); +void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, const char* strings[]); FF_C_NODISCARD uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c); FF_C_NODISCARD uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str); @@ -72,8 +66,6 @@ FF_C_NODISCARD uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace); void ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index); -void ffStrbufSubstrBeforeFirstC(FFstrbuf* strbuf, char c); -void ffStrbufSubstrBeforeLastC(FFstrbuf* strbuf, char c); void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index); void ffStrbufSubstrAfterFirstC(FFstrbuf* strbuf, char c); void ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str); @@ -91,7 +83,104 @@ void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file); FF_C_NODISCARD double ffStrbufToDouble(const FFstrbuf* strbuf); FF_C_NODISCARD uint16_t ffStrbufToUInt16(const FFstrbuf* strbuf, uint16_t defaultValue); -void ffStrbufDestroy(FFstrbuf* strbuf); +void ffStrbufUpperCase(FFstrbuf* strbuf); +void ffStrbufLowerCase(FFstrbuf* strbuf); + +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateA(uint32_t allocate) +{ + FFstrbuf strbuf; + ffStrbufInitA(&strbuf, allocate); + return strbuf; +} + +static inline void ffStrbufInitCopy(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict src) +{ + ffStrbufInitA(strbuf, src->allocated); + ffStrbufAppend(strbuf, src); +} + +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateCopy(const FFstrbuf* src) +{ + FFstrbuf strbuf; + ffStrbufInitCopy(&strbuf, src); + return strbuf; +} + +// Move the content of `src` into `strbuf`, and left `src` empty +static inline void ffStrbufInitMove(FFstrbuf* strbuf, FFstrbuf* src) +{ + if (src) + { + strbuf->allocated = src->allocated; + strbuf->chars = src->chars; + strbuf->length = src->length; + ffStrbufInit(src); + } + else + ffStrbufInit(strbuf); +} + +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateMove(FFstrbuf* src) +{ + FFstrbuf strbuf; + ffStrbufInitMove(&strbuf, src); + return strbuf; +} + +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateVF(const char* format, va_list arguments) +{ + FFstrbuf strbuf; + ffStrbufInitVF(&strbuf, format, arguments); + return strbuf; +} + +FF_C_PRINTF(2, 3) +static inline void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...) +{ + va_list arguments; + va_start(arguments, format); + ffStrbufInitVF(strbuf, format, arguments); + va_end(arguments); +} + +FF_C_PRINTF(1, 2) +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateF(const char* format, ...) +{ + FFstrbuf strbuf; + + va_list arguments; + va_start(arguments, format); + ffStrbufInitVF(&strbuf, format, arguments); + va_end(arguments); + + return strbuf; +} + +static inline void ffStrbufDestroy(FFstrbuf* strbuf) +{ + extern char* CHAR_NULL_PTR; + + if(strbuf->allocated == 0) + { + strbuf->length = 0; + strbuf->chars = CHAR_NULL_PTR; + return; + } + + //Avoid free-after-use. These 3 assignments are cheap so don't remove them + strbuf->allocated = strbuf->length = 0; + free(strbuf->chars); + strbuf->chars = CHAR_NULL_PTR; +} + +FF_C_NODISCARD static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf) +{ + assert(strbuf != NULL); + if(strbuf->allocated == 0) + return 0; + + return strbuf->allocated - strbuf->length - 1; // - 1 for the null byte +} static inline void ffStrbufRecalculateLength(FFstrbuf* strbuf) { @@ -121,11 +210,35 @@ static inline void ffStrbufInit(FFstrbuf* strbuf) strbuf->chars = CHAR_NULL_PTR; } -static inline FFstrbuf ffStrbufCreate() +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreate() +{ + FFstrbuf strbuf; + ffStrbufInit(&strbuf); + return strbuf; +} + +static inline void ffStrbufInitStatic(FFstrbuf* strbuf, const char* str) +{ + ffStrbufInit(strbuf); + strbuf->allocated = 0; + strbuf->length = (uint32_t) strlen(str); + strbuf->chars = (char*) str; +} + +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateStatic(const char* str) { - FFstrbuf result; - ffStrbufInit(&result); - return result; + FFstrbuf strbuf; + ffStrbufInitStatic(&strbuf, str); + return strbuf; +} + +static inline void ffStrbufSetStatic(FFstrbuf* strbuf, const char* value) +{ + if(strbuf->allocated > 0) + ffStrbufDestroy(strbuf); + + if(value != NULL) + ffStrbufInitStatic(strbuf, value); } static inline void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char* str) @@ -134,13 +247,27 @@ static inline void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char* ffStrbufAppendNS(strbuf, length, str); } +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateNS(uint32_t length, const char* str) +{ + FFstrbuf strbuf; + ffStrbufInitNS(&strbuf, length, str); + return strbuf; +} + static inline void ffStrbufInitS(FFstrbuf* strbuf, const char* str) { ffStrbufInit(strbuf); ffStrbufAppendS(strbuf, str); } -static inline void ffStrbufAppend(FFstrbuf* strbuf, const FFstrbuf* value) +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateS(const char* str) +{ + FFstrbuf strbuf; + ffStrbufInitS(&strbuf, str); + return strbuf; +} + +static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value) { assert(value != strbuf); if(value == NULL) @@ -148,6 +275,13 @@ static inline void ffStrbufAppend(FFstrbuf* strbuf, const FFstrbuf* value) ffStrbufAppendNS(strbuf, value->length, value->chars); } +static inline void ffStrbufPrepend(FFstrbuf* strbuf, FFstrbuf* value) +{ + if(value == NULL) + return; + ffStrbufPrependNS(strbuf, value->length, value->chars); +} + static inline void ffStrbufPrependS(FFstrbuf* strbuf, const char* value) { if(value == NULL) @@ -249,6 +383,16 @@ static inline FF_C_NODISCARD uint32_t ffStrbufLastIndexC(const FFstrbuf* strbuf, return ffStrbufPreviousIndexC(strbuf, strbuf->length - 1, c); } +static inline void ffStrbufSubstrBeforeFirstC(FFstrbuf* strbuf, char c) +{ + ffStrbufSubstrBefore(strbuf, ffStrbufFirstIndexC(strbuf, c)); +} + +static inline void ffStrbufSubstrBeforeLastC(FFstrbuf* strbuf, char c) +{ + ffStrbufSubstrBefore(strbuf, ffStrbufLastIndexC(strbuf, c)); +} + static inline FF_C_NODISCARD bool ffStrbufStartsWithC(const FFstrbuf* strbuf, char c) { return strbuf->chars[0] == c; @@ -330,6 +474,12 @@ static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCase(const FFstrbuf* strbuf return ffStrbufEndsWithIgnCaseNS(strbuf, end->length, end->chars); } +static inline void ffStrbufTrim(FFstrbuf* strbuf, char c) +{ + ffStrbufTrimRight(strbuf, c); + ffStrbufTrimLeft(strbuf, c); +} + #define FF_STRBUF_AUTO_DESTROY FFstrbuf __attribute__((__cleanup__(ffStrbufDestroy))) #endif diff --git a/src/util/FFvaluestore.c b/src/util/FFvaluestore.c deleted file mode 100644 index 68040045b4..0000000000 --- a/src/util/FFvaluestore.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "FFvaluestore.h" - -#include - -typedef char KeyType[32]; //31 byte key + \0 - -void ffValuestoreInit(FFvaluestore* vs, uint32_t valueSize) -{ - ffListInit(vs, (uint32_t) (sizeof(KeyType) + valueSize)); -} - -void* ffValuestoreGet(FFvaluestore* vs, const char* key) -{ - for(uint32_t i = 0; i < vs->length; i++) - { - char* element = ffListGet(vs, i); - if(strcmp(element, key) == 0) - return element + sizeof(KeyType); - } - - return NULL; -} - -void* ffValuestoreSet(FFvaluestore* vs, const char* key, bool* created) -{ - char* element = ffValuestoreGet(vs, key); - if(element != NULL) - { - if(created != NULL) - *created = false; - return element; - } - - element = ffListAdd(vs); - strncpy(element, key, sizeof(KeyType) - 1); - element[sizeof(KeyType) - 1] = '\0'; - - if(created != NULL) - *created = true; - return element + sizeof(KeyType); -} - -void ffValuestoreDestroy(FFvaluestore* vs) -{ - ffListDestroy(vs); -} diff --git a/src/util/FFvaluestore.h b/src/util/FFvaluestore.h deleted file mode 100644 index 4d966837c5..0000000000 --- a/src/util/FFvaluestore.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#ifndef FASTFETCH_INCLUDED_FFVALUESTORE -#define FASTFETCH_INCLUDED_FFVALUESTORE - -#include "FFlist.h" -#include "FFcheckmacros.h" - -typedef FFlist FFvaluestore; - -void ffValuestoreInit(FFvaluestore* vs, uint32_t valueSize); -FF_C_NODISCARD void* ffValuestoreGet(FFvaluestore* vs, const char* key); -FF_C_NODISCARD void* ffValuestoreSet(FFvaluestore* vs, const char* key, bool* created); //created may be NULL -void ffValuestoreDestroy(FFvaluestore* vs); - -#endif diff --git a/src/util/apple/ddcci.h b/src/util/apple/ddcci.h new file mode 100644 index 0000000000..a0de174828 --- /dev/null +++ b/src/util/apple/ddcci.h @@ -0,0 +1,15 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_util_apple_ddcci_h + +#include + +// DDC/CI +typedef CFTypeRef IOAVServiceRef; +extern IOAVServiceRef IOAVServiceCreate(CFAllocatorRef allocator) __attribute__((weak_import)); +extern IOAVServiceRef IOAVServiceCreateWithService(CFAllocatorRef allocator, io_service_t service) __attribute__((weak_import)); +extern IOReturn IOAVServiceCopyEDID(IOAVServiceRef service, CFDataRef* x2) __attribute__((weak_import)); +extern IOReturn IOAVServiceReadI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t offset, void* outputBuffer, uint32_t outputBufferSize) __attribute__((weak_import)); +extern IOReturn IOAVServiceWriteI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t dataAddress, void* inputBuffer, uint32_t inputBufferSize) __attribute__((weak_import)); + +#endif diff --git a/src/util/edidHelper.c b/src/util/edidHelper.c new file mode 100644 index 0000000000..456d8c58be --- /dev/null +++ b/src/util/edidHelper.c @@ -0,0 +1,80 @@ +#include "edidHelper.h" + +void ffEdidGetPhysicalResolution(const uint8_t edid[128], uint32_t* width, uint32_t* height) +{ + const int dtd = 54; + *width = (((uint32_t) edid[dtd + 4] >> 4) << 8) | edid[dtd + 2]; + *height = (((uint32_t) edid[dtd + 7] >> 4) << 8) | edid[dtd + 5]; +} + +void ffEdidGetVendorAndModel(const uint8_t edid[128], FFstrbuf* result) +{ + // https://github.com/jinksong/read_edid/blob/master/parse-edid/parse-edid.c + ffStrbufAppendF(result, "%c%c%c%04X", + (char) (((uint32_t)edid[8] >> 2 & 0x1f) + 'A' - 1), + (char) (((((uint32_t)edid[8] & 0x3) << 3) | (((uint32_t)edid[9] & 0xe0) >> 5)) + 'A' - 1), + (char) (((uint32_t)edid[9] & 0x1f) + 'A' - 1), + (uint32_t) (edid[10] + (uint32_t) (edid[11] << 8)) + ); +} + +bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name) +{ + // https://github.com/jinksong/read_edid/blob/master/parse-edid/parse-edid.c + for (uint32_t i = 0x36; i < 0x7E; i += 0x12) + { // read through descriptor blocks... + if (edid[i] == 0x00) + { // not a timing descriptor + if (edid[i + 3] == 0xfc) + { // Model Name tag + for (uint32_t j = 0; j < 13; j++) + { + if (edid[i + 5 + j] == 0x0a) + { + ffStrbufAppendNS(name, j, (const char*) &edid[i + 5]); + return true; + } + } + } + } + } + + // use manufacturer + model number as monitor name + ffEdidGetVendorAndModel(edid, name); + return false; +} + +void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* height) +{ + *width = (((uint32_t) edid[68] & 0xF0) << 4) + edid[66]; + *height = (((uint32_t) edid[68] & 0x0F) << 8) + edid[67]; +} + +bool ffEdidGetHdrCompatible(const uint8_t* edid, uint32_t length) +{ + if (length <= 128) return false; + for (const uint8_t* cta = &edid[128]; cta < &edid[length]; cta += 128) + { + // https://en.wikipedia.org/wiki/Extended_Display_Identification_Data#CTA_EDID_Timing_Extension_Block + if (cta[0] != 0x02 /* CTA EDID */) continue; + if (cta[1] < 0x03 /* Version 3 */) continue; + const uint8_t offset = cta[2]; + if (offset <= 4) continue; + for (uint8_t i = 4; i < offset;) + { + uint8_t blkLen = cta[i] & 0x1f; + if (blkLen > 0) + { + uint8_t blkTag = (cta[i] & 0xe0) >> 5; + if (blkTag == 0x07 /* Extended Block Type Tag */) + { + uint8_t extendedTag = cta[i + 1]; + if (extendedTag == 6 /* HDR SMDB */ || extendedTag == 7 /* HDR DMDB */) + return true; + } + } + i += blkLen + 1; + } + } + return false; +} diff --git a/src/util/edidHelper.h b/src/util/edidHelper.h new file mode 100644 index 0000000000..2009263761 --- /dev/null +++ b/src/util/edidHelper.h @@ -0,0 +1,15 @@ +#pragma once + +#ifndef FF_INCLUDED_EDID_HELPER_H +#define FF_INCLUDED_EDID_HELPER_H + +#include +#include "util/FFstrbuf.h" + +void ffEdidGetVendorAndModel(const uint8_t edid[128], FFstrbuf* result); +bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name); +void ffEdidGetPhysicalResolution(const uint8_t edid[128], uint32_t* width, uint32_t* height); +void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* height); // in mm +bool ffEdidGetHdrCompatible(const uint8_t edid[128], uint32_t length); + +#endif diff --git a/src/util/mallocHelper.h b/src/util/mallocHelper.h index f7d5456fd7..3cf19fad2b 100644 --- a/src/util/mallocHelper.h +++ b/src/util/mallocHelper.h @@ -1,3 +1,8 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_UTIL_MALLOC_HELPER +#define FASTFETCH_INCLUDED_UTIL_MALLOC_HELPER + #include #include @@ -9,3 +14,5 @@ static inline void ffWrapFree(void* pPtr) } #define FF_AUTO_FREE __attribute__((__cleanup__(ffWrapFree))) + +#endif diff --git a/src/util/platform/FFPlatform.c b/src/util/platform/FFPlatform.c index 811547c524..27b470b3bf 100644 --- a/src/util/platform/FFPlatform.c +++ b/src/util/platform/FFPlatform.c @@ -1,5 +1,6 @@ #include "FFPlatform_private.h" #include "util/stringUtils.h" +#include "common/io/io.h" void ffPlatformInit(FFPlatform* platform) { @@ -68,55 +69,21 @@ void ffPlatformDestroy(FFPlatform* platform) void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path) { - FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs); - ffStrbufInitA(buffer, 64); - ffStrbufAppendS(buffer, path); - ffStrbufEnsureEndsWithC(buffer, '/'); - FF_PLATFORM_PATH_UNIQUE(dirs, buffer); -} + if (!ffPathExists(path, FF_PATHTYPE_DIRECTORY)) + return; -void ffPlatformPathAddHome(FFlist* dirs, const FFPlatform* platform, const char* suffix) -{ - FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs); - ffStrbufInitA(buffer, 64); - ffStrbufAppend(buffer, &platform->homeDir); - ffStrbufAppendS(buffer, suffix); - ffStrbufEnsureEndsWithC(buffer, '/'); - FF_PLATFORM_PATH_UNIQUE(dirs, buffer); + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateS(path); + ffStrbufEnsureEndsWithC(&buffer, '/'); + if (!ffListContains(dirs, &buffer, (void*) ffStrbufEqual)) + ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer); } -void ffPlatformPathAddEnv(FFlist* dirs, const char* env) +void ffPlatformPathAddHome(FFlist* dirs, const FFPlatform* platform, const char* suffix) { - const char* envValue = getenv(env); - if(!ffStrSet(envValue)) - return; - - FFstrbuf value; - ffStrbufInitA(&value, 64); - ffStrbufAppendS(&value, envValue); - - uint32_t startIndex = 0; - while (startIndex < value.length) - { - #ifdef _WIN32 - const char separator = ';'; - #else - const char separator = ':'; - #endif - - uint32_t colonIndex = ffStrbufNextIndexC(&value, startIndex, separator); - value.chars[colonIndex] = '\0'; - - if(!ffStrSet(value.chars + startIndex)) - { - startIndex = colonIndex + 1; - continue; - } - - ffPlatformPathAddAbsolute(dirs, value.chars + startIndex); - - startIndex = colonIndex + 1; - } - - ffStrbufDestroy(&value); + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateA(64); + ffStrbufAppend(&buffer, &platform->homeDir); + ffStrbufAppendS(&buffer, suffix); + ffStrbufEnsureEndsWithC(&buffer, '/'); + if (ffPathExists(buffer.chars, FF_PATHTYPE_DIRECTORY) && !ffListContains(dirs, &buffer, (void*) ffStrbufEqual)) + ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer); } diff --git a/src/util/platform/FFPlatform_private.h b/src/util/platform/FFPlatform_private.h index 698f07609b..d81e6f9cf3 100644 --- a/src/util/platform/FFPlatform_private.h +++ b/src/util/platform/FFPlatform_private.h @@ -7,15 +7,7 @@ void ffPlatformInitImpl(FFPlatform* platform); -#define FF_PLATFORM_PATH_UNIQUE(list, element) \ - if(ffListFirstIndexComp(list, element, (bool(*)(const void*, const void*))ffStrbufEqual) < list->length - 1) \ - { \ - ffStrbufDestroy(ffListGet(list, list->length - 1)); \ - --list->length; \ - } - void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path); void ffPlatformPathAddHome(FFlist* dirs, const FFPlatform* platform, const char* suffix); -void ffPlatformPathAddEnv(FFlist* dirs, const char* env); #endif diff --git a/src/util/platform/FFPlatform_unix.c b/src/util/platform/FFPlatform_unix.c index 251edef542..a6e5d1b130 100644 --- a/src/util/platform/FFPlatform_unix.c +++ b/src/util/platform/FFPlatform_unix.c @@ -1,11 +1,39 @@ #include "FFPlatform_private.h" #include "util/stringUtils.h" #include "fastfetch_config.h" +#include "common/io/io.h" #include #include #include +static void platformPathAddEnv(FFlist* dirs, const char* env) +{ + const char* envValue = getenv(env); + if(!ffStrSet(envValue)) + return; + + FF_STRBUF_AUTO_DESTROY value = ffStrbufCreateA(64); + ffStrbufAppendS(&value, envValue); + + uint32_t startIndex = 0; + while (startIndex < value.length) + { + uint32_t colonIndex = ffStrbufNextIndexC(&value, startIndex, ':'); + value.chars[colonIndex] = '\0'; + + if(!ffStrSet(value.chars + startIndex)) + { + startIndex = colonIndex + 1; + continue; + } + + ffPlatformPathAddAbsolute(dirs, value.chars + startIndex); + + startIndex = colonIndex + 1; + } +} + static void getHomeDir(FFPlatform* platform, const struct passwd* pwd) { const char* home = pwd ? pwd->pw_dir : getenv("HOME"); @@ -30,7 +58,7 @@ static void getCacheDir(FFPlatform* platform) static void getConfigDirs(FFPlatform* platform) { - ffPlatformPathAddEnv(&platform->configDirs, "XDG_CONFIG_HOME"); + platformPathAddEnv(&platform->configDirs, "XDG_CONFIG_HOME"); ffPlatformPathAddHome(&platform->configDirs, platform, ".config/"); #if defined(__APPLE__) @@ -39,7 +67,7 @@ static void getConfigDirs(FFPlatform* platform) #endif ffPlatformPathAddHome(&platform->configDirs, platform, ""); - ffPlatformPathAddEnv(&platform->configDirs, "XDG_CONFIG_DIRS"); + platformPathAddEnv(&platform->configDirs, "XDG_CONFIG_DIRS"); #if !defined(__APPLE__) ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_ETC "/xdg/"); @@ -51,7 +79,7 @@ static void getConfigDirs(FFPlatform* platform) static void getDataDirs(FFPlatform* platform) { - ffPlatformPathAddEnv(&platform->dataDirs, "XDG_DATA_HOME"); + platformPathAddEnv(&platform->dataDirs, "XDG_DATA_HOME"); ffPlatformPathAddHome(&platform->dataDirs, platform, ".local/share/"); #if defined(__APPLE__) @@ -59,7 +87,7 @@ static void getDataDirs(FFPlatform* platform) #endif ffPlatformPathAddHome(&platform->dataDirs, platform, ""); - ffPlatformPathAddEnv(&platform->dataDirs, "XDG_DATA_DIRS"); + platformPathAddEnv(&platform->dataDirs, "XDG_DATA_DIRS"); ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR "/local/share/"); ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR "/share/"); } diff --git a/src/util/platform/FFPlatform_windows.c b/src/util/platform/FFPlatform_windows.c index bfa5e1a7e3..13fc972460 100644 --- a/src/util/platform/FFPlatform_windows.c +++ b/src/util/platform/FFPlatform_windows.c @@ -1,9 +1,11 @@ #include "FFPlatform_private.h" +#include "common/io/io.h" #include "util/stringUtils.h" #include "util/windows/unicode.h" #include #include + static void getHomeDir(FFPlatform* platform) { PWSTR pPath; @@ -38,11 +40,11 @@ static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId) PWSTR pPath; if(SUCCEEDED(SHGetKnownFolderPath(folderId, 0, NULL, &pPath))) { - FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs); - ffStrbufInitWS(buffer, pPath); - ffStrbufReplaceAllC(buffer, '\\', '/'); - ffStrbufEnsureEndsWithC(buffer, '/'); - FF_PLATFORM_PATH_UNIQUE(dirs, buffer); + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateWS(pPath); + ffStrbufReplaceAllC(&buffer, '\\', '/'); + ffStrbufEnsureEndsWithC(&buffer, '/'); + if (!ffListContains(dirs, &buffer, (void*) ffStrbufEqual)) + ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer); } CoTaskMemFree(pPath); } @@ -53,14 +55,18 @@ static void platformPathAddEnvSuffix(FFlist* dirs, const char* env, const char* if(!ffStrSet(value)) return; - FFstrbuf* buffer = ffListAdd(dirs); - ffStrbufInitA(buffer, 64); - ffStrbufAppendS(buffer, value); - ffStrbufReplaceAllC(buffer, '\\', '/'); - ffStrbufEnsureEndsWithC(buffer, '/'); - ffStrbufAppendS(buffer, suffix); - ffStrbufEnsureEndsWithC(buffer, '/'); - FF_PLATFORM_PATH_UNIQUE(dirs, buffer); + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateA(64); + ffStrbufAppendS(&buffer, value); + ffStrbufReplaceAllC(&buffer, '\\', '/'); + ffStrbufEnsureEndsWithC(&buffer, '/'); + if (suffix) + { + ffStrbufAppendS(&buffer, suffix); + ffStrbufEnsureEndsWithC(&buffer, '/'); + } + + if (ffPathExists(buffer.chars, FF_PATHTYPE_DIRECTORY) && !ffListContains(dirs, &buffer, (void*) ffStrbufEqual)) + ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer); } static void getConfigDirs(FFPlatform* platform) @@ -69,11 +75,12 @@ static void getConfigDirs(FFPlatform* platform) { // We are in MSYS2 / Git Bash platformPathAddEnvSuffix(&platform->configDirs, "HOME", ".config/"); - platformPathAddEnvSuffix(&platform->configDirs, "HOME", ""); + platformPathAddEnvSuffix(&platform->configDirs, "HOME", NULL); platformPathAddEnvSuffix(&platform->configDirs, "MINGW_PREFIX", "etc"); } ffPlatformPathAddHome(&platform->configDirs, platform, ".config/"); + platformPathAddKnownFolder(&platform->configDirs, &FOLDERID_ProgramData); platformPathAddKnownFolder(&platform->configDirs, &FOLDERID_RoamingAppData); platformPathAddKnownFolder(&platform->configDirs, &FOLDERID_LocalAppData); ffPlatformPathAddHome(&platform->configDirs, platform, ""); @@ -85,10 +92,11 @@ static void getDataDirs(FFPlatform* platform) { // We are in MSYS2 / Git Bash platformPathAddEnvSuffix(&platform->dataDirs, "HOME", ".local/share/"); - platformPathAddEnvSuffix(&platform->dataDirs, "HOME", ""); + platformPathAddEnvSuffix(&platform->dataDirs, "HOME", NULL); platformPathAddEnvSuffix(&platform->dataDirs, "MINGW_PREFIX", "share"); } ffPlatformPathAddHome(&platform->dataDirs, platform, ".local/share/"); + platformPathAddKnownFolder(&platform->dataDirs, &FOLDERID_ProgramData); platformPathAddKnownFolder(&platform->dataDirs, &FOLDERID_RoamingAppData); platformPathAddKnownFolder(&platform->dataDirs, &FOLDERID_LocalAppData); ffPlatformPathAddHome(&platform->dataDirs, platform, ""); @@ -96,31 +104,31 @@ static void getDataDirs(FFPlatform* platform) static void getUserName(FFPlatform* platform) { - ffStrbufEnsureFree(&platform->userName, 64); - DWORD len = (DWORD) ffStrbufGetFree(&platform->userName); - if(GetUserNameA(platform->userName.chars, &len)) - platform->userName.length = (uint32_t) len; + wchar_t buffer[128]; + DWORD len = sizeof(buffer) / sizeof(*buffer); + if(GetUserNameW(buffer, &len)) + ffStrbufSetWS(&platform->userName, buffer); } static void getHostName(FFPlatform* platform) { - ffStrbufEnsureFree(&platform->hostName, 64); - DWORD len = (DWORD) ffStrbufGetFree(&platform->hostName); - if(GetComputerNameExA(ComputerNameDnsHostname, platform->hostName.chars, &len)) - platform->hostName.length = (uint32_t) len; + wchar_t buffer[128]; + DWORD len = sizeof(buffer) / sizeof(*buffer); + if(GetComputerNameExW(ComputerNameDnsHostname, buffer, &len)) + ffStrbufSetWS(&platform->hostName, buffer); } static void getDomainName(FFPlatform* platform) { - ffStrbufEnsureFree(&platform->domainName, 64); - DWORD len = (DWORD) ffStrbufGetFree(&platform->domainName); - if(GetComputerNameExA(ComputerNameDnsDomain, platform->domainName.chars, &len)) - platform->domainName.length = (uint32_t) len; + wchar_t buffer[128]; + DWORD len = sizeof(buffer) / sizeof(*buffer); + if(GetComputerNameExW(ComputerNameDnsDomain, buffer, &len)) + ffStrbufSetWS(&platform->domainName, buffer); } static void getSystemName(FFPlatform* platform) { - ffStrbufAppendS(&platform->systemName, "Windows_NT"); + ffStrbufAppendS(&platform->systemName, getenv("OS")); } static void getSystemReleaseAndVersion(FFPlatform* platform) diff --git a/src/util/smbiosHelper.c b/src/util/smbiosHelper.c new file mode 100644 index 0000000000..1033ec8800 --- /dev/null +++ b/src/util/smbiosHelper.c @@ -0,0 +1,26 @@ +#include "smbiosHelper.h" + +bool ffIsSmbiosValueSet(FFstrbuf* value) +{ + return + value->length > 0 && + !ffStrbufStartsWithIgnCaseS(value, "To be filled") && + !ffStrbufStartsWithIgnCaseS(value, "To be set") && + !ffStrbufStartsWithIgnCaseS(value, "OEM") && + !ffStrbufStartsWithIgnCaseS(value, "O.E.M.") && + !ffStrbufIgnCaseEqualS(value, "None") && + !ffStrbufIgnCaseEqualS(value, "System Product") && + !ffStrbufIgnCaseEqualS(value, "System Product Name") && + !ffStrbufIgnCaseEqualS(value, "System Product Version") && + !ffStrbufIgnCaseEqualS(value, "System Name") && + !ffStrbufIgnCaseEqualS(value, "System Version") && + !ffStrbufIgnCaseEqualS(value, "Default string") && + !ffStrbufIgnCaseEqualS(value, "Undefined") && + !ffStrbufIgnCaseEqualS(value, "Not Specified") && + !ffStrbufIgnCaseEqualS(value, "Not Applicable") && + !ffStrbufIgnCaseEqualS(value, "INVALID") && + !ffStrbufIgnCaseEqualS(value, "Type1ProductConfigId") && + !ffStrbufIgnCaseEqualS(value, "All Series") && + !ffStrbufIgnCaseEqualS(value, "N/A") + ; +} diff --git a/src/util/smbiosHelper.h b/src/util/smbiosHelper.h new file mode 100644 index 0000000000..9be3e3120b --- /dev/null +++ b/src/util/smbiosHelper.h @@ -0,0 +1,15 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_SMBIOSVALUEHELPER +#define FASTFETCH_INCLUDED_SMBIOSVALUEHELPER + +#include "util/FFstrbuf.h" + +bool ffIsSmbiosValueSet(FFstrbuf* value); +static inline void ffCleanUpSmbiosValue(FFstrbuf* value) +{ + if (!ffIsSmbiosValueSet(value)) + ffStrbufClear(value); +} + +#endif \ No newline at end of file diff --git a/src/util/stringUtils.c b/src/util/stringUtils.c index 703c81a454..07a3bd1014 100644 --- a/src/util/stringUtils.c +++ b/src/util/stringUtils.c @@ -1,6 +1,5 @@ #include "stringUtils.h" -#include #include bool ffStrSet(const char* str) diff --git a/src/util/stringUtils.h b/src/util/stringUtils.h index 7c2475353d..80894ad26f 100644 --- a/src/util/stringUtils.h +++ b/src/util/stringUtils.h @@ -5,8 +5,38 @@ #include #include +#include bool ffStrSet(const char* str); bool ffStrHasNChars(const char* str, char c, uint32_t n); +static inline bool ffStrStartsWithIgnCase(const char* str, const char* compareTo) +{ + return strncasecmp(str, compareTo, strlen(compareTo)) == 0; +} + +static inline bool ffStrEqualsIgnCase(const char* str, const char* compareTo) +{ + return strcasecmp(str, compareTo) == 0; +} + +static inline bool ffStrStartsWith(const char* str, const char* compareTo) +{ + return strncmp(str, compareTo, strlen(compareTo)) == 0; +} + +static inline bool ffStrEndsWith(const char* str, const char* compareTo) +{ + size_t strLength = strlen(str); + size_t compareToLength = strlen(compareTo); + if (strLength < compareToLength) + return false; + return memcmp(str + strLength - compareToLength, compareTo, compareToLength) == 0; +} + +static inline bool ffStrEquals(const char* str, const char* compareTo) +{ + return strcmp(str, compareTo) == 0; +} + #endif diff --git a/src/util/unused.h b/src/util/unused.h new file mode 100644 index 0000000000..fbc0e93e37 --- /dev/null +++ b/src/util/unused.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_UNUSED +#define FASTFETCH_INCLUDED_UNUSED + +static inline void ffUnused(int dummy, ...) { (void) dummy; } +#define FF_UNUSED(...) ffUnused(0, __VA_ARGS__); +#define FF_MAYBE_UNUSED __attribute__ ((__unused__)) + +#endif diff --git a/src/util/wcwidth.c b/src/util/wcwidth.c new file mode 100644 index 0000000000..7abd26f98a --- /dev/null +++ b/src/util/wcwidth.c @@ -0,0 +1,314 @@ +/* + * This is an implementation of wcwidth() and wcswidth() (defined in + * IEEE Std 1002.1-2001) for Unicode. + * + * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html + * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html + * + * In fixed-width output devices, Latin characters all occupy a single + * "cell" position of equal width, whereas ideographic CJK characters + * occupy two such cells. Interoperability between terminal-line + * applications and (teletype-style) character terminals using the + * UTF-8 encoding requires agreement on which character should advance + * the cursor by how many cell positions. No established formal + * standards exist at present on which Unicode character shall occupy + * how many cell positions on character terminals. These routines are + * a first attempt of defining such behavior based on simple rules + * applied to data provided by the Unicode Consortium. + * + * For some graphical characters, the Unicode standard explicitly + * defines a character-cell width via the definition of the East Asian + * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes. + * In all these cases, there is no ambiguity about which width a + * terminal shall use. For characters in the East Asian Ambiguous (A) + * class, the width choice depends purely on a preference of backward + * compatibility with either historic CJK or Western practice. + * Choosing single-width for these characters is easy to justify as + * the appropriate long-term solution, as the CJK practice of + * displaying these characters as double-width comes from historic + * implementation simplicity (8-bit encoded characters were displayed + * single-width and 16-bit ones double-width, even for Greek, + * Cyrillic, etc.) and not any typographic considerations. + * + * Much less clear is the choice of width for the Not East Asian + * (Neutral) class. Existing practice does not dictate a width for any + * of these characters. It would nevertheless make sense + * typographically to allocate two character cells to characters such + * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be + * represented adequately with a single-width glyph. The following + * routines at present merely assign a single-cell width to all + * neutral characters, in the interest of simplicity. This is not + * entirely satisfactory and should be reconsidered before + * establishing a formal standard in this area. At the moment, the + * decision which Not East Asian (Neutral) characters should be + * represented by double-width glyphs cannot yet be answered by + * applying a simple rule from the Unicode database content. Setting + * up a proper standard for the behavior of UTF-8 character terminals + * will require a careful analysis not only of each Unicode character, + * but also of each presentation form, something the author of these + * routines has avoided to do so far. + * + * http://www.unicode.org/unicode/reports/tr11/ + * + * Markus Kuhn -- 2007-05-26 (Unicode 5.0) + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted. The author + * disclaims all warranties with regard to this software. + * + * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c + */ + +#include + +struct interval { + int first; + int last; +}; + +/* auxiliary function for binary search in interval table */ +static int bisearch(wchar_t ucs, const struct interval *table, int max) { + int min = 0; + int mid; + + if (ucs < table[0].first || ucs > table[max].last) + return 0; + while (max >= min) { + mid = (min + max) / 2; + if (ucs > table[mid].last) + min = mid + 1; + else if (ucs < table[mid].first) + max = mid - 1; + else + return 1; + } + + return 0; +} + + +/* The following two functions define the column width of an ISO 10646 + * character as follows: + * + * - The null character (U+0000) has a column width of 0. + * + * - Other C0/C1 control characters and DEL will lead to a return + * value of -1. + * + * - Non-spacing and enclosing combining characters (general + * category code Mn or Me in the Unicode database) have a + * column width of 0. + * + * - SOFT HYPHEN (U+00AD) has a column width of 1. + * + * - Other format characters (general category code Cf in the Unicode + * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0. + * + * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) + * have a column width of 0. + * + * - Spacing characters in the East Asian Wide (W) or East Asian + * Full-width (F) category as defined in Unicode Technical + * Report #11 have a column width of 2. + * + * - All remaining characters (including all printable + * ISO 8859-1 and WGL4 characters, Unicode control characters, + * etc.) have a column width of 1. + * + * This implementation assumes that wchar_t characters are encoded + * in ISO 10646. + */ + +int mk_wcwidth(wchar_t ucs) +{ + /* sorted list of non-overlapping intervals of non-spacing characters */ + /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ + static const struct interval combining[] = { + { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 }, + { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, + { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 }, + { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, + { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, + { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 }, + { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, + { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, + { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, + { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, + { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, + { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, + { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, + { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, + { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D }, + { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, + { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, + { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC }, + { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, + { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, + { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, + { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, + { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, + { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, + { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, + { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, + { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, + { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, + { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F }, + { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 }, + { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, + { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, + { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, + { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, + { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, + { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, + { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 }, + { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F }, + { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, + { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, + { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, + { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, + { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 }, + { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, + { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, + { 0xE0100, 0xE01EF } + }; + + /* test for 8-bit control characters */ + if (ucs == 0) + return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return -1; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, combining, + sizeof(combining) / sizeof(struct interval) - 1)) + return 0; + + /* if we arrive here, ucs is not a combining or C0/C1 control character */ + + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + ucs == 0x2329 || ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && + ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + +#ifndef _WIN32 // sizeof(wchar_t) == 2 + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd) || +#endif + 0 + )); +} + + +int mk_wcswidth(const wchar_t *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = mk_wcwidth(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} + + +/* + * The following functions are the same as mk_wcwidth() and + * mk_wcswidth(), except that spacing characters in the East Asian + * Ambiguous (A) category as defined in Unicode Technical Report #11 + * have a column width of 2. This variant might be useful for users of + * CJK legacy encodings who want to migrate to UCS without changing + * the traditional terminal character-width behaviour. It is not + * otherwise recommended for general use. + */ +int mk_wcwidth_cjk(wchar_t ucs) +{ + /* sorted list of non-overlapping intervals of East Asian Ambiguous + * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */ + static const struct interval ambiguous[] = { + { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 }, + { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 }, + { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 }, + { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 }, + { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED }, + { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA }, + { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 }, + { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B }, + { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 }, + { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 }, + { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 }, + { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE }, + { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 }, + { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA }, + { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 }, + { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, + { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, + { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 }, + { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 }, + { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 }, + { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 }, + { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 }, + { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 }, + { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 }, + { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC }, + { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 }, + { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 }, + { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 }, + { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 }, + { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 }, + { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 }, + { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B }, + { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 }, + { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 }, + { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E }, + { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 }, + { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 }, + { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F }, + { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, + { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, + { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B }, + { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, + { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, + { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, + { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, + { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 }, + { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 }, + { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 }, + { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 }, + { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F }, + { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF }, + { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD } + }; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, ambiguous, + sizeof(ambiguous) / sizeof(struct interval) - 1)) + return 2; + + return mk_wcwidth(ucs); +} + + +int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = mk_wcwidth_cjk(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} diff --git a/src/util/wcwidth.h b/src/util/wcwidth.h new file mode 100644 index 0000000000..eaeceed221 --- /dev/null +++ b/src/util/wcwidth.h @@ -0,0 +1,21 @@ +#pragma once + +#ifndef FF_INCLUDED_UTIL_WCWIDTH_H +#define FF_INCLUDED_UTIL_WCWIDTH_H + +#include + +#ifdef FF_HAVE_WCWIDTH +static inline int mk_wcwidth(wchar_t ucs) { + return wcwidth(ucs); +} +static inline int mk_wcswidth(const wchar_t *pwcs, size_t n) { + return wcswidth(pwcs, n); +} +#else +// https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c +int mk_wcwidth(wchar_t ucs); +int mk_wcswidth(const wchar_t *pwcs, size_t n); +#endif + +#endif diff --git a/src/util/windows/com.cpp b/src/util/windows/com.cpp index c11cccf955..43c4a5a496 100644 --- a/src/util/windows/com.cpp +++ b/src/util/windows/com.cpp @@ -6,7 +6,7 @@ //https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer //https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes -static void CoUninitializeWrap() +static void CoUninitializeWrap(void) { CoUninitialize(); } diff --git a/src/util/windows/registry.c b/src/util/windows/registry.c index 0a80781d34..998bfaf3cb 100644 --- a/src/util/windows/registry.c +++ b/src/util/windows/registry.c @@ -1,99 +1,156 @@ -#include "registry.h" -#include "unicode.h" -#include "util/mallocHelper.h" - -static const char* hKey2Str(HKEY hKey) -{ - #define HKEY_CASE(compareKey) if(hKey == compareKey) return #compareKey; - HKEY_CASE(HKEY_CLASSES_ROOT) - HKEY_CASE(HKEY_CURRENT_USER) - HKEY_CASE(HKEY_LOCAL_MACHINE) - HKEY_CASE(HKEY_USERS) - HKEY_CASE(HKEY_PERFORMANCE_DATA) - HKEY_CASE(HKEY_PERFORMANCE_TEXT) - HKEY_CASE(HKEY_PERFORMANCE_NLSTEXT) - HKEY_CASE(HKEY_CURRENT_CONFIG) - HKEY_CASE(HKEY_DYN_DATA) - HKEY_CASE(HKEY_CURRENT_USER_LOCAL_SETTINGS) - #undef HKEY_CASE - - return "UNKNOWN"; -} - -bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrbuf* error) -{ - if(RegOpenKeyExW(hKey, subKeyW, 0, KEY_READ, result) != ERROR_SUCCESS) - { - if(error) - { - FF_STRBUF_AUTO_DESTROY subKeyA = ffStrbufCreateWS(subKeyW); - ffStrbufAppendF(error, "RegOpenKeyExW(%s\\%s) failed", hKey2Str(hKey), subKeyA.chars); - } - return false; - } - return true; -} - -bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error) -{ - DWORD bufSize; //with tailing '\0' - if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, NULL, &bufSize) != ERROR_SUCCESS) - { - if(error) - { - if(!valueNameW) - valueNameW = L"(default)"; - FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); - ffStrbufAppendF(error, "RegGetValueW(%s, NULL, RRF_RT_REG_SZ) failed", valueNameA.chars); - } - return false; - } - wchar_t* FF_AUTO_FREE resultW = (wchar_t*)malloc(bufSize); - if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, resultW, &bufSize) != ERROR_SUCCESS) - { - if(error) - { - if(!valueNameW) - valueNameW = L"(default)"; - FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); - ffStrbufAppendF(error, "RegGetValueW(%s, result, RRF_RT_REG_SZ) failed", valueNameA.chars); - } - return false; - } - ffStrbufSetWS(result, resultW); - return true; -} - -bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error) -{ - DWORD bufSize = sizeof(*result); - if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_DWORD, NULL, result, &bufSize) != ERROR_SUCCESS) - { - if(error) - { - if(!valueNameW) - valueNameW = L"(default)"; - FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); - ffStrbufAppendF(error, "RegGetValueW(%s, result, RRF_RT_DWORD) failed", valueNameA.chars); - } - return false; - } - return true; -} - -bool ffRegReadUint64(HKEY hKey, const wchar_t* valueNameW, uint64_t* result, FFstrbuf* error) -{ - DWORD bufSize = sizeof(*result); - if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_QWORD, NULL, result, &bufSize) != ERROR_SUCCESS) - { - if(error) - { - if(!valueNameW) - valueNameW = L"(default)"; - FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); - ffStrbufAppendF(error, "RegGetValueW(%s, result, RRF_RT_QWORD) failed", valueNameA.chars); - } - return false; - } - return true; -} +#include "registry.h" +#include "unicode.h" +#include "util/mallocHelper.h" + +static const char* hKey2Str(HKEY hKey) +{ + #define HKEY_CASE(compareKey) if(hKey == compareKey) return #compareKey; + HKEY_CASE(HKEY_CLASSES_ROOT) + HKEY_CASE(HKEY_CURRENT_USER) + HKEY_CASE(HKEY_LOCAL_MACHINE) + HKEY_CASE(HKEY_USERS) + HKEY_CASE(HKEY_PERFORMANCE_DATA) + HKEY_CASE(HKEY_PERFORMANCE_TEXT) + HKEY_CASE(HKEY_PERFORMANCE_NLSTEXT) + HKEY_CASE(HKEY_CURRENT_CONFIG) + HKEY_CASE(HKEY_DYN_DATA) + HKEY_CASE(HKEY_CURRENT_USER_LOCAL_SETTINGS) + #undef HKEY_CASE + + return "UNKNOWN"; +} + +bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrbuf* error) +{ + if(RegOpenKeyExW(hKey, subKeyW, 0, KEY_READ, result) != ERROR_SUCCESS) + { + if(error) + { + FF_STRBUF_AUTO_DESTROY subKeyA = ffStrbufCreateWS(subKeyW); + ffStrbufAppendF(error, "RegOpenKeyExW(%s\\%s) failed", hKey2Str(hKey), subKeyA.chars); + } + return false; + } + return true; +} + +bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error) +{ + DWORD bufSize; //with tailing '\0' + if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, NULL, &bufSize) != ERROR_SUCCESS) + { + if(error) + { + if(!valueNameW) + valueNameW = L"(default)"; + FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); + ffStrbufAppendF(error, "RegGetValueW(%s, NULL, RRF_RT_REG_SZ) failed", valueNameA.chars); + } + return false; + } + wchar_t* FF_AUTO_FREE resultW = (wchar_t*)malloc(bufSize); + if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_SZ, NULL, resultW, &bufSize) != ERROR_SUCCESS) + { + if(error) + { + if(!valueNameW) + valueNameW = L"(default)"; + FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); + ffStrbufAppendF(error, "RegGetValueW(%s, result, RRF_RT_REG_SZ) failed", valueNameA.chars); + } + return false; + } + ffStrbufSetWS(result, resultW); + return true; +} + +bool ffRegReadData(HKEY hKey, const wchar_t* valueNameW, uint8_t** result, uint32_t* length, FFstrbuf* error) +{ + assert(result && length); + DWORD bufSize = 0; + LONG err = RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_BINARY, NULL, NULL, &bufSize); + if(err != ERROR_SUCCESS || bufSize == 0) + { + if(error) + { + if(!valueNameW) + valueNameW = L"(default)"; + FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); + ffStrbufAppendF(error, "RegGetValueW(%s, NULL, RRF_RT_REG_BINARY, NULL, NULL, &bufSize) failed", valueNameA.chars); + } + return false; + } + + uint8_t* buf = (uint8_t*) malloc(bufSize); + err = RegGetValueW(hKey, NULL, valueNameW, RRF_RT_REG_BINARY, NULL, buf, &bufSize); + if(err != ERROR_SUCCESS) + { + if(error) + { + if(!valueNameW) + valueNameW = L"(default)"; + FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); + ffStrbufAppendF(error, "RegGetValueW(%s, NULL, RRF_RT_REG_BINARY, NULL, length) failed", valueNameA.chars); + } + free(buf); + return false; + } + *result = buf; + *length = bufSize; + return true; +} + +bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error) +{ + DWORD bufSize = sizeof(*result); + if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_DWORD, NULL, result, &bufSize) != ERROR_SUCCESS) + { + if(error) + { + if(!valueNameW) + valueNameW = L"(default)"; + FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); + ffStrbufAppendF(error, "RegGetValueW(%s, result, RRF_RT_DWORD) failed", valueNameA.chars); + } + return false; + } + return true; +} + +bool ffRegReadUint64(HKEY hKey, const wchar_t* valueNameW, uint64_t* result, FFstrbuf* error) +{ + DWORD bufSize = sizeof(*result); + if(RegGetValueW(hKey, NULL, valueNameW, RRF_RT_QWORD, NULL, result, &bufSize) != ERROR_SUCCESS) + { + if(error) + { + if(!valueNameW) + valueNameW = L"(default)"; + FF_STRBUF_AUTO_DESTROY valueNameA = ffStrbufCreateWS(valueNameW); + ffStrbufAppendF(error, "RegGetValueW(%s, result, RRF_RT_QWORD) failed", valueNameA.chars); + } + return false; + } + return true; +} + +bool ffRegGetSubKey(HKEY hKey, uint32_t index, FFstrbuf* result, FFstrbuf* error) +{ + DWORD bufSize = 0; + if(RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, &bufSize, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + { + if (error) + ffStrbufAppendS(error, "RegQueryInfoKeyW(hKey) failed"); + return false; + } + ++bufSize; + wchar_t* FF_AUTO_FREE resultW = (wchar_t*) malloc(bufSize * sizeof(*resultW)); + if(RegEnumKeyExW(hKey, index, resultW, &bufSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + { + if (error) + ffStrbufAppendF(error, "RegEnumKeyExW(hKey, %u) failed", (unsigned) index); + return false; + } + ffStrbufSetWS(result, resultW); + return true; +} diff --git a/src/util/windows/registry.h b/src/util/windows/registry.h index 44fd5c4308..42dd08aaf9 100644 --- a/src/util/windows/registry.h +++ b/src/util/windows/registry.h @@ -17,7 +17,9 @@ static inline void wrapRegCloseKey(HKEY* phKey) bool ffRegOpenKeyForRead(HKEY hKey, const wchar_t* subKeyW, HKEY* result, FFstrbuf* error); bool ffRegReadStrbuf(HKEY hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error); +bool ffRegReadData(HKEY hKey, const wchar_t* valueNameW, uint8_t** result, uint32_t* length, FFstrbuf* error); bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error); bool ffRegReadUint64(HKEY hKey, const wchar_t* valueNameW, uint64_t* result, FFstrbuf* error); +bool ffRegGetSubKey(HKEY hKey, uint32_t index, FFstrbuf* result, FFstrbuf* error); #endif diff --git a/src/util/windows/unicode.hpp b/src/util/windows/unicode.hpp new file mode 100644 index 0000000000..18441a50da --- /dev/null +++ b/src/util/windows/unicode.hpp @@ -0,0 +1,25 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_UNICODE_HPP +#define FASTFETCH_INCLUDED_UNICODE_HPP + +#ifdef __cplusplus + +extern "C" { +#include "unicode.h" +} + +#include + +static inline void ffStrbufSetWSV(FFstrbuf* result, const std::wstring_view source) +{ + return ffStrbufSetNWS(result, (uint32_t) source.size(), source.data()); +} + +#else + + #error Must be included in C++ source file + +#endif + +#endif diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index b8e576fd50..a131bceb51 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -1,5 +1,6 @@ #include "wmi.hpp" #include "util/windows/com.hpp" +#include "util/windows/unicode.hpp" #include #include @@ -11,9 +12,9 @@ namespace struct bstr_t { explicit bstr_t(const wchar_t* str) noexcept: _bstr(SysAllocString(str)) {} - ~bstr_t() noexcept { SysFreeString(_bstr); } - explicit operator const wchar_t*() const noexcept { return _bstr; } - operator BSTR() const noexcept { return _bstr; } + ~bstr_t(void) noexcept { SysFreeString(_bstr); } + explicit operator const wchar_t*(void) const noexcept { return _bstr; } + operator BSTR(void) const noexcept { return _bstr; } private: BSTR _bstr; @@ -125,27 +126,11 @@ FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace } } -static void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) -{ - int len = (int)SysStringLen(bstr); - if(len <= 0) - { - ffStrbufClear(strbuf); - return; - } - int size_needed = WideCharToMultiByte(CP_UTF8, 0, bstr, len, nullptr, 0, nullptr, nullptr); - ffStrbufEnsureFree(strbuf, (uint32_t)size_needed); - WideCharToMultiByte(CP_UTF8, 0, bstr, len, strbuf->chars, size_needed, nullptr, nullptr); - strbuf->length = (uint32_t)size_needed; - strbuf->chars[size_needed] = '\0'; -} - bool FFWmiRecord::getString(const wchar_t* key, FFstrbuf* strbuf) { bool result = true; - VARIANT vtProp; - VariantInit(&vtProp); + FFWmiVariant vtProp; CIMTYPE type; if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr)) || vtProp.vt != VT_BSTR) @@ -168,11 +153,11 @@ bool FFWmiRecord::getString(const wchar_t* key, FFstrbuf* strbuf) else if(FAILED(pDateTime->GetFileTime(VARIANT_TRUE, &dateStr))) result = false; else - ffBstrToStrbuf(dateStr, strbuf); + ffStrbufSetNWS(strbuf, SysStringLen(dateStr), dateStr); } else { - ffBstrToStrbuf(vtProp.bstrVal, strbuf); + ffStrbufSetNWS(strbuf, SysStringLen(vtProp.bstrVal), vtProp.bstrVal); } break; @@ -180,13 +165,12 @@ bool FFWmiRecord::getString(const wchar_t* key, FFstrbuf* strbuf) ffStrbufAppendS(strbuf, vtProp.pcVal); break; - case VT_LPWSTR: // TODO + case VT_LPWSTR: default: - result = false; + ffStrbufSetWS(strbuf, vtProp.bstrVal); break; } } - VariantClear(&vtProp); return result; } @@ -194,8 +178,7 @@ bool FFWmiRecord::getSigned(const wchar_t* key, int64_t* integer) { bool result = true; - VARIANT vtProp; - VariantInit(&vtProp); + FFWmiVariant vtProp; CIMTYPE type; if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr))) @@ -221,7 +204,6 @@ bool FFWmiRecord::getSigned(const wchar_t* key, int64_t* integer) default: *integer = 0; result = false; } } - VariantClear(&vtProp); return result; } @@ -229,8 +211,7 @@ bool FFWmiRecord::getUnsigned(const wchar_t* key, uint64_t* integer) { bool result = true; - VARIANT vtProp; - VariantInit(&vtProp); + FFWmiVariant vtProp; if(FAILED(obj->Get(key, 0, &vtProp, nullptr, nullptr))) { @@ -255,7 +236,6 @@ bool FFWmiRecord::getUnsigned(const wchar_t* key, uint64_t* integer) default: *integer = 0; result = false; } } - VariantClear(&vtProp); return result; } @@ -263,8 +243,7 @@ bool FFWmiRecord::getReal(const wchar_t* key, double* real) { bool result = true; - VARIANT vtProp; - VariantInit(&vtProp); + FFWmiVariant vtProp; if(FAILED(obj->Get(key, 0, &vtProp, nullptr, nullptr))) { @@ -291,6 +270,5 @@ bool FFWmiRecord::getReal(const wchar_t* key, double* real) default: *real = NAN; result = false; } } - VariantClear(&vtProp); return result; } diff --git a/src/util/windows/wmi.hpp b/src/util/windows/wmi.hpp index 32ce0bcb47..29ff621a02 100644 --- a/src/util/windows/wmi.hpp +++ b/src/util/windows/wmi.hpp @@ -6,11 +6,14 @@ #ifdef __cplusplus extern "C" { - #include "util/FFstrbuf.h" + #include "fastfetch.h" } #include #include +#include +#include +#include enum class FFWmiNamespace { CIMV2, @@ -18,8 +21,131 @@ enum class FFWmiNamespace { LAST, }; -enum { - FF_WMI_QUERY_TIMEOUT = 5000 +struct FFWmiVariant: VARIANT { + explicit FFWmiVariant() { VariantInit(this); } + ~FFWmiVariant() { VariantClear(this); } + + FFWmiVariant(const FFWmiVariant&) = delete; + FFWmiVariant(FFWmiVariant&&); // don't define it to enforce NRVO optimization + + bool hasValue() { + return this->vt != VT_EMPTY; + } + + explicit operator bool() { + return this->hasValue(); + } + + template T get(); + + // boolean + template <> bool get() { + assert(this->vt == VT_BOOL); + return this->boolVal != VARIANT_FALSE; + } + + // signed + template <> int8_t get() { + assert(this->vt == VT_I1); + return this->cVal; + } + template <> int16_t get() { + assert(vt == VT_I2); + return this->iVal; + } + template <> int32_t get() { + assert(this->vt == VT_I4 || vt == VT_INT); + return this->intVal; + } + template <> int64_t get() { + assert(this->vt == VT_I8); + return this->llVal; + } + + // unsigned + template <> uint8_t get() { + assert(this->vt == VT_UI1); + return this->bVal; + } + template <> uint16_t get() { + assert(this->vt == VT_UI2); + return this->uiVal; + } + template <> uint32_t get() { + assert(this->vt == VT_UI4 || vt == VT_UINT); + return this->uintVal; + } + template <> uint64_t get() { + assert(this->vt == VT_UI8); + return this->ullVal; + } + + // decimal + template <> float get() { + assert(this->vt == VT_R4); + return this->fltVal; + } + template <> double get() { + assert(this->vt == VT_R8); + return this->dblVal; + } + + // string + template <> std::string_view get() { + assert(this->vt == VT_LPSTR); + return this->pcVal; + } + template <> std::wstring_view get() { + assert(this->vt == VT_BSTR || this->vt == VT_LPWSTR); + if (this->vt == VT_LPWSTR) + return this->bstrVal; + else + return { this->bstrVal, SysStringLen(this->bstrVal) }; + } + + // array signed + template <> std::pair get() { + assert(this->vt & VT_ARRAY); + assert((this->vt & ~VT_ARRAY) == VT_I1); + return std::make_pair((int8_t*)this->parray->pvData, this->parray->cDims); + } + template <> std::pair get() { + assert(this->vt & VT_ARRAY); + assert((this->vt & ~VT_ARRAY) == VT_I2); + return std::make_pair((int16_t*)this->parray->pvData, this->parray->cDims); + } + template <> std::pair get() { + assert(this->vt & VT_ARRAY); + assert((this->vt & ~VT_ARRAY) == VT_I4); + return std::make_pair((int32_t*)this->parray->pvData, this->parray->cDims); + } + template <> std::pair get() { + assert(this->vt & VT_ARRAY); + assert((this->vt & ~VT_ARRAY) == VT_I8); + return std::make_pair((int64_t*)this->parray->pvData, this->parray->cDims); + } + + // array unsigned + template <> std::pair get() { + assert(this->vt & VT_ARRAY); + assert((this->vt & ~VT_ARRAY) == VT_UI1); + return std::make_pair((uint8_t*)this->parray->pvData, this->parray->cDims); + } + template <> std::pair get() { + assert(this->vt & VT_ARRAY); + assert((this->vt & ~VT_ARRAY) == VT_UI2); + return std::make_pair((uint16_t*)this->parray->pvData, this->parray->cDims); + } + template <> std::pair get() { + assert(this->vt & VT_ARRAY); + assert((this->vt & ~VT_ARRAY) == VT_UI4); + return std::make_pair((uint32_t*)this->parray->pvData, this->parray->cDims); + } + template <> std::pair get() { + assert(this->vt & VT_ARRAY); + assert((this->vt & ~VT_ARRAY) == VT_UI8); + return std::make_pair((uint64_t*)this->parray->pvData, this->parray->cDims); + } }; struct FFWmiRecord @@ -30,7 +156,7 @@ struct FFWmiRecord if(!pEnumerator) return; ULONG ret; - bool ok = SUCCEEDED(pEnumerator->Next(FF_WMI_QUERY_TIMEOUT, 1, &obj, &ret)) && ret; + bool ok = SUCCEEDED(pEnumerator->Next(instance.config.wmiTimeout, 1, &obj, &ret)) && ret; if(!ok) obj = nullptr; } FFWmiRecord(const FFWmiRecord&) = delete; @@ -48,6 +174,11 @@ struct FFWmiRecord bool getSigned(const wchar_t* key, int64_t* integer); bool getUnsigned(const wchar_t* key, uint64_t* integer); bool getReal(const wchar_t* key, double* real); + FFWmiVariant get(const wchar_t* key) { + FFWmiVariant result; + obj->Get(key, 0, &result, nullptr, nullptr); + return result; + } }; struct FFWmiQuery diff --git a/tests/list.c b/tests/list.c index db4db544a8..5119b046f9 100644 --- a/tests/list.c +++ b/tests/list.c @@ -87,6 +87,12 @@ int main(void) n = 999; VERIFY(ffListFirstIndexComp(&list, &n, numEqualsAdapter) == list.length); + // ffListContains + n = 10; + VERIFY(ffListContains(&list, &n, numEqualsAdapter)); + n = 999; + VERIFY(!ffListContains(&list, &n, numEqualsAdapter)); + //shift VERIFY(ffListShift(&list, &n)); VERIFY(n == 1); @@ -108,6 +114,13 @@ int main(void) VERIFY(list.capacity == 0); VERIFY(list.length == 0); + { + FF_LIST_AUTO_DESTROY test = ffListCreate(1); + VERIFY(test.elementSize = 1); + VERIFY(test.capacity == 0); + VERIFY(test.length == 0); + } + //Success puts("\033[32mAll tests passed!"FASTFETCH_TEXT_MODIFIER_RESET); } diff --git a/tests/strbuf.c b/tests/strbuf.c index 3d8d3d0574..d35c93e2f6 100644 --- a/tests/strbuf.c +++ b/tests/strbuf.c @@ -28,12 +28,12 @@ int main(void) FFstrbuf strbuf; //destroy 0 - ffStrbufInitA(&strbuf, 0); + ffStrbufInit(&strbuf); ffStrbufDestroy(&strbuf); //initA - ffStrbufInitA(&strbuf, 0); + ffStrbufInit(&strbuf); VERIFY(strbuf.chars[0] == 0); VERIFY(strbuf.allocated == 0); @@ -129,7 +129,7 @@ int main(void) //removeStrings - ffStrbufRemoveStrings(&strbuf, 3, "23", "45", "9"); + ffStrbufRemoveStrings(&strbuf, 3, (const char*[]) { "23", "45", "9" }); VERIFY(strbuf.length == 2); VERIFY(strcmp(strbuf.chars, "16") == 0); @@ -214,8 +214,116 @@ int main(void) ffStrbufReplaceAllC(&strbuf, '1', '-'); VERIFY(ffStrbufEqualS(&strbuf, "-234567890-234567890-234567890-")); + //trim + ffStrbufTrim(&strbuf, '-'); + VERIFY(ffStrbufEqualS(&strbuf, "234567890-234567890-234567890")); + + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateS + { + FF_STRBUF_AUTO_DESTROY testCreate = ffStrbufCreateS("TEST"); + VERIFY(ffStrbufEqualS(&testCreate, "TEST")); + } + + //ffStrbufCreateStatic + ffStrbufInitStatic(&strbuf, "TEST"); + VERIFY(ffStrbufEqualS(&strbuf, "TEST")); + VERIFY(strbuf.length == 4); + VERIFY(strbuf.allocated == 0); + + ffStrbufDestroy(&strbuf); + VERIFY(strbuf.length == 0); + VERIFY(strbuf.allocated == 0); + + //ffStrbufCreateStatic / Allocate + ffStrbufInitStatic(&strbuf, "TEST"); + ffStrbufEnsureFree(&strbuf, 0); + VERIFY(ffStrbufEqualS(&strbuf, "TEST")); + VERIFY(strbuf.length == 4); + VERIFY(strbuf.allocated > 0); + + //ffStrbufCreateStatic / Append + ffStrbufInitStatic(&strbuf, "TEST"); + ffStrbufAppendS(&strbuf, "_TEST"); + VERIFY(ffStrbufEqualS(&strbuf, "TEST_TEST")); + VERIFY(strbuf.length == 9); + VERIFY(strbuf.allocated >= 10); + ffStrbufDestroy(&strbuf); + VERIFY(strbuf.length == 0); + VERIFY(strbuf.allocated == 0); + + //ffStrbufCreateStatic / Clear + ffStrbufInitStatic(&strbuf, "TEST"); + ffStrbufClear(&strbuf); + VERIFY(strbuf.length == 0); + VERIFY(strbuf.allocated == 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Set + ffStrbufInitStatic(&strbuf, "TEST"); // static + ffStrbufSetStatic(&strbuf, "test"); + VERIFY(ffStrbufEqualS(&strbuf, "test")); + VERIFY(strbuf.length == 4); + VERIFY(strbuf.allocated == 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Set + ffStrbufInitS(&strbuf, "TEST"); // allocated + ffStrbufSetStatic(&strbuf, "test"); + VERIFY(ffStrbufEqualS(&strbuf, "test")); + VERIFY(strbuf.length == 4); + VERIFY(strbuf.allocated == 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / TrimL + ffStrbufInitStatic(&strbuf, "_TEST_"); + ffStrbufTrimLeft(&strbuf, '_'); + VERIFY(ffStrbufEqualS(&strbuf, "TEST_")); + VERIFY(strbuf.length == 5); + VERIFY(strbuf.allocated == 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / TrimR + ffStrbufInitStatic(&strbuf, "_TEST_"); + ffStrbufTrimRight(&strbuf, '_'); + VERIFY(ffStrbufEqualS(&strbuf, "_TEST")); + VERIFY(strbuf.length == 5); + VERIFY(strbuf.allocated > 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Substr + ffStrbufInitStatic(&strbuf, "__TEST__"); + ffStrbufRemoveSubstr(&strbuf, 0, 6); + VERIFY(ffStrbufEqualS(&strbuf, "__")); + VERIFY(strbuf.length == 2); + VERIFY(strbuf.allocated > 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Substr + ffStrbufInitStatic(&strbuf, "__TEST__"); + ffStrbufRemoveSubstr(&strbuf, 2, 8); + VERIFY(ffStrbufEqualS(&strbuf, "__")); + VERIFY(strbuf.length == 2); + VERIFY(strbuf.allocated > 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Substr + ffStrbufInitStatic(&strbuf, "__TEST__"); + ffStrbufRemoveSubstr(&strbuf, 2, 6); + VERIFY(ffStrbufEqualS(&strbuf, "____")); + VERIFY(strbuf.length == 4); + VERIFY(strbuf.allocated > 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Substr + ffStrbufInitStatic(&strbuf, "__TEST__"); + ffStrbufReplaceAllC(&strbuf, '_', '-'); + VERIFY(ffStrbufEqualS(&strbuf, "--TEST--")); + VERIFY(strbuf.length == 8); + VERIFY(strbuf.allocated > 0); ffStrbufDestroy(&strbuf); //Success - puts("\033[32mAll tests passed!"FASTFETCH_TEXT_MODIFIER_RESET); + puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET); }