From 234cbadce2ebbca233e6ef7981e3e4a037d92e4b Mon Sep 17 00:00:00 2001 From: damachine Date: Tue, 10 Feb 2026 13:28:26 +0100 Subject: [PATCH 01/10] VERSION: prepare for 2.2.4 release --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5859406..530cdd9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2.3 +2.2.4 From f2e5dd10a79c467c44a9186e968c610ddf3876ef Mon Sep 17 00:00:00 2001 From: damachine Date: Tue, 10 Feb 2026 13:33:52 +0100 Subject: [PATCH 02/10] chore: update git ignore and attributes --- .gitattributes | 36 ++++++++++++++++++++++++++++++++++++ .gitignore | 18 +++++++++--------- 2 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..4a46c20 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,36 @@ +# Automatic line ending normalization +* text=auto + +# Shell scripts always with LF (Unix line endings) +*.sh text eol=lf +*.bash text eol=lf + +# Markdown files +*.md text eol=lf linguist-documentation + +# Configuration files +*.yml text eol=lf +*.yaml text eol=lf +*.cfg text eol=lf +*.conf text eol=lf + +# Git configuration +.gitignore text eol=lf +.gitattributes text eol=lf + +# Documentation +docs/* linguist-documentation +*.md linguist-documentation +README.md linguist-documentation +LICENSE text eol=lf + +# GitHub Workflows/Actions +.github/workflows/* linguist-generated +.github/FUNDING.yml text eol=lf + +# Export behavior (for git archive) +.gitattributes export-ignore +.gitignore export-ignore +.github export-ignore +docs export-ignore +*.md export-ignore diff --git a/.gitignore b/.gitignore index 97fced8..90e6945 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,3 @@ -!VERSION -!.md -!.SRCINFO -!coolerdash.install -!PKGBUILD -!Makefile -!.github -!.gitignore -!.gitattributes coolerdash-bin/ *~ .* @@ -47,3 +38,12 @@ packaging/debian/coolerdash/ packaging/debian/files packaging/debian/*.substvars packaging/debian/*.log +!VERSION +!.md +!.SRCINFO +!coolerdash.install +!PKGBUILD +!Makefile +!.github +!.gitignore +!.gitattributes From 4773462342e5acd3bdb660fa7c041d6a98a2c39b Mon Sep 17 00:00:00 2001 From: damachine Date: Tue, 10 Feb 2026 20:02:18 +0100 Subject: [PATCH 03/10] chore: update aur/PKGBUILD convention --- PKGBUILD | 2 +- aur/PKGBUILD | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/PKGBUILD b/PKGBUILD index 2309d65..f7bc82c 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,4 +1,4 @@ -# Created by: damachin3 (damachine3 at proton dot me) +# Maintainer: damachin3 (damachine3 at proton dot me) # Website: https://github.com/damachine/coolerdash # This PKGBUILD is for building the coolerdash package from local source. diff --git a/aur/PKGBUILD b/aur/PKGBUILD index 6f0dfc2..ef1b2c6 100644 --- a/aur/PKGBUILD +++ b/aur/PKGBUILD @@ -1,5 +1,4 @@ - -# Created by: damachin3 (damachine3 at proton dot me) +# Maintainer: damachin3 (damachine3 at proton dot me) # Website: https://github.com/damachine/coolerdash pkgname=coolerdash-git From 116e079cb90878d050b2a7de96d629dbfb427fc2 Mon Sep 17 00:00:00 2001 From: damachine Date: Tue, 10 Feb 2026 20:28:11 +0100 Subject: [PATCH 04/10] chore: update aur/PKGBUILD convention --- .SRCINFO | 2 +- PKGBUILD | 14 +++++++------- aur/PKGBUILD | 16 ++++++++-------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.SRCINFO b/.SRCINFO index e3f944f..215beed 100644 --- a/.SRCINFO +++ b/.SRCINFO @@ -1,6 +1,6 @@ pkgbase = coolerdash pkgdesc = Monitor telemetry data on an AIO liquid cooler with an integrated LCD display - pkgver = 2.2.2 + pkgver = 2.2.4 pkgrel = 1 url = https://github.com/damachine/coolerdash install = coolerdash.install diff --git a/PKGBUILD b/PKGBUILD index f7bc82c..628bf49 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -29,19 +29,19 @@ build() { # Fetch latest tags if in git repo if git rev-parse --git-dir >/dev/null 2>&1; then echo "Fetching latest tags..." - git fetch --tags 2>/dev/null || true + git fetch --tags fi # Remove all previous tarball builds - rm -rf coolerdash-*.pkg.* || true + rm -rf coolerdash-*.pkg.* # Clean any previous builds if a Makefile exists if [[ -f Makefile || -f GNUmakefile ]]; then - make clean || true + make clean fi - # Build with Arch Linux specific optimizations and C99 compliance - make || return 1 + # Build the project + make # Copy files to srcdir for packaging (fakeroot cannot access startdir) mkdir -p "${srcdir}/bin" "${srcdir}/images" "${srcdir}/man" "${srcdir}/etc/coolercontrol/plugins/coolerdash/ui" "${srcdir}/etc/applications" "${srcdir}/etc/icons" "${srcdir}/etc/udev/rules.d" @@ -67,9 +67,9 @@ check() { # Verify that the binary was created successfully if [[ -f bin/coolerdash ]]; then - echo "Build successful - binary created" + msg "Build successful - binary created" else - echo "ERROR: Binary not found" + error "Build failed - binary not found" return 1 fi } diff --git a/aur/PKGBUILD b/aur/PKGBUILD index ef1b2c6..7899188 100644 --- a/aur/PKGBUILD +++ b/aur/PKGBUILD @@ -27,29 +27,29 @@ pkgver() { build() { # Build inside the checked-out repository - cd "${srcdir}/coolerdash" || return 1 + cd "${srcdir}/coolerdash" # Remove all previous tarball builds - rm -rf coolerdash-*.pkg.* || true + rm -rf coolerdash-*.pkg.* # Clean any previous builds if a Makefile exists if [[ -f Makefile || -f GNUmakefile ]]; then - make clean || true + make clean fi - # Build - make || return 1 + # Build the project + make } check() { # Check in the checked-out repository - cd "${srcdir}/coolerdash" || return 1 + cd "${srcdir}/coolerdash" # Verify that the binary was created successfully if [[ -f bin/coolerdash ]]; then - echo "Build successful - binary created" + msg "Build successful - binary created" else - echo "ERROR: Binary not found" + error "Build failed - binary not found" return 1 fi } From 4b360f177697183e5659609117e7a8e0dd569eb9 Mon Sep 17 00:00:00 2001 From: damachine Date: Tue, 10 Feb 2026 20:41:40 +0100 Subject: [PATCH 05/10] chore: update Makefile convention --- Makefile | 112 +++++++++++++++++++++++++------------------------------ 1 file changed, 51 insertions(+), 61 deletions(-) diff --git a/Makefile b/Makefile index 700f267..8aeec2a 100644 --- a/Makefile +++ b/Makefile @@ -35,26 +35,16 @@ CYAN = \033[0;36m WHITE = \033[1;37m RESET = \033[0m -# Icons (Unicode) -ICON_BUILD = πŸ”¨ -ICON_INSTALL = πŸ“¦ -ICON_SERVICE = βš™οΈ -ICON_SUCCESS = βœ… -ICON_WARNING = ⚠️ -ICON_INFO = ℹ️ -ICON_CLEAN = 🧹 -ICON_UNINSTALL = πŸ—‘οΈ - # Standard Build Target - Standard C99 project structure $(TARGET): $(OBJDIR) $(BINDIR) $(OBJECTS) $(MAIN_SOURCE) @printf "\n$(PURPLE)Manual Installation Check:$(RESET)\n" @printf "If you see errors about 'conflicting files' or manual installation, run 'make uninstall' and remove leftover files in /opt/coolerdash, /etc/coolerdash, /etc/systemd/system/coolerdash.service.\n\n" - @printf "$(ICON_BUILD) $(CYAN)Compiling $(TARGET) (Standard C99 structure)...$(RESET)\n" + @printf "$(CYAN)Compiling $(TARGET) (Standard C99 structure)...$(RESET)\n" @printf "$(BLUE)Structure:$(RESET) src/ include/ build/ bin/\n" @printf "$(BLUE)CFLAGS:$(RESET) $(CFLAGS)\n" @printf "$(BLUE)LIBS:$(RESET) $(LIBS)\n" $(CC) $(CFLAGS) -o $(BINDIR)/$(TARGET) $(MAIN_SOURCE) $(OBJECTS) $(LIBS) - @printf "$(ICON_SUCCESS) $(GREEN)Build successful: $(BINDIR)/$(TARGET)$(RESET)\n" + @printf "$(GREEN)Build successful: $(BINDIR)/$(TARGET)$(RESET)\n" # Create build directory $(OBJDIR): @@ -70,7 +60,7 @@ $(BINDIR): # Compile object files from src/ and subdirectories $(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR) @mkdir -p $(dir $@) - @printf "$(ICON_BUILD) $(YELLOW)Compiling module: $<$(RESET)\n" + @printf "$(YELLOW)Compiling module: $<$(RESET)\n" @$(CC) $(CFLAGS) -MMD -MP -c $< -o $@ -include $(OBJECTS:.o=.d) @@ -93,10 +83,10 @@ banner: # Clean Target clean: $(MAKE) banner - @printf "$(ICON_CLEAN) $(YELLOW)Cleaning up...$(RESET)\n" + @printf "$(YELLOW)Cleaning up...$(RESET)\n" rm -f $(BINDIR)/$(TARGET) $(OBJECTS) *.o rm -rf $(OBJDIR) $(BINDIR) - @printf "$(ICON_SUCCESS) $(GREEN)Cleanup completed$(RESET)\n" + @printf "$(GREEN)Cleanup completed$(RESET)\n" # Detect Linux distro via release files, os-release as fallback detect-distro: @@ -119,47 +109,47 @@ install-deps: @DISTRO=$$($(MAKE) detect-distro); \ case $$DISTRO in \ arch) \ - printf "$(ICON_INSTALL) $(GREEN)Installing dependencies for Arch Linux/Manjaro...$(RESET)\n"; \ + printf "$(GREEN)Installing dependencies for Arch Linux/Manjaro...$(RESET)\n"; \ $(SUDO) pacman -S --needed cairo libcurl-gnutls gcc make pkg-config ttf-roboto jansson || { \ - printf "$(ICON_WARNING) $(RED)Error installing dependencies!$(RESET)\n"; \ + printf "$(RED)Error installing dependencies!$(RESET)\n"; \ printf "$(YELLOW)Please run manually:$(RESET) $(SUDO) pacman -S cairo libcurl-gnutls gcc make pkg-config ttf-roboto jansson\n"; \ exit 1; \ }; \ ;; \ debian) \ - printf "$(ICON_INSTALL) $(GREEN)Installing dependencies for Ubuntu/Debian...$(RESET)\n"; \ + printf "$(GREEN)Installing dependencies for Ubuntu/Debian...$(RESET)\n"; \ $(SUDO) apt update && $(SUDO) apt install -y libcairo2-dev libcurl4-openssl-dev gcc make pkg-config fonts-roboto libjansson-dev || { \ - printf "$(ICON_WARNING) $(RED)Error installing dependencies!$(RESET)\n"; \ + printf "$(RED)Error installing dependencies!$(RESET)\n"; \ printf "$(YELLOW)Please run manually:$(RESET) $(SUDO) apt install libcairo2-dev libcurl4-openssl-dev gcc make pkg-config fonts-roboto libjansson-dev\n"; \ exit 1; \ }; \ ;; \ fedora) \ - printf "$(ICON_INSTALL) $(GREEN)Installing dependencies for Fedora...$(RESET)\n"; \ + printf "$(GREEN)Installing dependencies for Fedora...$(RESET)\n"; \ $(SUDO) dnf install -y cairo-devel libcurl-devel gcc make pkg-config google-roboto-fonts jansson-devel || { \ - printf "$(ICON_WARNING) $(RED)Error installing dependencies!$(RESET)\n"; \ + printf "$(RED)Error installing dependencies!$(RESET)\n"; \ printf "$(YELLOW)Please run manually:$(RESET) $(SUDO) dnf install cairo-devel libcurl-devel gcc make pkg-config google-roboto-fonts jansson-devel\n"; \ exit 1; \ }; \ ;; \ rhel) \ - printf "$(ICON_INSTALL) $(GREEN)Installing dependencies for RHEL/CentOS...$(RESET)\n"; \ + printf "$(GREEN)Installing dependencies for RHEL/CentOS...$(RESET)\n"; \ $(SUDO) yum install -y cairo-devel libcurl-devel gcc make pkg-config google-roboto-fonts jansson-devel || { \ - printf "$(ICON_WARNING) $(RED)Error installing dependencies!$(RESET)\n"; \ + printf "$(RED)Error installing dependencies!$(RESET)\n"; \ printf "$(YELLOW)Please run manually:$(RESET) $(SUDO) yum install cairo-devel libcurl-devel gcc make pkg-config google-roboto-fonts jansson-devel\n"; \ exit 1; \ }; \ ;; \ opensuse) \ - printf "$(ICON_INSTALL) $(GREEN)Installing dependencies for openSUSE...$(RESET)\n"; \ + printf "$(GREEN)Installing dependencies for openSUSE...$(RESET)\n"; \ $(SUDO) zypper install -y cairo-devel libcurl-devel gcc make pkg-config google-roboto-fonts libjansson-devel || { \ - printf "$(ICON_WARNING) $(RED)Error installing dependencies!$(RESET)\n"; \ + printf "$(RED)Error installing dependencies!$(RESET)\n"; \ printf "$(YELLOW)Please run manually:$(RESET) $(SUDO) zypper install cairo-devel libcurl-devel gcc make pkg-config google-roboto-fonts libjansson-devel\n"; \ exit 1; \ }; \ ;; \ *) \ - printf "$(ICON_WARNING) $(RED)Unknown distribution detected!$(RESET)\n"; \ + printf "$(RED)Unknown distribution detected!$(RESET)\n"; \ printf "\n"; \ printf "$(YELLOW)Please install the following dependencies manually:$(RESET)\n"; \ printf "\n"; \ @@ -191,19 +181,19 @@ check-deps: fi; \ done; \ if [ -n "$$MISSING" ]; then \ - printf "$(ICON_WARNING) $(YELLOW)Missing dependencies:$$MISSING$(RESET)\n"; \ + printf "$(YELLOW)Missing dependencies:$$MISSING$(RESET)\n"; \ $(MAKE) install-deps; \ else \ - printf "$(ICON_SUCCESS) $(GREEN)All dependencies found$(RESET)\n"; \ + printf "$(GREEN)All dependencies found$(RESET)\n"; \ fi # Install binary to /usr/libexec, plugin data to /etc/coolercontrol/plugins/coolerdash/ install: check-deps $(TARGET) @printf "\n" - @printf "$(ICON_INSTALL) $(WHITE)═══ COOLERDASH INSTALLATION ═══$(RESET)\n" + @printf "$(WHITE)=== COOLERDASH INSTALLATION ===$(RESET)\n" @printf "\n" @if [ "$(REALOS)" = "yes" ]; then \ - printf "$(ICON_SERVICE) $(CYAN)Migration: Checking for legacy files and services...$(RESET)\n"; \ + printf "$(CYAN)Migration: Checking for legacy files and services...$(RESET)\n"; \ LEGACY_FOUND=0; \ if $(SUDO) systemctl is-active --quiet coolerdash.service 2>/dev/null; then \ $(SUDO) systemctl stop coolerdash.service; \ @@ -258,29 +248,29 @@ install: check-deps $(TARGET) LEGACY_FOUND=1; \ fi; \ if [ "$$LEGACY_FOUND" -eq 1 ]; then \ - printf " $(GREEN)βœ“$(RESET) Legacy cleanup complete\n"; \ + printf " $(GREEN)OK$(RESET) Legacy cleanup complete\n"; \ else \ - printf " $(BLUE)β†’$(RESET) No legacy files found (clean install)\n"; \ + printf " $(BLUE)->$(RESET) No legacy files found (clean install)\n"; \ fi; \ printf "\n"; \ COOLERDASH_COUNT=$$(pgrep -x coolerdash 2>/dev/null | wc -l); \ if [ "$$COOLERDASH_COUNT" -gt 0 ]; then \ - printf "$(ICON_SERVICE) $(CYAN)Terminating running coolerdash process(es)...$(RESET)\n"; \ + printf "$(CYAN)Terminating running coolerdash process(es)...$(RESET)\n"; \ $(SUDO) killall -TERM coolerdash 2>/dev/null || true; \ sleep 2; \ REMAINING_COUNT=$$(pgrep -x coolerdash 2>/dev/null | wc -l); \ if [ "$$REMAINING_COUNT" -gt 0 ]; then \ - printf " $(YELLOW)β†’$(RESET) Force killing $$REMAINING_COUNT remaining process(es)...\n"; \ + printf " $(YELLOW)->$(RESET) Force killing $$REMAINING_COUNT remaining process(es)...\n"; \ $(SUDO) killall -KILL coolerdash 2>/dev/null || true; \ fi; \ - printf " $(GREEN)β†’$(RESET) Processes terminated\n"; \ + printf " $(GREEN)->$(RESET) Processes terminated\n"; \ printf "\n"; \ fi; \ else \ - printf "$(ICON_INFO) $(YELLOW)Migration skipped (CI environment).$(RESET)\n"; \ + printf "$(YELLOW)Migration skipped (CI environment).$(RESET)\n"; \ fi @printf "\n" - @printf "$(ICON_INFO) $(CYAN)Installing plugin files...$(RESET)\n" + @printf "$(CYAN)Installing plugin files...$(RESET)\n" @install -dm755 "$(DESTDIR)/etc/coolercontrol/plugins/coolerdash" @install -Dm755 $(BINDIR)/$(TARGET) "$(DESTDIR)/usr/libexec/coolerdash/coolerdash" @install -m644 $(README) "$(DESTDIR)/etc/coolercontrol/plugins/coolerdash/README.md" @@ -305,30 +295,30 @@ install: check-deps $(TARGET) @printf " $(GREEN)Image:$(RESET) shutdown.png (coolerdash.png)\n" @printf " $(GREEN)Documentation:$(RESET) README.md, LICENSE, CHANGELOG.md, VERSION\n" @printf "\n" - @printf "$(ICON_INFO) $(CYAN)Note: Plugin binary is available at /usr/libexec/coolerdash/coolerdash$(RESET)\\n" + @printf "$(CYAN)Note: Plugin binary is available at /usr/libexec/coolerdash/coolerdash$(RESET)\\n" @printf "\n" - @printf "$(ICON_SERVICE) $(CYAN)Installing documentation...$(RESET)\n" + @printf "$(CYAN)Installing documentation...$(RESET)\n" @install -Dm644 $(MANPAGE) "$(DESTDIR)/usr/share/man/man1/coolerdash.1" @printf " $(GREEN)Manual:$(RESET) $(DESTDIR)/usr/share/man/man1/coolerdash.1\n" - @printf "$(ICON_SERVICE) $(CYAN)Installing license...$(RESET)\n" + @printf "$(CYAN)Installing license...$(RESET)\n" @install -Dm644 LICENSE "$(DESTDIR)/usr/share/licenses/coolerdash/LICENSE" @printf " $(GREEN)License:$(RESET) $(DESTDIR)/usr/share/licenses/coolerdash/LICENSE\n" - @printf "$(ICON_SERVICE) $(CYAN)Installing desktop shortcut...$(RESET)\n" + @printf "$(CYAN)Installing desktop shortcut...$(RESET)\n" @install -Dm644 etc/applications/coolerdash.desktop "$(DESTDIR)/usr/share/applications/coolerdash.desktop" @printf " $(GREEN)Shortcut:$(RESET) $(DESTDIR)/usr/share/applications/coolerdash.desktop\n" - @printf "$(ICON_SERVICE) $(CYAN)Installing icon...$(RESET)\n" + @printf "$(CYAN)Installing icon...$(RESET)\n" @install -Dm644 etc/icons/coolerdash.svg "$(DESTDIR)/usr/share/icons/hicolor/scalable/apps/coolerdash.svg" @printf " $(GREEN)Icon:$(RESET) $(DESTDIR)/usr/share/icons/hicolor/scalable/apps/coolerdash.svg\n" - @printf "$(ICON_SERVICE) $(CYAN)Installing udev rules for USB power management...$(RESET)\n" + @printf "$(CYAN)Installing udev rules for USB power management...$(RESET)\n" @install -Dm644 etc/udev/rules.d/99-coolerdash.rules "$(DESTDIR)/usr/lib/udev/rules.d/99-coolerdash.rules" @printf " $(GREEN)udev rule:$(RESET) $(DESTDIR)/usr/lib/udev/rules.d/99-coolerdash.rules\n" @if [ "$(REALOS)" = "yes" ]; then \ $(SUDO) udevadm control --reload-rules 2>/dev/null || true; \ $(SUDO) udevadm trigger --subsystem-match=usb 2>/dev/null || true; \ - printf " $(GREEN)βœ“$(RESET) USB power management configured\n"; \ + printf " $(GREEN)OK$(RESET) USB power management configured\n"; \ fi @printf "\n" - @printf "$(ICON_SUCCESS) $(WHITE)INSTALLATION SUCCESSFUL$(RESET)\n" + @printf "$(WHITE)INSTALLATION SUCCESSFUL$(RESET)\n" @printf "\n" @printf "$(YELLOW)Next steps:$(RESET)\n" @if [ "$(REALOS)" = "yes" ]; then \ @@ -345,10 +335,10 @@ install: check-deps $(TARGET) # Uninstall Target uninstall: @printf "\n" - @printf "$(ICON_INSTALL) $(WHITE)═══ COOLERDASH UNINSTALLATION ═══$(RESET)\n" + @printf "$(WHITE)=== COOLERDASH UNINSTALLATION ===$(RESET)\n" @printf "\n" @if [ "$(REALOS)" = "yes" ]; then \ - printf "$(ICON_SERVICE) $(CYAN)Stopping and disabling services...$(RESET)\n"; \ + printf "$(CYAN)Stopping and disabling services...$(RESET)\n"; \ $(SUDO) systemctl stop cc-plugin-coolerdash.service >/dev/null 2>&1 || true; \ $(SUDO) systemctl disable cc-plugin-coolerdash.service >/dev/null 2>&1 || true; \ fi @@ -417,12 +407,12 @@ uninstall: @$(SUDO) rm -rf "$(DESTDIR)/usr/share/licenses/coolerdash" @$(SUDO) rm -f "$(DESTDIR)/usr/share/man/man1/coolerdash.1" @$(SUDO) rm -f "$(DESTDIR)/usr/share/applications/coolerdash.desktop" - @printf "$(ICON_CLEAN) $(CYAN)Removing udev rule...$(RESET)\n" + @printf "$(CYAN)Removing udev rule...$(RESET)\n" @$(SUDO) rm -f "$(DESTDIR)/usr/lib/udev/rules.d/99-coolerdash.rules" @if [ "$(REALOS)" = "yes" ]; then \ $(SUDO) udevadm control --reload-rules 2>/dev/null || true; \ $(SUDO) udevadm trigger --subsystem-match=usb 2>/dev/null || true; \ - printf " $(GREEN)βœ“$(RESET) udev rules reloaded\n"; \ + printf " $(GREEN)OK$(RESET) udev rules reloaded\n"; \ fi @$(SUDO) rm -f "$(DESTDIR)/usr/share/icons/hicolor/scalable/apps/coolerdash.svg" @if [ "$(REALOS)" = "yes" ]; then \ @@ -433,50 +423,50 @@ uninstall: $(SUDO) systemctl daemon-reload >/dev/null 2>&1 || true; \ $(SUDO) systemctl restart coolercontrold.service >/dev/null 2>&1 || true; \ fi - @printf "\n$(ICON_SUCCESS) $(GREEN)Uninstallation completed successfully$(RESET)\n" + @printf "\n$(GREEN)Uninstallation completed successfully$(RESET)\n" @printf "\n" # Debug Build debug: CFLAGS += -g -DDEBUG -fsanitize=address debug: LIBS += -fsanitize=address debug: $(TARGET) - @printf "$(ICON_SUCCESS) $(GREEN)Debug build created with AddressSanitizer: $(BINDIR)/$(TARGET)$(RESET)\n" + @printf "$(GREEN)Debug build created with AddressSanitizer: $(BINDIR)/$(TARGET)$(RESET)\n" logs: - @printf "$(ICON_INFO) $(CYAN)Live logs (Ctrl+C to exit):$(RESET)\n" + @printf "$(CYAN)Live logs (Ctrl+C to exit):$(RESET)\n" journalctl -u cc-plugin-coolerdash.service -f # Help help: @printf "\n" - @printf "$(WHITE)════════════════════════════════════════$(RESET)\n" + @printf "$(WHITE)========================================$(RESET)\n" @printf "$(WHITE) COOLERDASH BUILD SYSTEM $(RESET)\n" - @printf "$(WHITE)════════════════════════════════════════$(RESET)\n" + @printf "$(WHITE)========================================$(RESET)\n" @printf "\n" - @printf "$(YELLOW)πŸ”¨ Build Targets:$(RESET)\n" + @printf "$(YELLOW)Build Targets:$(RESET)\n" @printf " $(GREEN)make$(RESET) - Compiles the program\n" @printf " $(GREEN)make clean$(RESET) - Removes compiled files\n" @printf " $(GREEN)make debug$(RESET) - Debug build with AddressSanitizer\n" @printf "\n" - @printf "$(YELLOW)πŸ“¦ Installation:$(RESET)\n" + @printf "$(YELLOW)Installation:$(RESET)\n" @printf " $(GREEN)make install$(RESET) - Installs binary + plugin data + systemd units\n" @printf " $(GREEN)make uninstall$(RESET)- Uninstalls the program\n" @printf "\n" - @printf "$(YELLOW)βš™οΈ Plugin Management:$(RESET)\n" + @printf "$(YELLOW)Plugin Management:$(RESET)\n" @printf " $(GREEN)systemctl enable --now coolercontrold.service$(RESET) - Active CoolerControl service\n" @printf " $(GREEN)systemctl status coolercontrold.service$(RESET) - Shows CoolerControl status\n" @printf " $(GREEN)journalctl -u coolercontrold.service -f$(RESET) - Shows live logs\n" @printf " $(BLUE)Note:$(RESET) CoolerControl automatically manages coolerdash lifecycle\n" @printf " $(BLUE)Shutdown:$(RESET) Plugin automatically displays shutdown.png when stopped\n" @printf "\n" - @printf "$(YELLOW)πŸ“š Documentation:$(RESET)\n" + @printf "$(YELLOW)Documentation:$(RESET)\n" @printf " $(GREEN)man coolerdash$(RESET) - Shows manual page\n" @printf " $(GREEN)make help$(RESET) - Shows this help\n" @printf "\n" - @printf "$(YELLOW)🌍 README:$(RESET)\n" - @printf " $(GREEN)README.md$(RESET) - πŸ‡ΊπŸ‡Έ English (main documentation)\n" + @printf "$(YELLOW)README:$(RESET)\n" + @printf " $(GREEN)README.md$(RESET) - English (main documentation)\n" @printf "\n" - @printf "$(YELLOW)πŸ”„ Version Usage:$(RESET)\n" + @printf "$(YELLOW)Version Usage:$(RESET)\n" @printf " $(GREEN)Program:$(RESET) /usr/libexec/coolerdash/coolerdash [mode]\n" @printf " $(GREEN)Config:$(RESET) /etc/coolercontrol/plugins/coolerdash/config.json\n" @printf " $(GREEN)Web UI:$(RESET) CoolerControl Plugin Settings\n" From 35f136e56383ce856c63c99befa9d9131ad69fff Mon Sep 17 00:00:00 2001 From: damachine Date: Tue, 10 Feb 2026 22:35:49 +0100 Subject: [PATCH 06/10] code: improvments and refactoring --- aur/PKGBUILD | 1 + src/device/config.c | 2 - src/device/config.h | 6 +- src/main.c | 12 +- src/mods/circle.c | 304 ++++++------------------------------------- src/mods/circle.h | 21 --- src/mods/display.c | 227 +++++++++++++++++++++++++++++++- src/mods/display.h | 101 +++++++++++++- src/mods/dual.c | 241 +--------------------------------- src/mods/dual.h | 28 +--- src/srv/cc_conf.h | 8 -- src/srv/cc_sensor.c | 55 ++++++-- src/srv/cc_sensor.h | 6 + tests/test_scaling.c | 2 +- 14 files changed, 423 insertions(+), 591 deletions(-) diff --git a/aur/PKGBUILD b/aur/PKGBUILD index 7899188..96a46c1 100644 --- a/aur/PKGBUILD +++ b/aur/PKGBUILD @@ -21,6 +21,7 @@ sha256sums=('SKIP') # SKIP for git repo source builds pkgver() { cd "${srcdir}/coolerdash" + # Fetch latest tags in git repo git fetch --tags git describe --tags --long --match "v*" | sed -E 's/^v//; s/-([0-9]+)-g/\.r\1.g/; s/-/./g' } diff --git a/src/device/config.c b/src/device/config.c index e0a3015..fb975bc 100644 --- a/src/device/config.c +++ b/src/device/config.c @@ -24,7 +24,6 @@ #include "config.h" #include "../srv/cc_conf.h" -#include "../srv/cc_main.h" // ============================================================================ // Global Logging Implementation @@ -495,7 +494,6 @@ static const char *find_config_json(const char *custom_path) } static const char *possible_paths[] = { - "~/.config/coolerdash/config.json", "/etc/coolercontrol/plugins/coolerdash/config.json", NULL}; diff --git a/src/device/config.h b/src/device/config.h index e7cddf6..a2fdbf6 100644 --- a/src/device/config.h +++ b/src/device/config.h @@ -12,8 +12,8 @@ * @details Config struct, load/save functions, default values. */ -#ifndef PLUGIN_H -#define PLUGIN_H +#ifndef CONFIG_H +#define CONFIG_H // Include necessary headers // cppcheck-suppress-begin missingIncludeSystem @@ -208,4 +208,4 @@ static inline int is_valid_orientation(int orientation) */ int load_plugin_config(Config *config, const char *config_path); -#endif // PLUGIN_H +#endif // CONFIG_H diff --git a/src/main.c b/src/main.c index fcf8c49..df7949b 100644 --- a/src/main.c +++ b/src/main.c @@ -19,8 +19,6 @@ // Include necessary headers // cppcheck-suppress-begin missingIncludeSystem #include -#include -#include #include #include #include @@ -28,7 +26,6 @@ #include #include #include -#include #include #include // cppcheck-suppress-end missingIncludeSystem @@ -42,17 +39,9 @@ // Security and performance constants #define DEFAULT_VERSION "unknown" -#define MAX_ERROR_MSG_LEN 512 -#define MAX_PID_STR_LEN 32 -#define PID_READ_BUFFER_SIZE 64 #define SHUTDOWN_RETRY_COUNT 2 #define VERSION_BUFFER_SIZE 32 -// Define O_NOFOLLOW if not defined (for portability) -#ifndef O_NOFOLLOW -#define O_NOFOLLOW 0 -#endif - /** * @brief Global variables for daemon management. * @details Used for controlling the main daemon loop and shutdown image logic. @@ -750,6 +739,7 @@ static void perform_cleanup(const Config *config) // Close CoolerControl session and free resources cleanup_coolercontrol_session(); + cleanup_sensor_curl_handle(); remove_image_file(config->paths_image_coolerdash); running = 0; diff --git a/src/mods/circle.c b/src/mods/circle.c index 4482f88..adb60de 100644 --- a/src/mods/circle.c +++ b/src/mods/circle.c @@ -15,16 +15,10 @@ // Include necessary headers // cppcheck-suppress-begin missingIncludeSystem #include -#include #include -#include -#include #include -#include #include -#include #include -#include // cppcheck-suppress-end missingIncludeSystem // Include project headers @@ -35,170 +29,12 @@ #include "display.h" #include "circle.h" -// Circle inscribe factor for circular displays (1/√2 β‰ˆ 0.7071) -#ifndef M_SQRT1_2 -#define M_SQRT1_2 0.7071067811865476 -#endif - /** * @brief Global state for sensor alternation (slot-based cycling) */ static int current_slot_index = 0; // 0=up, 1=mid, 2=down static time_t last_switch_time = 0; -/** - * @brief Convert color component to cairo format (0-255 to 0.0-1.0) - */ -static inline double cairo_color_convert(uint8_t color_component) -{ - return color_component / 255.0; -} - -/** - * @brief Set cairo color from Color structure - */ -static inline void set_cairo_color(cairo_t *cr, const Color *color) -{ - cairo_set_source_rgb(cr, cairo_color_convert(color->r), - cairo_color_convert(color->g), - cairo_color_convert(color->b)); -} - -/** - * @brief Calculate temperature fill width with bounds checking - */ -static inline int calculate_temp_fill_width(float temp_value, int max_width, - float max_temp) -{ - if (temp_value <= 0.0f) - return 0; - - const float ratio = fminf(temp_value / max_temp, 1.0f); - return (int)(ratio * max_width); -} - -/** - * @brief Dynamic scaling parameters structure - */ -typedef struct -{ - double scale_x; - double scale_y; - double corner_radius; - double inscribe_factor; // 1.0 for rectangular, M_SQRT1_2 for circular - int safe_bar_width; // Safe bar width for circular displays - double safe_content_margin; // Horizontal margin for safe content area - int is_circular; // 1 if circular display, 0 if rectangular -} ScalingParams; - -/** - * @brief Calculate dynamic scaling parameters based on display dimensions - */ -static void calculate_scaling_params(const struct Config *config, - ScalingParams *params, - const char *device_name) -{ - const double base_width = 240.0; - const double base_height = 240.0; - - params->scale_x = config->display_width / base_width; - params->scale_y = config->display_height / base_height; - const double scale_avg = (params->scale_x + params->scale_y) / 2.0; - - // Detect circular displays - int is_circular_by_device = is_circular_display_device( - device_name, config->display_width, config->display_height); - - // Check display_shape configuration - if (strcmp(config->display_shape, "rectangular") == 0) - { - // Force rectangular (inscribe_factor = 1.0) - params->is_circular = 0; - params->inscribe_factor = 1.0; - log_message(LOG_INFO, "Circle mode: Display shape forced to rectangular " - "via config (inscribe_factor: 1.0)"); - } - else if (strcmp(config->display_shape, "circular") == 0) - { - // Force circular (inscribe_factor = M_SQRT1_2 β‰ˆ 0.7071) - params->is_circular = 1; - double cfg_inscribe; - if (config->display_inscribe_factor == 0.0f) - cfg_inscribe = M_SQRT1_2; // user 'auto' - else if (config->display_inscribe_factor > 0.0f && - config->display_inscribe_factor <= 1.0f) - cfg_inscribe = (double)config->display_inscribe_factor; - else - cfg_inscribe = M_SQRT1_2; // fallback - params->inscribe_factor = cfg_inscribe; - log_message(LOG_INFO, - "Circle mode: Display shape forced to circular via config " - "(inscribe_factor: %.4f)", - params->inscribe_factor); - } - else if (config->force_display_circular) - { - // Legacy developer override (CLI --develop) - params->is_circular = 1; - { - double cfg_inscribe; - if (config->display_inscribe_factor == 0.0f) - cfg_inscribe = M_SQRT1_2; - else if (config->display_inscribe_factor > 0.0f && - config->display_inscribe_factor <= 1.0f) - cfg_inscribe = (double)config->display_inscribe_factor; - else - cfg_inscribe = M_SQRT1_2; - params->inscribe_factor = cfg_inscribe; - } - } - else - { - // Auto-detection based on device database - params->is_circular = is_circular_by_device; - if (params->is_circular) - { - double cfg_inscribe; - if (config->display_inscribe_factor == 0.0f) - cfg_inscribe = M_SQRT1_2; - else if (config->display_inscribe_factor > 0.0f && - config->display_inscribe_factor <= 1.0f) - cfg_inscribe = (double)config->display_inscribe_factor; - else - cfg_inscribe = M_SQRT1_2; - params->inscribe_factor = cfg_inscribe; - } - else - { - params->inscribe_factor = 1.0; - } - } - - // Calculate safe area width - const double safe_area_width = - config->display_width * params->inscribe_factor; - const float content_scale = (config->display_content_scale_factor > 0.0f && - config->display_content_scale_factor <= 1.0f) - ? config->display_content_scale_factor - : 0.98f; // Fallback: 98% - // Apply bar_width percentage (default 98% = 1% margin left+right) - const double bar_width_factor = (config->layout_bar_width > 0) - ? (config->layout_bar_width / 100.0) - : 0.98; - params->safe_bar_width = - (int)(safe_area_width * content_scale * bar_width_factor); - params->safe_content_margin = - (config->display_width - params->safe_bar_width) / 2.0; - - params->corner_radius = 8.0 * scale_avg; - - log_message(LOG_INFO, - "Circle mode scaling: safe_area=%.0fpx, bar_width=%dpx (%.0f%%), " - "margin=%.1fpx", - safe_area_width, params->safe_bar_width, bar_width_factor * 100.0, - params->safe_content_margin); -} - /** * @brief Get the slot value for a given slot index * @param config Configuration @@ -303,36 +139,6 @@ static void update_sensor_mode(const struct Config *config) } } -/** - * @brief Draw rounded rectangle path - */ -static void draw_rounded_rectangle_path(cairo_t *cr, int x, int y, int width, - int height, double radius) -{ - cairo_new_sub_path(cr); - cairo_arc(cr, x + width - radius, y + radius, radius, -CIRCLE_M_PI_2, 0); - cairo_arc(cr, x + width - radius, y + height - radius, radius, 0, - CIRCLE_M_PI_2); - cairo_arc(cr, x + radius, y + height - radius, radius, CIRCLE_M_PI_2, - CIRCLE_M_PI); - cairo_arc(cr, x + radius, y + radius, radius, CIRCLE_M_PI, 1.5 * CIRCLE_M_PI); - cairo_close_path(cr); -} - -/** - * @brief Draw degree symbol at calculated position - */ -static void draw_degree_symbol(cairo_t *cr, double x, double y, - const struct Config *config) -{ - if (!cr || !config) - return; - cairo_set_font_size(cr, config->font_size_temp / 1.66); - cairo_move_to(cr, x, y); - cairo_show_text(cr, "Β°"); - cairo_set_font_size(cr, config->font_size_temp); -} - /** * @brief Draw single sensor display based on current slot * @param cr Cairo context @@ -501,31 +307,6 @@ static void draw_single_sensor(cairo_t *cr, const struct Config *config, } } -/** - * @brief Create cairo context and surface - */ -static cairo_t *create_cairo_context(const struct Config *config, - cairo_surface_t **surface) -{ - *surface = cairo_image_surface_create( - CAIRO_FORMAT_ARGB32, config->display_width, config->display_height); - if (cairo_surface_status(*surface) != CAIRO_STATUS_SUCCESS) - { - log_message(LOG_ERROR, "Failed to create Cairo surface"); - return NULL; - } - - cairo_t *cr = cairo_create(*surface); - if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) - { - log_message(LOG_ERROR, "Failed to create Cairo context"); - cairo_surface_destroy(*surface); - return NULL; - } - - return cr; -} - /** * @brief Render complete circle mode display */ @@ -549,11 +330,12 @@ static void render_display_content(cairo_t *cr, const struct Config *config, } /** - * @brief Render circle mode display and upload to LCD + * @brief Render circle mode display to PNG file. + * @details Creates PNG image with single sensor, does NOT upload. */ -int render_circle_display(const struct Config *config, - const monitor_sensor_data_t *data, - const char *device_name) +static int render_circle_display(const struct Config *config, + const monitor_sensor_data_t *data, + const char *device_name) { if (!config || !data) { @@ -581,6 +363,16 @@ int render_circle_display(const struct Config *config, render_display_content(cr, config, data, ¶ms); + cairo_surface_flush(surface); + if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) + { + log_message(LOG_ERROR, "Cairo drawing error: %s", + cairo_status_to_string(cairo_status(cr))); + cairo_destroy(cr); + cairo_surface_destroy(surface); + return 0; + } + // Write PNG to file cairo_status_t write_status = cairo_surface_write_to_png(surface, config->paths_image_coolerdash); @@ -594,41 +386,13 @@ int render_circle_display(const struct Config *config, return 0; } - // Get device UID for upload - char device_uid[128] = {0}; - char device_name_buf[128] = {0}; - int screen_width = 0, screen_height = 0; - - if (!get_liquidctl_data(config, device_uid, sizeof(device_uid), - device_name_buf, sizeof(device_name_buf), - &screen_width, &screen_height)) - { - log_message(LOG_ERROR, "Failed to get device information"); - return 0; - } - - // Upload to LCD - if (!send_image_to_lcd(config, config->paths_image_coolerdash, device_uid)) - { - log_message(LOG_ERROR, "Failed to upload circle mode image to LCD"); - return 0; - } - - // Verbose logging only - if (verbose_logging) - { - const char *slot_value = get_slot_value_by_index(config, current_slot_index); - const char *label = get_slot_label(slot_value); - float temp = get_slot_temperature(data, slot_value); - log_message(LOG_STATUS, "Circle mode: %s display updated (%.1fΒ°C)", - label ? label : "unknown", temp); - } - return 1; } /** * @brief High-level entry point for circle mode rendering + * @details Collects sensor data, renders circle display using + * render_circle_display(), and sends to LCD device. */ void draw_circle_image(const struct Config *config) { @@ -643,12 +407,9 @@ void draw_circle_image(const struct Config *config) char device_name[128] = {0}; int screen_width = 0, screen_height = 0; - if (!get_liquidctl_data(config, device_uid, sizeof(device_uid), device_name, - sizeof(device_name), &screen_width, &screen_height)) - { - log_message(LOG_ERROR, "Circle mode: Failed to get device data"); - return; - } + const int device_available = + get_liquidctl_data(config, device_uid, sizeof(device_uid), device_name, + sizeof(device_name), &screen_width, &screen_height); // Get temperature data monitor_sensor_data_t data = {0}; @@ -658,6 +419,27 @@ void draw_circle_image(const struct Config *config) return; } - // Render and upload - render_circle_display(config, &data, device_name); + // Render circle display with device name for circular display detection + if (!render_circle_display(config, &data, device_name)) + { + log_message(LOG_ERROR, "Circle display rendering failed"); + return; + } + + // Send to LCD if available + if (is_session_initialized() && device_available && device_uid[0] != '\0') + { + const char *name = + (device_name[0] != '\0') ? device_name : "Unknown Device"; + log_message(LOG_INFO, "Sending circle image to LCD: %s [%s]", name, + device_uid); + + send_image_to_lcd(config, config->paths_image_coolerdash, device_uid); + + log_message(LOG_INFO, "Circle LCD image uploaded successfully"); + } + else + { + log_message(LOG_WARNING, "Skipping circle LCD upload - device not available"); + } } diff --git a/src/mods/circle.h b/src/mods/circle.h index 2468732..fdee872 100644 --- a/src/mods/circle.h +++ b/src/mods/circle.h @@ -27,18 +27,6 @@ // Forward declarations struct Config; -// Mathematical constants for Cairo graphics operations -#ifndef M_PI -#define CIRCLE_M_PI 3.14159265358979323846 -#else -#define CIRCLE_M_PI M_PI -#endif -#ifndef M_PI_2 -#define CIRCLE_M_PI_2 1.57079632679489661923 -#else -#define CIRCLE_M_PI_2 M_PI_2 -#endif - /** * @brief Collects sensor data and renders circle mode display. * @details High-level entry point function that retrieves temperature data and @@ -46,13 +34,4 @@ struct Config; */ void draw_circle_image(const struct Config *config); -/** - * @brief Render single sensor display based on current mode (CPU or GPU). - * @details Creates PNG image using Cairo graphics library showing either CPU or - * GPU temperature, alternates every 2.5 seconds. - */ -int render_circle_display(const struct Config *config, - const monitor_sensor_data_t *data, - const char *device_name); - #endif // CIRCLE_H diff --git a/src/mods/display.c b/src/mods/display.c index d08fc38..4bf1f92 100644 --- a/src/mods/display.c +++ b/src/mods/display.c @@ -8,8 +8,9 @@ */ /** - * @brief Display mode dispatcher. - * @details Routes to dual or circle rendering module, shared sensor helpers. + * @brief Display mode dispatcher and shared rendering utilities. + * @details Routes to dual or circle rendering module, provides shared Cairo + * helpers and sensor slot functions used by all display modes. */ // Define POSIX constants @@ -17,20 +18,236 @@ // Include necessary headers // cppcheck-suppress-begin missingIncludeSystem +#include +#include +#include #include // cppcheck-suppress-end missingIncludeSystem // Include project headers #include "../device/config.h" +#include "../srv/cc_conf.h" #include "../srv/cc_sensor.h" #include "circle.h" #include "display.h" #include "dual.h" +// Circle inscribe factor for circular displays (1/sqrt(2) ~ 0.7071) +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.7071067811865476 +#endif + // ============================================================================ -// Sensor Slot Helper Functions +// Shared Cairo Rendering Helpers // ============================================================================ +/** + * @brief Convert color component from 0-255 to cairo 0.0-1.0 range. + */ +double cairo_color_convert(uint8_t color_component) +{ + return color_component / 255.0; +} + +/** + * @brief Set cairo source color from Color structure. + */ +void set_cairo_color(cairo_t *cr, const Color *color) +{ + cairo_set_source_rgb(cr, cairo_color_convert(color->r), + cairo_color_convert(color->g), + cairo_color_convert(color->b)); +} + +/** + * @brief Calculate temperature fill width with bounds checking. + */ +int calculate_temp_fill_width(float temp_value, int max_width, float max_temp) +{ + if (temp_value <= 0.0f) + return 0; + + const float ratio = fminf(temp_value / max_temp, 1.0f); + return (int)(ratio * max_width); +} + +/** + * @brief Draw rounded rectangle path for temperature bars. + */ +void draw_rounded_rectangle_path(cairo_t *cr, int x, int y, int width, + int height, double radius) +{ + cairo_new_sub_path(cr); + cairo_arc(cr, x + width - radius, y + radius, radius, -DISPLAY_M_PI_2, 0); + cairo_arc(cr, x + width - radius, y + height - radius, radius, 0, + DISPLAY_M_PI_2); + cairo_arc(cr, x + radius, y + height - radius, radius, DISPLAY_M_PI_2, + DISPLAY_M_PI); + cairo_arc(cr, x + radius, y + radius, radius, DISPLAY_M_PI, + 1.5 * DISPLAY_M_PI); + cairo_close_path(cr); +} + +/** + * @brief Draw degree symbol at calculated position with proper font scaling. + */ +void draw_degree_symbol(cairo_t *cr, double x, double y, + const struct Config *config) +{ + if (!cr || !config) + return; + cairo_set_font_size(cr, config->font_size_temp / 1.66); + cairo_move_to(cr, x, y); + cairo_show_text(cr, "Β°"); + cairo_set_font_size(cr, config->font_size_temp); +} + +/** + * @brief Create cairo surface and context for display rendering. + * @details Creates ARGB32 surface with dimensions from config. Caller must + * destroy both context and surface after use. + */ +cairo_t *create_cairo_context(const struct Config *config, + cairo_surface_t **surface) +{ + *surface = cairo_image_surface_create( + CAIRO_FORMAT_ARGB32, config->display_width, config->display_height); + if (!*surface || cairo_surface_status(*surface) != CAIRO_STATUS_SUCCESS) + { + log_message(LOG_ERROR, "Failed to create cairo surface"); + if (*surface) + cairo_surface_destroy(*surface); + *surface = NULL; + return NULL; + } + + cairo_t *cr = cairo_create(*surface); + if (!cr || cairo_status(cr) != CAIRO_STATUS_SUCCESS) + { + log_message(LOG_ERROR, "Failed to create cairo context"); + if (cr) + cairo_destroy(cr); + cairo_surface_destroy(*surface); + *surface = NULL; + return NULL; + } + + return cr; +} + +/** + * @brief Calculate dynamic scaling parameters based on display dimensions. + * @details Display shape detection: NZXT Kraken 240x240=rect, >240=circular. + */ +void calculate_scaling_params(const struct Config *config, + ScalingParams *params, const char *device_name) +{ + const double base_width = 240.0; + const double base_height = 240.0; + + params->scale_x = config->display_width / base_width; + params->scale_y = config->display_height / base_height; + const double scale_avg = (params->scale_x + params->scale_y) / 2.0; + + // Detect circular displays using device database with resolution info + int is_circular_by_device = is_circular_display_device( + device_name, config->display_width, config->display_height); + + // Check display_shape configuration + if (strcmp(config->display_shape, "rectangular") == 0) + { + // Force rectangular (inscribe_factor = 1.0) + params->is_circular = 0; + params->inscribe_factor = 1.0; + log_message(LOG_INFO, "Display shape forced to rectangular via config " + "(inscribe_factor: 1.0)"); + } + else if (strcmp(config->display_shape, "circular") == 0) + { + // Force circular (inscribe_factor = M_SQRT1_2 ~ 0.7071) + params->is_circular = 1; + double cfg_inscribe; + if (config->display_inscribe_factor == 0.0f) + cfg_inscribe = M_SQRT1_2; + else if (config->display_inscribe_factor > 0.0f && + config->display_inscribe_factor <= 1.0f) + cfg_inscribe = (double)config->display_inscribe_factor; + else + cfg_inscribe = M_SQRT1_2; + params->inscribe_factor = cfg_inscribe; + log_message( + LOG_INFO, + "Display shape forced to circular via config (inscribe_factor: %.4f)", + params->inscribe_factor); + } + else if (config->force_display_circular) + { + // Legacy developer override (CLI --develop) + params->is_circular = 1; + { + double cfg_inscribe; + if (config->display_inscribe_factor == 0.0f) + cfg_inscribe = M_SQRT1_2; + else if (config->display_inscribe_factor > 0.0f && + config->display_inscribe_factor <= 1.0f) + cfg_inscribe = (double)config->display_inscribe_factor; + else + cfg_inscribe = M_SQRT1_2; + params->inscribe_factor = cfg_inscribe; + } + log_message(LOG_INFO, + "Developer override active: forcing circular display detection " + "(device: %s)", + device_name ? device_name : "unknown"); + } + else + { + // Auto-detection based on device database + params->is_circular = is_circular_by_device; + if (params->is_circular) + { + double cfg_inscribe; + if (config->display_inscribe_factor == 0.0f) + cfg_inscribe = M_SQRT1_2; + else if (config->display_inscribe_factor > 0.0f && + config->display_inscribe_factor <= 1.0f) + cfg_inscribe = (double)config->display_inscribe_factor; + else + cfg_inscribe = M_SQRT1_2; + params->inscribe_factor = cfg_inscribe; + } + else + { + params->inscribe_factor = 1.0; + } + } + + // Calculate safe area width + const double safe_area_width = + config->display_width * params->inscribe_factor; + const float content_scale = (config->display_content_scale_factor > 0.0f && + config->display_content_scale_factor <= 1.0f) + ? config->display_content_scale_factor + : 0.98f; // Fallback: 98% + // Apply bar_width percentage (default 98% = 1% margin left+right) + const double bar_width_factor = (config->layout_bar_width > 0) + ? (config->layout_bar_width / 100.0) + : 0.98; + params->safe_bar_width = + (int)(safe_area_width * content_scale * bar_width_factor); + params->safe_content_margin = + (config->display_width - params->safe_bar_width) / 2.0; + + params->corner_radius = 8.0 * scale_avg; + + // Log detailed scaling calculations (verbose only) + log_message( + LOG_INFO, + "Scaling: safe_area=%.0fpx, bar_width=%dpx (%.0f%%), margin=%.1fpx", + safe_area_width, params->safe_bar_width, bar_width_factor * 100.0, + params->safe_content_margin); +} + /** * @brief Check if a sensor slot is active (not "none") */ @@ -166,10 +383,6 @@ uint16_t get_slot_bar_height(const struct Config *config, const char *slot_name) return config->layout_bar_height; // Fallback to global } -// ============================================================================ -// Display Dispatcher -// ============================================================================ - /** * @brief Main display dispatcher - routes to appropriate rendering mode. * @details Examines display_mode configuration and dispatches to either dual or diff --git a/src/mods/display.h b/src/mods/display.h index 8832091..a7c7a5c 100644 --- a/src/mods/display.h +++ b/src/mods/display.h @@ -8,18 +8,60 @@ */ /** - * @brief Display mode dispatcher. - * @details Routes to dual or circle rendering module. + * @brief Display mode dispatcher and shared rendering utilities. + * @details Routes to dual or circle rendering module, provides common Cairo + * helpers and sensor slot functions shared by all display modes. */ #ifndef DISPLAY_DISPATCHER_H #define DISPLAY_DISPATCHER_H +// Include necessary headers +// cppcheck-suppress-begin missingIncludeSystem +#include +#include +#include +// cppcheck-suppress-end missingIncludeSystem + // Include for Config and Color types #include "../device/config.h" // Include for monitor_sensor_data_t #include "../srv/cc_sensor.h" +// ============================================================================ +// Mathematical Constants for Cairo Graphics +// ============================================================================ + +#ifndef M_PI +#define DISPLAY_M_PI 3.14159265358979323846 +#else +#define DISPLAY_M_PI M_PI +#endif +#ifndef M_PI_2 +#define DISPLAY_M_PI_2 1.57079632679489661923 +#else +#define DISPLAY_M_PI_2 M_PI_2 +#endif + +// ============================================================================ +// Shared Rendering Types +// ============================================================================ + +/** + * @brief Dynamic scaling parameters for display rendering. + * @details Calculated once per frame based on display dimensions and device type. + */ +typedef struct +{ + double scale_x; + double scale_y; + double corner_radius; + double inscribe_factor; /**< 1.0 for rectangular, M_SQRT1_2 for circular */ + int safe_bar_width; /**< Safe bar width for circular displays */ + double safe_content_margin; /**< Horizontal margin for safe content area */ + int is_circular; /**< 1 if circular display, 0 if rectangular */ +} ScalingParams; + /** * @brief Main display dispatcher - routes to appropriate rendering mode. * @details High-level entry point that examines configuration and dispatches to @@ -29,6 +71,61 @@ */ void draw_display_image(const struct Config *config); +// ============================================================================ +// Shared Cairo Rendering Helpers +// ============================================================================ + +/** + * @brief Calculate dynamic scaling parameters based on display dimensions. + * @details Detects circular/rectangular displays and computes safe content area. + * @param config Configuration with display dimensions + * @param params Output scaling parameters + * @param device_name Device name for circular display detection + */ +void calculate_scaling_params(const struct Config *config, + ScalingParams *params, const char *device_name); + +/** + * @brief Create cairo surface and context for display rendering. + * @details Caller must destroy both context and surface after use. + * @param config Configuration with display dimensions + * @param surface Output pointer to created surface + * @return Cairo context, or NULL on failure + */ +cairo_t *create_cairo_context(const struct Config *config, + cairo_surface_t **surface); + +/** + * @brief Convert color component from 0-255 to cairo 0.0-1.0 range. + */ +double cairo_color_convert(uint8_t color_component); + +/** + * @brief Set cairo source color from Color structure. + */ +void set_cairo_color(cairo_t *cr, const Color *color); + +/** + * @brief Calculate temperature fill width with bounds checking. + * @param temp_value Current temperature value + * @param max_width Maximum width of the bar in pixels + * @param max_temp Maximum temperature scale + * @return Fill width in pixels + */ +int calculate_temp_fill_width(float temp_value, int max_width, float max_temp); + +/** + * @brief Draw rounded rectangle path for temperature bars. + */ +void draw_rounded_rectangle_path(cairo_t *cr, int x, int y, int width, + int height, double radius); + +/** + * @brief Draw degree symbol at calculated position with proper font scaling. + */ +void draw_degree_symbol(cairo_t *cr, double x, double y, + const struct Config *config); + // ============================================================================ // Sensor Slot Helper Functions // ============================================================================ diff --git a/src/mods/dual.c b/src/mods/dual.c index bdf6237..d0d2120 100644 --- a/src/mods/dual.c +++ b/src/mods/dual.c @@ -15,16 +15,10 @@ // Include necessary headers // cppcheck-suppress-begin missingIncludeSystem #include -#include #include -#include #include #include -#include #include -#include -#include -#include // cppcheck-suppress-end missingIncludeSystem // Include project headers @@ -35,176 +29,6 @@ #include "display.h" #include "dual.h" -// Circle inscribe factor for circular displays (1/√2 β‰ˆ 0.7071) -#ifndef M_SQRT1_2 -#define M_SQRT1_2 0.7071067811865476 -#endif - -// Dynamic positioning factors -#define LABEL_MARGIN_FACTOR 0.02 - -/** - * @brief Convert color component to cairo format (0-255 to 0.0-1.0) - */ -static inline double cairo_color_convert(uint8_t color_component) -{ - return color_component / 255.0; -} - -/** - * @brief Set cairo color from Color structure - */ -static inline void set_cairo_color(cairo_t *cr, const Color *color) -{ - cairo_set_source_rgb(cr, cairo_color_convert(color->r), - cairo_color_convert(color->g), - cairo_color_convert(color->b)); -} - -/** - * @brief Calculate temperature fill width with bounds checking - * @param temp_value Current temperature value - * @param max_width Maximum width of the bar in pixels - * @param max_temp Maximum temperature from configuration (highest threshold) - */ -static inline int calculate_temp_fill_width(float temp_value, int max_width, - float max_temp) -{ - if (temp_value <= 0.0f) - return 0; - - const float ratio = fminf(temp_value / max_temp, 1.0f); - return (int)(ratio * max_width); -} - -/** - * @brief Dynamic scaling parameters structure - */ -typedef struct -{ - double scale_x; - double scale_y; - double corner_radius; - double inscribe_factor; // 1.0 for rectangular, M_SQRT1_2 for circular - int safe_bar_width; // Safe bar width for circular displays - double safe_content_margin; // Horizontal margin for safe content area - int is_circular; // 1 if circular display, 0 if rectangular -} ScalingParams; - -/** - * @brief Calculate dynamic scaling parameters based on display dimensions - * @details Display shape detection: NZXT Kraken 240x240=rect, >240=circular - */ -static void calculate_scaling_params(const struct Config *config, - ScalingParams *params, - const char *device_name) -{ - const double base_width = 240.0; - const double base_height = 240.0; - - params->scale_x = config->display_width / base_width; - params->scale_y = config->display_height / base_height; - const double scale_avg = (params->scale_x + params->scale_y) / 2.0; - - // Detect circular displays using device database with resolution info - int is_circular_by_device = is_circular_display_device( - device_name, config->display_width, config->display_height); - - // Check display_shape configuration - if (strcmp(config->display_shape, "rectangular") == 0) - { - // Force rectangular (inscribe_factor = 1.0) - params->is_circular = 0; - params->inscribe_factor = 1.0; - log_message(LOG_INFO, "Display shape forced to rectangular via config " - "(inscribe_factor: 1.0)"); - } - else if (strcmp(config->display_shape, "circular") == 0) - { - // Force circular (inscribe_factor = M_SQRT1_2 β‰ˆ 0.7071) - params->is_circular = 1; - double cfg_inscribe; - if (config->display_inscribe_factor == 0.0f) - cfg_inscribe = M_SQRT1_2; // user 'auto' - else if (config->display_inscribe_factor > 0.0f && - config->display_inscribe_factor <= 1.0f) - cfg_inscribe = (double)config->display_inscribe_factor; - else - cfg_inscribe = M_SQRT1_2; // fallback - params->inscribe_factor = cfg_inscribe; - log_message( - LOG_INFO, - "Display shape forced to circular via config (inscribe_factor: %.4f)", - params->inscribe_factor); - } - else if (config->force_display_circular) - { - // Legacy developer override (CLI --develop) - params->is_circular = 1; - { - double cfg_inscribe; - if (config->display_inscribe_factor == 0.0f) - cfg_inscribe = M_SQRT1_2; - else if (config->display_inscribe_factor > 0.0f && - config->display_inscribe_factor <= 1.0f) - cfg_inscribe = (double)config->display_inscribe_factor; - else - cfg_inscribe = M_SQRT1_2; - params->inscribe_factor = cfg_inscribe; - } - log_message(LOG_INFO, - "Developer override active: forcing circular display detection " - "(device: %s)", - device_name ? device_name : "unknown"); - } - else - { - // Auto-detection based on device database - params->is_circular = is_circular_by_device; - if (params->is_circular) - { - double cfg_inscribe; - if (config->display_inscribe_factor == 0.0f) - cfg_inscribe = M_SQRT1_2; - else if (config->display_inscribe_factor > 0.0f && - config->display_inscribe_factor <= 1.0f) - cfg_inscribe = (double)config->display_inscribe_factor; - else - cfg_inscribe = M_SQRT1_2; - params->inscribe_factor = cfg_inscribe; - } - else - { - params->inscribe_factor = 1.0; - } - } - - // Calculate safe area width - const double safe_area_width = - config->display_width * params->inscribe_factor; - const float content_scale = (config->display_content_scale_factor > 0.0f && - config->display_content_scale_factor <= 1.0f) - ? config->display_content_scale_factor - : 0.98f; // Fallback: 98% - // Apply bar_width percentage (default 98% = 1% margin left+right) - const double bar_width_factor = (config->layout_bar_width > 0) - ? (config->layout_bar_width / 100.0) - : 0.98; - params->safe_bar_width = - (int)(safe_area_width * content_scale * bar_width_factor); - params->safe_content_margin = - (config->display_width - params->safe_bar_width) / 2.0; - - params->corner_radius = 8.0 * scale_avg; - - // Log detailed scaling calculations (verbose only) - log_message( - LOG_INFO, - "Scaling: safe_area=%.0fpx, bar_width=%dpx (%.0f%%), margin=%.1fpx", - safe_area_width, params->safe_bar_width, bar_width_factor * 100.0, - params->safe_content_margin); -} - /** * @brief Forward declarations for internal display rendering functions */ @@ -225,41 +49,9 @@ static void draw_single_temperature_bar_slot(cairo_t *cr, static void draw_labels(cairo_t *cr, const struct Config *config, const monitor_sensor_data_t *data, const ScalingParams *params); -static void draw_rounded_rectangle_path(cairo_t *cr, int x, int y, int width, - int height, double radius); -static cairo_t *create_cairo_context(const struct Config *config, - cairo_surface_t **surface); static void render_display_content(cairo_t *cr, const struct Config *config, const monitor_sensor_data_t *data, const ScalingParams *params); -// Helper to draw degree symbol at calculated position with proper font scaling -static void draw_degree_symbol(cairo_t *cr, double x, double y, - const struct Config *config) -{ - if (!cr || !config) - return; - cairo_set_font_size(cr, config->font_size_temp / 1.66); - cairo_move_to(cr, x, y); - cairo_show_text(cr, "Β°"); - cairo_set_font_size(cr, config->font_size_temp); -} - -/** - * @brief Draw rounded rectangle path for temperature bars - */ -static void draw_rounded_rectangle_path(cairo_t *cr, int x, int y, int width, - int height, double radius) -{ - cairo_new_sub_path(cr); - cairo_arc(cr, x + width - radius, y + radius, radius, -DISPLAY_M_PI_2, 0); - cairo_arc(cr, x + width - radius, y + height - radius, radius, 0, - DISPLAY_M_PI_2); - cairo_arc(cr, x + radius, y + height - radius, radius, DISPLAY_M_PI_2, - DISPLAY_M_PI); - cairo_arc(cr, x + radius, y + radius, radius, DISPLAY_M_PI, - 1.5 * DISPLAY_M_PI); - cairo_close_path(cr); -} /** * @brief Draw temperature displays for up and down slots @@ -586,33 +378,6 @@ static void draw_labels(cairo_t *cr, const struct Config *config, } } -/** - * @brief Create cairo context and surface - */ -static cairo_t *create_cairo_context(const struct Config *config, - cairo_surface_t **surface) -{ - *surface = cairo_image_surface_create( - CAIRO_FORMAT_ARGB32, config->display_width, config->display_height); - if (!*surface || cairo_surface_status(*surface) != CAIRO_STATUS_SUCCESS) - { - log_message(LOG_ERROR, "Failed to create cairo surface"); - if (*surface) - cairo_surface_destroy(*surface); - return NULL; - } - - cairo_t *cr = cairo_create(*surface); - if (!cr) - { - log_message(LOG_ERROR, "Failed to create cairo context"); - cairo_surface_destroy(*surface); - *surface = NULL; - } - - return cr; -} - /** * @brief Render display content to cairo context */ @@ -649,9 +414,9 @@ static void render_display_content(cairo_t *cr, const struct Config *config, * @brief Display rendering - creates surface, renders content, saves PNG (Dual * mode - CPU+GPU) */ -int render_dual_display(const struct Config *config, - const monitor_sensor_data_t *data, - const char *device_name) +static int render_dual_display(const struct Config *config, + const monitor_sensor_data_t *data, + const char *device_name) { if (!data || !config) { diff --git a/src/mods/dual.h b/src/mods/dual.h index f079f4e..5f0c29c 100644 --- a/src/mods/dual.h +++ b/src/mods/dual.h @@ -13,8 +13,8 @@ */ // Include necessary headers -#ifndef DISPLAY_H -#define DISPLAY_H +#ifndef DUAL_H +#define DUAL_H // Include necessary headers // cppcheck-suppress-begin missingIncludeSystem @@ -28,28 +28,6 @@ // Forward declarations struct Config; -// Mathematical constants for Cairo graphics operations -#ifndef M_PI -#define DISPLAY_M_PI 3.14159265358979323846 -#else -#define DISPLAY_M_PI M_PI -#endif -#ifndef M_PI_2 -#define DISPLAY_M_PI_2 1.57079632679489661923 -#else -#define DISPLAY_M_PI_2 M_PI_2 -#endif - -/** - * @brief Render dual-sensor display (CPU+GPU simultaneously). - * @details Low-level function that creates PNG image using Cairo graphics - * library based on temperature sensor data and configuration settings, then - * uploads to LCD device. Shows both sensors at once. - */ -int render_dual_display(const struct Config *config, - const monitor_sensor_data_t *data, - const char *device_name); - /** * @brief Main dual mode entry point. * @details Collects sensor data, renders dual display using @@ -58,4 +36,4 @@ int render_dual_display(const struct Config *config, */ void draw_dual_image(const struct Config *config); -#endif // DISPLAY_H +#endif // DUAL_H diff --git a/src/srv/cc_conf.h b/src/srv/cc_conf.h index d040370..37ad27f 100644 --- a/src/srv/cc_conf.h +++ b/src/srv/cc_conf.h @@ -17,7 +17,6 @@ // Include necessary headers // cppcheck-suppress-begin missingIncludeSystem -#include #include // cppcheck-suppress-end missingIncludeSystem @@ -62,13 +61,6 @@ int init_device_cache(const struct Config *config); */ int update_config_from_device(struct Config *config); -/** - * @brief Extract device type from JSON device object. - * @details Common helper function to extract device type string from JSON - * device object. - */ -const char *extract_device_type_from_json(const json_t *dev); - /** * @brief Check if a device has a circular display based on device name/type. * @details Returns true if the device is known to have a circular/round LCD diff --git a/src/srv/cc_sensor.c b/src/srv/cc_sensor.c index 8da0782..2a0e5bf 100644 --- a/src/srv/cc_sensor.c +++ b/src/srv/cc_sensor.c @@ -16,7 +16,6 @@ // cppcheck-suppress-begin missingIncludeSystem #include #include -#include #include #include #include @@ -28,6 +27,43 @@ #include "cc_main.h" #include "cc_sensor.h" +/** + * @brief Extract device type from JSON object + * @details Helper function to extract device type from JSON object + */ +extern const char *extract_device_type_from_json(const json_t *dev); + +/** @brief Cached CURL handle for reuse across polling cycles */ +static CURL *sensor_curl_handle = NULL; + +/** + * @brief Initialize or retrieve cached CURL handle for sensor polling. + * @return Cached CURL handle, or NULL on failure + */ +static CURL *get_sensor_curl_handle(void) +{ + if (!sensor_curl_handle) + { + sensor_curl_handle = curl_easy_init(); + if (!sensor_curl_handle) + log_message(LOG_ERROR, "Failed to initialize sensor CURL handle"); + } + return sensor_curl_handle; +} + +/** + * @brief Cleanup cached sensor CURL handle. + * @details Called during daemon shutdown to free resources. + */ +void cleanup_sensor_curl_handle(void) +{ + if (sensor_curl_handle) + { + curl_easy_cleanup(sensor_curl_handle); + sensor_curl_handle = NULL; + } +} + /** * @brief Extract temperature from device status history * @details Helper function to get temperature from the latest status entry @@ -231,29 +267,25 @@ static int get_temperature_data(const Config *config, float *temp_cpu, return 0; } - // Initialize CURL - CURL *curl = curl_easy_init(); + // Get cached CURL handle for sensor polling + CURL *curl = get_sensor_curl_handle(); if (!curl) - { - log_message(LOG_ERROR, "Failed to initialize CURL"); return 0; - } + + // Reset handle state for clean request + curl_easy_reset(curl); // Build URL char url[256]; int url_len = snprintf(url, sizeof(url), "%s/status", config->daemon_address); if (url_len < 0 || url_len >= (int)sizeof(url)) - { - curl_easy_cleanup(curl); return 0; - } // Initialize response buffer struct http_response response = {0}; if (!cc_init_response_buffer(&response, 8192)) { log_message(LOG_ERROR, "Failed to allocate response buffer"); - curl_easy_cleanup(curl); return 0; } @@ -297,11 +329,10 @@ static int get_temperature_data(const Config *config, float *temp_cpu, log_message(LOG_ERROR, "CURL error: %s", curl_easy_strerror(curl_result)); } - // Cleanup + // Cleanup request-specific resources cc_cleanup_response_buffer(&response); if (headers) curl_slist_free_all(headers); - curl_easy_cleanup(curl); return result; } diff --git a/src/srv/cc_sensor.h b/src/srv/cc_sensor.h index 0c3163b..9158602 100644 --- a/src/srv/cc_sensor.h +++ b/src/srv/cc_sensor.h @@ -44,4 +44,10 @@ typedef struct int get_temperature_monitor_data(const struct Config *config, monitor_sensor_data_t *data); +/** + * @brief Cleanup cached sensor CURL handle. + * @details Called during daemon shutdown to free resources. + */ +void cleanup_sensor_curl_handle(void); + #endif // CC_SENSOR_H diff --git a/tests/test_scaling.c b/tests/test_scaling.c index d1c5687..35b76f9 100644 --- a/tests/test_scaling.c +++ b/tests/test_scaling.c @@ -9,7 +9,7 @@ #include // cppcheck-suppress-end missingIncludeSystem -#include "../src/device/sys.h" +#include "../src/device/config.h" // Use same constant #ifndef M_SQRT1_2 From ce023b9b58e7cb3fd38dc5eb127a1b8a80496252 Mon Sep 17 00:00:00 2001 From: damachine Date: Tue, 10 Feb 2026 22:55:19 +0100 Subject: [PATCH 07/10] code: refactor and cleanup --- src/device/config.c | 58 ++++++++++++++++++++++----------------------- src/device/config.h | 6 ++--- src/main.c | 2 +- src/mods/circle.c | 16 ++++++------- src/mods/display.c | 25 ++++++++----------- src/mods/display.h | 12 +++++----- src/mods/dual.c | 14 +++++------ src/srv/cc_sensor.c | 14 +++++------ 8 files changed, 71 insertions(+), 76 deletions(-) diff --git a/src/device/config.c b/src/device/config.c index fb975bc..5fcb627 100644 --- a/src/device/config.c +++ b/src/device/config.c @@ -30,7 +30,7 @@ // ============================================================================ /** - * @brief Global logging implementation for all modules except main.c + * @brief Global logging implementation for all modules except main.c. */ void log_message(log_level_t level, const char *format, ...) { @@ -62,7 +62,7 @@ void log_message(log_level_t level, const char *format, ...) // ============================================================================ /** - * @brief Set daemon default values + * @brief Set daemon default values. */ static void set_daemon_defaults(Config *config) { @@ -77,7 +77,7 @@ static void set_daemon_defaults(Config *config) } /** - * @brief Set paths default values + * @brief Set paths default values. */ static void set_paths_defaults(Config *config) { @@ -97,7 +97,7 @@ static void set_paths_defaults(Config *config) } /** - * @brief Try to set display dimensions from LCD device + * @brief Try to set display dimensions from LCD device. */ static void try_set_lcd_dimensions(Config *config) { @@ -118,7 +118,7 @@ static void try_set_lcd_dimensions(Config *config) } /** - * @brief Set display default values with LCD device fallback + * @brief Set display default values with LCD device fallback. */ static void set_display_defaults(Config *config) { @@ -151,7 +151,7 @@ static void set_display_defaults(Config *config) } /** - * @brief Set layout default values + * @brief Set layout default values. */ static void set_layout_defaults(Config *config) { @@ -182,7 +182,7 @@ static void set_layout_defaults(Config *config) } /** - * @brief Set display positioning default values + * @brief Set display positioning default values. */ static void set_display_positioning_defaults(Config *config) { @@ -194,7 +194,7 @@ static void set_display_positioning_defaults(Config *config) } /** - * @brief Set font default values with dynamic scaling + * @brief Set font default values with dynamic scaling. */ static void set_font_defaults(Config *config) { @@ -237,7 +237,7 @@ static void set_font_defaults(Config *config) } /** - * @brief Set temperature defaults + * @brief Set temperature defaults. */ static void set_temperature_defaults(Config *config) { @@ -273,7 +273,7 @@ static void set_temperature_defaults(Config *config) } /** - * @brief Check if color is unset + * @brief Check if color is unset. * @details Uses is_set flag - all RGB values (0,0,0 to 255,255,255) are valid. */ static inline int is_color_unset(const Color *color) @@ -282,7 +282,7 @@ static inline int is_color_unset(const Color *color) } /** - * @brief Color default configuration entry + * @brief Color default configuration entry. */ typedef struct { @@ -291,7 +291,7 @@ typedef struct } ColorDefault; /** - * @brief Set color default values + * @brief Set color default values. */ static void set_color_defaults(Config *config) { @@ -330,7 +330,7 @@ static void set_color_defaults(Config *config) } /** - * @brief Check if a sensor slot value is valid + * @brief Check if a sensor slot value is valid. */ static int is_valid_sensor_slot(const char *slot) { @@ -343,7 +343,7 @@ static int is_valid_sensor_slot(const char *slot) } /** - * @brief Check if a sensor slot is active (not "none") + * @brief Check if a sensor slot is active (not "none"). */ static int slot_is_active_str(const char *slot) { @@ -353,7 +353,7 @@ static int slot_is_active_str(const char *slot) } /** - * @brief Validate sensor slot configuration + * @brief Validate sensor slot configuration. * @details Checks for duplicates (excluding "none"), ensures at least one active slot, * and validates slot values. Resets to defaults on critical errors. */ @@ -427,7 +427,7 @@ static void validate_sensor_slots(Config *config) } /** - * @brief Apply all system default values for missing fields + * @brief Apply all system default values for missing fields. */ static void apply_system_defaults(Config *config) { @@ -449,7 +449,7 @@ static void apply_system_defaults(Config *config) // ============================================================================ /** - * @brief Read color from JSON object + * @brief Read color from JSON object. */ static int read_color_from_json(json_t *color_obj, Color *color) { @@ -479,7 +479,7 @@ static int read_color_from_json(json_t *color_obj, Color *color) } /** - * @brief Try to locate config.json + * @brief Try to locate config.json. */ static const char *find_config_json(const char *custom_path) { @@ -511,7 +511,7 @@ static const char *find_config_json(const char *custom_path) } /** - * @brief Load daemon settings from JSON + * @brief Load daemon settings from JSON. */ static void load_daemon_from_json(json_t *root, Config *config) { @@ -541,7 +541,7 @@ static void load_daemon_from_json(json_t *root, Config *config) } /** - * @brief Load paths from JSON + * @brief Load paths from JSON. */ static void load_paths_from_json(json_t *root, Config *config) { @@ -581,7 +581,7 @@ static void load_paths_from_json(json_t *root, Config *config) } /** - * @brief Load display settings from JSON + * @brief Load display settings from JSON. */ static void load_display_from_json(json_t *root, Config *config) { @@ -696,7 +696,7 @@ static void load_display_from_json(json_t *root, Config *config) } /** - * @brief Load layout settings from JSON + * @brief Load layout settings from JSON. */ static void load_layout_from_json(json_t *root, Config *config) { @@ -789,7 +789,7 @@ static void load_layout_from_json(json_t *root, Config *config) } /** - * @brief Load colors from JSON + * @brief Load colors from JSON. */ static void load_colors_from_json(json_t *root, Config *config) { @@ -805,7 +805,7 @@ static void load_colors_from_json(json_t *root, Config *config) } /** - * @brief Load font settings from JSON + * @brief Load font settings from JSON. */ static void load_font_from_json(json_t *root, Config *config) { @@ -837,7 +837,7 @@ static void load_font_from_json(json_t *root, Config *config) } /** - * @brief Load CPU temperature settings from JSON + * @brief Load CPU temperature settings from JSON. */ static void load_cpu_temperature_from_json(json_t *root, Config *config) { @@ -876,7 +876,7 @@ static void load_cpu_temperature_from_json(json_t *root, Config *config) } /** - * @brief Load GPU temperature settings from JSON + * @brief Load GPU temperature settings from JSON. */ static void load_gpu_temperature_from_json(json_t *root, Config *config) { @@ -915,7 +915,7 @@ static void load_gpu_temperature_from_json(json_t *root, Config *config) } /** - * @brief Load liquid temperature settings from JSON + * @brief Load liquid temperature settings from JSON. */ static void load_liquid_from_json(json_t *root, Config *config) { @@ -954,7 +954,7 @@ static void load_liquid_from_json(json_t *root, Config *config) } /** - * @brief Load positioning settings from JSON + * @brief Load positioning settings from JSON. */ static void load_positioning_from_json(json_t *root, Config *config) { @@ -1022,7 +1022,7 @@ static void load_positioning_from_json(json_t *root, Config *config) // ============================================================================ /** - * @brief Load complete configuration from config.json with hardcoded defaults + * @brief Load complete configuration from config.json with hardcoded defaults. */ int load_plugin_config(Config *config, const char *config_path) { diff --git a/src/device/config.h b/src/device/config.h index a2fdbf6..494e8be 100644 --- a/src/device/config.h +++ b/src/device/config.h @@ -152,13 +152,13 @@ typedef struct Config } Config; /** - * @brief Global logging function for all modules except main.c + * @brief Global logging function for all modules except main.c. * @details Provides unified log output for info, status, warning and error messages. */ void log_message(log_level_t level, const char *format, ...); /** - * @brief Global logging control from main.c + * @brief Global logging control from main.c. * @details External variable controlling verbose logging behavior across all modules. */ extern int verbose_logging; @@ -192,7 +192,7 @@ static inline int is_valid_orientation(int orientation) // ============================================================================ /** - * @brief Load complete configuration from config.json with hardcoded defaults + * @brief Load complete configuration from config.json with hardcoded defaults. * @param config Pointer to Config struct to populate * @param config_path Optional path to config.json (NULL = use default location) * @return 1 on success (config loaded), 0 if using defaults only diff --git a/src/main.c b/src/main.c index df7949b..03dfa51 100644 --- a/src/main.c +++ b/src/main.c @@ -601,7 +601,7 @@ static int verify_plugin_dir_permissions(const char *plugin_dir) } /** - * @brief Initialize configuration from plugin config.json + * @brief Initialize configuration from plugin config.json. * @details Loads config using unified plugin.c system: * 1. Initialize defaults (hardcoded) * 2. Try to load config.json (overrides defaults) diff --git a/src/mods/circle.c b/src/mods/circle.c index adb60de..2315770 100644 --- a/src/mods/circle.c +++ b/src/mods/circle.c @@ -30,13 +30,13 @@ #include "circle.h" /** - * @brief Global state for sensor alternation (slot-based cycling) + * @brief Global state for sensor alternation (slot-based cycling). */ static int current_slot_index = 0; // 0=up, 1=mid, 2=down static time_t last_switch_time = 0; /** - * @brief Get the slot value for a given slot index + * @brief Get the slot value for a given slot index. * @param config Configuration * @param slot_index 0=up, 1=mid, 2=down * @return Slot value string ("cpu", "gpu", "liquid", "none") @@ -60,7 +60,7 @@ static const char *get_slot_value_by_index(const struct Config *config, int slot } /** - * @brief Get slot name for a given slot index + * @brief Get slot name for a given slot index. */ static const char *get_slot_name_by_index(int slot_index) { @@ -78,7 +78,7 @@ static const char *get_slot_name_by_index(int slot_index) } /** - * @brief Find next active slot index (wrapping around) + * @brief Find next active slot index (wrapping around). * @param config Configuration * @param start_index Starting slot index * @return Next active slot index, or -1 if none found @@ -96,7 +96,7 @@ static int find_next_active_slot(const struct Config *config, int start_index) } /** - * @brief Check if sensor should switch based on configured interval + * @brief Check if sensor should switch based on configured interval. */ static void update_sensor_mode(const struct Config *config) { @@ -140,7 +140,7 @@ static void update_sensor_mode(const struct Config *config) } /** - * @brief Draw single sensor display based on current slot + * @brief Draw single sensor display based on current slot. * @param cr Cairo context * @param config Configuration * @param params Scaling parameters @@ -308,7 +308,7 @@ static void draw_single_sensor(cairo_t *cr, const struct Config *config, } /** - * @brief Render complete circle mode display + * @brief Render complete circle mode display. */ static void render_display_content(cairo_t *cr, const struct Config *config, const monitor_sensor_data_t *data, @@ -390,7 +390,7 @@ static int render_circle_display(const struct Config *config, } /** - * @brief High-level entry point for circle mode rendering + * @brief High-level entry point for circle mode rendering. * @details Collects sensor data, renders circle display using * render_circle_display(), and sends to LCD device. */ diff --git a/src/mods/display.c b/src/mods/display.c index 4bf1f92..369239e 100644 --- a/src/mods/display.c +++ b/src/mods/display.c @@ -37,12 +37,8 @@ #define M_SQRT1_2 0.7071067811865476 #endif -// ============================================================================ -// Shared Cairo Rendering Helpers -// ============================================================================ - /** - * @brief Convert color component from 0-255 to cairo 0.0-1.0 range. + * @brief Convert color component into a 0.0-1.0 range. */ double cairo_color_convert(uint8_t color_component) { @@ -104,8 +100,7 @@ void draw_degree_symbol(cairo_t *cr, double x, double y, /** * @brief Create cairo surface and context for display rendering. - * @details Creates ARGB32 surface with dimensions from config. Caller must - * destroy both context and surface after use. + * @details Creates ARGB32 surface with dimensions from config. */ cairo_t *create_cairo_context(const struct Config *config, cairo_surface_t **surface) @@ -229,7 +224,7 @@ void calculate_scaling_params(const struct Config *config, config->display_content_scale_factor <= 1.0f) ? config->display_content_scale_factor : 0.98f; // Fallback: 98% - // Apply bar_width percentage (default 98% = 1% margin left+right) + // Apply bar_width percentage const double bar_width_factor = (config->layout_bar_width > 0) ? (config->layout_bar_width / 100.0) : 0.98; @@ -240,7 +235,7 @@ void calculate_scaling_params(const struct Config *config, params->corner_radius = 8.0 * scale_avg; - // Log detailed scaling calculations (verbose only) + // Log detailed scaling calculations log_message( LOG_INFO, "Scaling: safe_area=%.0fpx, bar_width=%dpx (%.0f%%), margin=%.1fpx", @@ -249,7 +244,7 @@ void calculate_scaling_params(const struct Config *config, } /** - * @brief Check if a sensor slot is active (not "none") + * @brief Check if a sensor slot is active. */ int slot_is_active(const char *slot_value) { @@ -259,7 +254,7 @@ int slot_is_active(const char *slot_value) } /** - * @brief Get temperature value for a sensor slot + * @brief Get temperature value for a sensor slot. */ float get_slot_temperature(const monitor_sensor_data_t *data, const char *slot_value) { @@ -277,7 +272,7 @@ float get_slot_temperature(const monitor_sensor_data_t *data, const char *slot_v } /** - * @brief Get display label for a sensor slot + * @brief Get display label for a sensor slot. */ const char *get_slot_label(const char *slot_value) { @@ -297,7 +292,7 @@ const char *get_slot_label(const char *slot_value) } /** - * @brief Get bar color for a sensor slot based on temperature + * @brief Get bar color for a sensor slot based on temperature. */ Color get_slot_bar_color(const struct Config *config, const char *slot_value, float temperature) { @@ -346,7 +341,7 @@ Color get_slot_bar_color(const struct Config *config, const char *slot_value, fl } /** - * @brief Get maximum scale for a sensor slot + * @brief Get maximum scale for a sensor slot. */ float get_slot_max_scale(const struct Config *config, const char *slot_value) { @@ -366,7 +361,7 @@ float get_slot_max_scale(const struct Config *config, const char *slot_value) } /** - * @brief Get bar height for a specific slot + * @brief Get bar height for a specific slot. */ uint16_t get_slot_bar_height(const struct Config *config, const char *slot_name) { diff --git a/src/mods/display.h b/src/mods/display.h index a7c7a5c..b8c1d46 100644 --- a/src/mods/display.h +++ b/src/mods/display.h @@ -131,14 +131,14 @@ void draw_degree_symbol(cairo_t *cr, double x, double y, // ============================================================================ /** - * @brief Check if a sensor slot is active (not "none") + * @brief Check if a sensor slot is active (not "none"). * @param slot_value Slot configuration value ("cpu", "gpu", "liquid", "none") * @return 1 if active, 0 if "none" or invalid */ int slot_is_active(const char *slot_value); /** - * @brief Get temperature value for a sensor slot + * @brief Get temperature value for a sensor slot. * @param data Sensor data structure with CPU, GPU, and liquid temperatures * @param slot_value Slot configuration value ("cpu", "gpu", "liquid") * @return Temperature in Celsius, or 0.0 if slot is "none" or invalid @@ -146,14 +146,14 @@ int slot_is_active(const char *slot_value); float get_slot_temperature(const monitor_sensor_data_t *data, const char *slot_value); /** - * @brief Get display label for a sensor slot + * @brief Get display label for a sensor slot. * @param slot_value Slot configuration value ("cpu", "gpu", "liquid", "none") * @return Label string ("CPU", "GPU", "LIQ") or NULL if "none" */ const char *get_slot_label(const char *slot_value); /** - * @brief Get bar color for a sensor slot based on temperature + * @brief Get bar color for a sensor slot based on temperature. * @param config Configuration with threshold colors * @param slot_value Slot configuration value (determines which thresholds to use) * @param temperature Current temperature value @@ -162,7 +162,7 @@ const char *get_slot_label(const char *slot_value); Color get_slot_bar_color(const struct Config *config, const char *slot_value, float temperature); /** - * @brief Get maximum scale for a sensor slot + * @brief Get maximum scale for a sensor slot. * @param config Configuration with max scale values * @param slot_value Slot configuration value * @return Maximum temperature scale (liquid uses different max) @@ -170,7 +170,7 @@ Color get_slot_bar_color(const struct Config *config, const char *slot_value, fl float get_slot_max_scale(const struct Config *config, const char *slot_value); /** - * @brief Get bar height for a specific slot + * @brief Get bar height for a specific slot. * @param config Configuration with bar height values * @param slot_name Slot name: "up", "mid", or "down" * @return Bar height in pixels for the specified slot diff --git a/src/mods/dual.c b/src/mods/dual.c index d0d2120..198a9c3 100644 --- a/src/mods/dual.c +++ b/src/mods/dual.c @@ -30,7 +30,7 @@ #include "dual.h" /** - * @brief Forward declarations for internal display rendering functions + * @brief Forward declarations for internal display rendering functions. */ static void draw_temperature_displays(cairo_t *cr, const monitor_sensor_data_t *data, @@ -54,7 +54,7 @@ static void render_display_content(cairo_t *cr, const struct Config *config, const ScalingParams *params); /** - * @brief Draw temperature displays for up and down slots + * @brief Draw temperature displays for up and down slots. */ static void draw_temperature_displays(cairo_t *cr, const monitor_sensor_data_t *data, @@ -175,7 +175,7 @@ static void draw_temperature_displays(cairo_t *cr, } /** - * @brief Draw a single temperature bar with background, fill, and border + * @brief Draw a single temperature bar with background, fill, and border. */ static void draw_single_temperature_bar_slot(cairo_t *cr, const struct Config *config, @@ -226,7 +226,7 @@ static void draw_single_temperature_bar_slot(cairo_t *cr, } /** - * @brief Draw temperature bars for up and down slots + * @brief Draw temperature bars for up and down slots. */ static void draw_temperature_bars(cairo_t *cr, const monitor_sensor_data_t *data, @@ -288,7 +288,7 @@ static void draw_temperature_bars(cairo_t *cr, } /** - * @brief Draw labels for up and down slots + * @brief Draw labels for up and down slots. */ static void draw_labels(cairo_t *cr, const struct Config *config, const monitor_sensor_data_t *data, @@ -379,7 +379,7 @@ static void draw_labels(cairo_t *cr, const struct Config *config, } /** - * @brief Render display content to cairo context + * @brief Render display content to cairo context. */ static void render_display_content(cairo_t *cr, const struct Config *config, const monitor_sensor_data_t *data, @@ -412,7 +412,7 @@ static void render_display_content(cairo_t *cr, const struct Config *config, /** * @brief Display rendering - creates surface, renders content, saves PNG (Dual - * mode - CPU+GPU) + * mode - CPU+GPU). */ static int render_dual_display(const struct Config *config, const monitor_sensor_data_t *data, diff --git a/src/srv/cc_sensor.c b/src/srv/cc_sensor.c index 2a0e5bf..8739db9 100644 --- a/src/srv/cc_sensor.c +++ b/src/srv/cc_sensor.c @@ -28,12 +28,12 @@ #include "cc_sensor.h" /** - * @brief Extract device type from JSON object - * @details Helper function to extract device type from JSON object + * @brief Extract device type from JSON object. + * @details Helper function to extract device type from JSON object. */ extern const char *extract_device_type_from_json(const json_t *dev); -/** @brief Cached CURL handle for reuse across polling cycles */ +/** @brief Cached CURL handle for reuse across polling cycles. */ static CURL *sensor_curl_handle = NULL; /** @@ -65,8 +65,8 @@ void cleanup_sensor_curl_handle(void) } /** - * @brief Extract temperature from device status history - * @details Helper function to get temperature from the latest status entry + * @brief Extract temperature from device status history. + * @details Helper function to get temperature from the latest status entry. */ static float extract_device_temperature(const json_t *device, const char *device_type) @@ -225,8 +225,8 @@ static int parse_temperature_data(const char *json, float *temp_cpu, } /** - * @brief Configure CURL for status API request - * @details Helper function to set up CURL options for temperature data request + * @brief Configure CURL for status API request. + * @details Helper function to set up CURL options for temperature data request. */ static void configure_status_request(CURL *curl, const char *url, struct http_response *response) From b888c65a52d7d64bfeee6f8dc18e14bdba590df0 Mon Sep 17 00:00:00 2001 From: damachine Date: Tue, 10 Feb 2026 23:30:36 +0100 Subject: [PATCH 08/10] feat: add new device and info tab in plugin-ui --- .../plugins/coolerdash/ui/index.html | 277 ++++++++++++++++++ 1 file changed, 277 insertions(+) diff --git a/etc/coolercontrol/plugins/coolerdash/ui/index.html b/etc/coolercontrol/plugins/coolerdash/ui/index.html index b6cc589..ae5815c 100644 --- a/etc/coolercontrol/plugins/coolerdash/ui/index.html +++ b/etc/coolercontrol/plugins/coolerdash/ui/index.html @@ -70,6 +70,102 @@ font-size: 14px; } + /* Device Tab */ + .device-info-card { + background: var(--bg-input); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 20px 24px; + margin-bottom: 16px; + } + + .device-info-row { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 0; + border-bottom: 1px solid rgba(45, 66, 99, 0.4); + } + + .device-info-row:last-child { + border-bottom: none; + } + + .device-info-label { + font-size: 13px; + color: var(--text-dim); + font-weight: 500; + } + + .device-info-value { + font-size: 14px; + font-weight: 600; + color: var(--text); + } + + .device-info-value.mono { + font-family: 'SF Mono', 'Fira Code', 'Courier New', monospace; + } + + .device-status { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 3px 10px; + border-radius: 12px; + font-size: 12px; + font-weight: 600; + } + + .device-status.connected { + background: rgba(34, 197, 94, 0.12); + color: var(--success); + } + + .device-status.disconnected { + background: rgba(255, 140, 0, 0.12); + color: #ff8c00; + } + + .device-status.error { + background: rgba(233, 69, 96, 0.12); + color: var(--accent); + } + + .device-status-dot { + width: 7px; + height: 7px; + border-radius: 50%; + background: currentColor; + } + + .info-item { + margin-bottom: 20px; + } + + .info-item-label { + font-size: 11px; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.8px; + margin-bottom: 4px; + } + + .info-item-value { + font-size: 14px; + color: var(--text); + } + + .info-item-value a { + color: var(--accent); + text-decoration: none; + } + + .info-item-value a:hover { + color: var(--accent-hover); + text-decoration: underline; + } + /* Tabs */ .tabs { display: flex; @@ -393,6 +489,8 @@

