From 44d0f616a16115be3b50e8c2b55b4e65f1f434af Mon Sep 17 00:00:00 2001 From: No0ne558 Date: Fri, 6 Feb 2026 12:30:53 -0800 Subject: [PATCH 1/2] Ignore v2 directory in master branch --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 867f21f7..63b6c6fc 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ coverage/ *.zip *.deb *.rpm +v2/ From ebc958159aef48247d86b93f4b1e7418e1676812 Mon Sep 17 00:00:00 2001 From: No0ne558 Date: Thu, 12 Feb 2026 11:22:53 -0800 Subject: [PATCH 2/2] Fix Hardware zone bugs: duplicate server terminals and shared printer removal - Fix FindServer to properly identify server terminals and prevent duplicates - Add IsPrinterShared method to check if printer is used by multiple terminals - Modify KillRecord to only remove printer if not shared by other terminals - Update changelog with bug fixes --- docs/changelog.md | 11 ++++ main/data/settings.cc | 130 ++++++++++++++++++++++++++++++------------ main/data/settings.hh | 1 + zone/hardware_zone.cc | 10 +++- 4 files changed, 112 insertions(+), 40 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 70dae3e0..1b7d2145 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased] ### Fixed +- **Hardware Button Type: Server Terminal Duplicates and Printer Removal (2026-02-12)** + - Fixed bugs in Hardware zone that created duplicate server terminals and incorrectly removed shared printers + - **Bug 1: Duplicate Server Terminals** + - **Root Cause**: `FindServer()` assumed first terminal was always server but didn't properly search for existing servers or handle loaded settings with incorrect order + - **Solution**: Rewrote `FindServer()` to first search for terminal matching display hostname, then existing server terminals, ensure correct terminal is marked as server and moved to front, clear IsServer flags from others, and remove duplicate "Server" named terminals + - **Impact**: Server terminals are correctly identified, duplicates are prevented and cleaned up + - **Bug 2: Shared Printer Removal** + - **Root Cause**: When removing a terminal, associated printer was killed even if other terminals shared the same printer configuration + - **Solution**: Added `IsPrinterShared()` method to check if printer is used by multiple terminals, modified `KillRecord()` to only kill printer if not shared + - **Impact**: Printers are preserved when shared between terminals, only removed when truly no longer needed + - **Files modified**: `main/data/settings.cc`, `main/data/settings.hh`, `zone/hardware_zone.cc` - **Hardware Button Type: Simplified Server Display Logic (2026-02-05)** - Completely simplified the server display and terminal initialization logic - **New Approach**: The FIRST terminal in the list is ALWAYS the server display diff --git a/main/data/settings.cc b/main/data/settings.cc index dcc50cdf..5ee0856f 100644 --- a/main/data/settings.cc +++ b/main/data/settings.cc @@ -3920,6 +3920,20 @@ int Settings::Remove(PrinterInfo *pr) return printer_list.Remove(pr); } +bool Settings::IsPrinterShared(const genericChar* host, int port, TermInfo *exclude) +{ + FnTrace("Settings::IsPrinterShared()"); + for (TermInfo *ti = term_list.Head(); ti != nullptr; ti = ti->next) + { + if (ti == exclude) continue; + if (strcmp(ti->printer_host.Value(), host) == 0 && ti->printer_port == port) + { + return true; + } + } + return false; +} + int Settings::Remove(MoneyInfo *my) { FnTrace("Settings::Remove(MoneyInfo)"); @@ -4471,51 +4485,93 @@ TermInfo *Settings::FindServer(const genericChar* displaystr) { FnTrace("Settings::FindServer()"); TermInfo *ti = term_list.Head(); + TermInfo *found = nullptr; - // The first terminal in the list is ALWAYS the server display - if (ti != nullptr) + // First, look for a terminal matching the displaystr + while (ti != nullptr) { - // Ensure the first terminal is marked as server - if (!ti->IsServer()) + if (strcmp(ti->display_host.Value(), displaystr) == 0) { - ti->IsServer(1); + found = ti; + break; } - - // Remove any other terminals that were previously marked as server - // and have the default "Server" name (auto-created duplicates) - TermInfo *other = ti->next; - while (other != nullptr) + ti = ti->next; + } + + // If not found, look for an existing server + if (found == nullptr) + { + ti = term_list.Head(); + while (ti != nullptr) { - TermInfo *next_other = other->next; - if (other->IsServer()) + if (ti->IsServer()) { - other->IsServer(0); + found = ti; + break; } - // Remove auto-created "Server" terminals that are duplicates - if (strcmp(other->name.Value(), "Server") == 0 && - (other->display_host.empty() || - strcmp(other->display_host.Value(), displaystr) == 0)) - { - Remove(other); - delete other; - } - other = next_other; + ti = ti->next; } - - return ti; - } - - // No terminals exist - create the server terminal - ti = new TermInfo; - ti->name.Set("Server"); - ti->display_host.Clear(); - ti->type = TERMINAL_NORMAL; - ti->printer_model = 0; - ti->printer_port = 0; - ti->IsServer(1); - AddFront(ti); - - return ti; + } + + // If still not found, use the first terminal or create one + if (found == nullptr) + { + ti = term_list.Head(); + if (ti != nullptr) + { + found = ti; + } + else + { + // No terminals exist - create the server terminal + found = new TermInfo; + found->name.Set("Server"); + found->display_host.Set(displaystr); + found->type = TERMINAL_NORMAL; + found->printer_model = 0; + found->printer_port = 0; + found->IsServer(1); + AddFront(found); + return found; + } + } + + // Ensure the found terminal is marked as server and moved to front if not already + found->IsServer(1); + if (found != term_list.Head()) + { + // Move to front + Remove(found); + AddFront(found); + } + + // Clear IsServer from all others + ti = term_list.Head(); + while (ti != nullptr) + { + if (ti != found) + { + ti->IsServer(0); + } + ti = ti->next; + } + + // Remove auto-created duplicate "Server" terminals + ti = term_list.Head()->next; // Start from second + while (ti != nullptr) + { + TermInfo *next_ti = ti->next; + if (strcmp(ti->name.Value(), "Server") == 0 && + (ti->display_host.empty() || + strcmp(ti->display_host.Value(), displaystr) == 0)) + { + Remove(ti); + delete ti; + } + ti = next_ti; + } + + return found; } TermInfo *Settings::FindTerminal(const char* displaystr) diff --git a/main/data/settings.hh b/main/data/settings.hh index 94f2be9e..65d85ffa 100644 --- a/main/data/settings.hh +++ b/main/data/settings.hh @@ -916,6 +916,7 @@ public: int AddFront(TermInfo *ti); int Remove(TermInfo *ti); int TermReport(Terminal *t, Report *r); + bool IsPrinterShared(const genericChar* host, int port, TermInfo *exclude = nullptr); // printer functions PrinterInfo *PrinterList() { return printer_list.Head(); } diff --git a/zone/hardware_zone.cc b/zone/hardware_zone.cc index 0769ab36..334d2b4b 100644 --- a/zone/hardware_zone.cc +++ b/zone/hardware_zone.cc @@ -539,10 +539,14 @@ int HardwareZone::KillRecord(Terminal *term, int record) TermInfo *ti = settings->FindTermByRecord(record); if (ti && !ti->IsServer()) { + // Check if the printer is shared by other terminals + if (!settings->IsPrinterShared(ti->printer_host.Value(), ti->printer_port, ti)) + { + Printer *printer = ti->FindPrinter(db); + if (printer) + db->KillPrinter(printer); + } settings->Remove(ti); - Printer *printer = ti->FindPrinter(db); - if (printer) - db->KillPrinter(printer); Terminal *tmp = ti->FindTerm(db); if (tmp) tmp->kill_me = 1;