CoolerDash Configuration

+ +
@@ -985,6 +1083,85 @@

Backup & Restore

πŸ’Ύ Export Configuration + + +
+

Detected LCD Device

+ +
+ Detecting device from CoolerControl API... +
+ + + + +
+ + +
+

About CoolerDash

+ +
+
+
Plugin
+
CoolerDash β€” LCD Temperature Dashboard
+
+
+
Description
+
Displays CPU, GPU, and Liquid temperatures on AIO liquid cooler LCD screens (NZXT Kraken, etc.) via the CoolerControl REST API.
+
+
+
Author
+
damachine
+
+ +
+
License
+
MIT
+
+
+
Language / Platform
+
C99 / Linux (systemd)
+
+
+
@@ -1152,6 +1329,101 @@

Backup & Restore

window.runPluginScript = function(mainFunction) { mainFunction(); }; } + // ===== DEVICE DETECTION ===== + let lastApiAddress = ''; + let lastApiPassword = ''; + + async function fetchDeviceInfo(apiAddress, password) { + lastApiAddress = apiAddress; + lastApiPassword = password; + + const loadingEl = document.getElementById('device-loading'); + const contentEl = document.getElementById('device-panel-content'); + const errorEl = document.getElementById('device-error'); + + loadingEl.style.display = 'block'; + contentEl.style.display = 'none'; + errorEl.style.display = 'none'; + + try { + const headers = {}; + if (password) { + headers['Authorization'] = `Basic ${btoa(`admin:${password}`)}`; + } + const response = await fetch(`${apiAddress}/devices`, { headers }); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + const data = await response.json(); + + const devices = data.devices || []; + let found = null; + for (const dev of devices) { + const dtype = dev.type || ''; + if (dtype === 'Liquidctl') { + found = dev; + break; + } + } + + loadingEl.style.display = 'none'; + + if (found) { + const name = found.name || 'Unknown Device'; + const uid = found.uid || 'β€”'; + document.getElementById('device-name').textContent = name; + document.getElementById('device-uid').textContent = uid; + + // LCD info path: info.channels..lcd_info + let width = 0, height = 0; + const channels = found.info?.channels; + if (channels) { + for (const ch of Object.values(channels)) { + if (ch.lcd_info) { + width = ch.lcd_info.screen_width || 0; + height = ch.lcd_info.screen_height || 0; + break; + } + } + } + + const resEl = document.getElementById('device-resolution'); + const shapeEl = document.getElementById('device-shape'); + if (width > 0 && height > 0) { + resEl.textContent = `${width} Γ— ${height} px`; + const isCircular = name.includes('Kraken') && (width > 240 || height > 240); + shapeEl.textContent = isCircular ? 'Circular' : 'Rectangular'; + } else { + resEl.textContent = 'Not available'; + shapeEl.textContent = 'Unknown'; + } + + document.getElementById('device-status').innerHTML = + ' Connected'; + contentEl.style.display = 'block'; + } else { + document.getElementById('device-name').textContent = 'β€”'; + document.getElementById('device-uid').textContent = 'β€”'; + document.getElementById('device-resolution').textContent = 'β€”'; + document.getElementById('device-shape').textContent = 'β€”'; + document.getElementById('device-status').innerHTML = + ' No LCD device found'; + contentEl.style.display = 'block'; + } + } catch (error) { + console.warn('Device detection failed:', error); + loadingEl.style.display = 'none'; + document.getElementById('device-status').innerHTML = + ' Detection failed'; + document.getElementById('device-error-text').textContent = + `Could not connect to CoolerControl API (${error.message}).`; + contentEl.style.display = 'block'; + errorEl.style.display = 'block'; + } + } + + function refreshDeviceInfo() { + fetchDeviceInfo(lastApiAddress, lastApiPassword); + } + // ===== UI FUNCTIONS ===== function switchTab(index) { document.querySelectorAll('.tab').forEach((tab, i) => tab.classList.toggle('active', i === index)); @@ -1485,6 +1757,11 @@

Backup & Restore

} populateForm(config); + + // Detect device from CoolerControl API + const apiAddr = config.daemon?.address || 'http://localhost:11987'; + const apiPass = config.daemon?.password || ''; + fetchDeviceInfo(apiAddr, apiPass); } catch (error) { console.error("Init failed:", error); if (DEFAULT_CONFIG) populateForm(DEFAULT_CONFIG); From 311b1f4494ceffac076eee156a66ce43105bf868 Mon Sep 17 00:00:00 2001 From: damachine Date: Wed, 11 Feb 2026 00:07:47 +0100 Subject: [PATCH 09/10] add more details to new tabs --- Makefile | 3 + PKGBUILD | 1 + aur/PKGBUILD | 1 + .../plugins/coolerdash/ui/index.html | 91 ++++++++++++++++++- 4 files changed, 94 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 8aeec2a..620c6e2 100644 --- a/Makefile +++ b/Makefile @@ -283,6 +283,9 @@ install: check-deps $(TARGET) @install -m644 images/shutdown.png "$(DESTDIR)/etc/coolercontrol/plugins/coolerdash/shutdown.png" @install -m644 $(MANIFEST) "$(DESTDIR)/etc/coolercontrol/plugins/coolerdash/manifest.toml" @sed -i 's/{{VERSION}}/$(VERSION)/g' "$(DESTDIR)/etc/coolercontrol/plugins/coolerdash/manifest.toml" + @sed -i 's/{{VERSION}}/$(VERSION)/g' "$(DESTDIR)/etc/coolercontrol/plugins/coolerdash/ui/index.html" + @OS_RELEASE=$$(grep -m1 '^PRETTY_NAME=' /etc/os-release 2>/dev/null | cut -d= -f2 | tr -d '"' || echo "Linux"); \ + sed -i "s/{{OS_RELEASE}}/$$OS_RELEASE/g" "$(DESTDIR)/etc/coolercontrol/plugins/coolerdash/ui/index.html" @install -Dm644 etc/systemd/cc-plugin-coolerdash.service.d/startup-delay.conf "$(DESTDIR)/etc/systemd/system/cc-plugin-coolerdash.service.d/startup-delay.conf" @install -Dm644 etc/systemd/coolerdash-helperd.service "$(DESTDIR)/usr/lib/systemd/system/coolerdash-helperd.service" @printf " $(GREEN)Drop-in:$(RESET) $(DESTDIR)/etc/systemd/system/cc-plugin-coolerdash.service.d/startup-delay.conf\n" diff --git a/PKGBUILD b/PKGBUILD index 628bf49..4a7a1ae 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -90,6 +90,7 @@ package() { install -Dm644 "${srcdir}/etc/coolercontrol/plugins/coolerdash/manifest.toml" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/manifest.toml" sed -i "s/{{VERSION}}/${pkgver}/g" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/manifest.toml" + sed -i "s/{{VERSION}}/${pkgver}/g" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/ui/index.html" install -Dm644 "${srcdir}/man/coolerdash.1" "${pkgdir}/usr/share/man/man1/coolerdash.1" install -Dm644 "${srcdir}/etc/applications/coolerdash.desktop" "${pkgdir}/usr/share/applications/coolerdash.desktop" diff --git a/aur/PKGBUILD b/aur/PKGBUILD index 96a46c1..061075d 100644 --- a/aur/PKGBUILD +++ b/aur/PKGBUILD @@ -71,6 +71,7 @@ package() { install -m644 "${srcdir}/coolerdash/etc/coolercontrol/plugins/coolerdash/manifest.toml" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/manifest.toml" sed -i "s/{{VERSION}}/${pkgver}/g" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/manifest.toml" + sed -i "s/{{VERSION}}/${pkgver}/g" "${pkgdir}/etc/coolercontrol/plugins/coolerdash/ui/index.html" install -Dm644 "${srcdir}/coolerdash/man/coolerdash.1" "${pkgdir}/usr/share/man/man1/coolerdash.1" install -Dm644 "${srcdir}/coolerdash/etc/applications/coolerdash.desktop" "${pkgdir}/usr/share/applications/coolerdash.desktop" diff --git a/etc/coolercontrol/plugins/coolerdash/ui/index.html b/etc/coolercontrol/plugins/coolerdash/ui/index.html index ae5815c..d556690 100644 --- a/etc/coolercontrol/plugins/coolerdash/ui/index.html +++ b/etc/coolercontrol/plugins/coolerdash/ui/index.html @@ -474,7 +474,7 @@

CoolerDash Configuration

Customize your LCD temperature dashboard β€’ Changes require plugin restart

- πŸ’‘ Tip: After an update, click Reset to apply new default values added by the developer. + πŸ’‘ Tip: After an update, click Reset to apply new default values. Feedback & bug reports are welcome β€” see the Info tab for links.

@@ -1118,6 +1118,14 @@

Detected LCD Device

Display Shape β€” +
+ Firmware + β€” +
+
+ Liquidctl Version + β€” +