diff --git a/apps/gtk-discover/BACnet-Icon.svg b/apps/gtk-discover/BACnet-Icon.svg new file mode 100644 index 00000000..f4fcbc4e --- /dev/null +++ b/apps/gtk-discover/BACnet-Icon.svg @@ -0,0 +1,193 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + A + C + t + e + n + B + diff --git a/apps/gtk-discover/bacdiscover-gtk.desktop b/apps/gtk-discover/bacdiscover-gtk.desktop new file mode 100644 index 00000000..63571ed1 --- /dev/null +++ b/apps/gtk-discover/bacdiscover-gtk.desktop @@ -0,0 +1,16 @@ +[Desktop Entry] +Name=BACnet GTK Discovery +Comment=Graphical discovery for BACnet devices, objects, and properties +Exec=/usr/local/bin/bacdiscover-gtk +Icon=network-workgroup +Terminal=false +Type=Application +Categories=Network;Development;Utility; +Keywords=BACnet;Building Automation;HVAC;Industrial;Network;Protocol; +StartupNotify=true +MimeType=application/x-bacnet; + +# Additional metadata +GenericName=BACnet Device Discovery +StartupWMClass=bacnet-gtk-discovery +X-GNOME-UsesNotifications=true diff --git a/apps/gtk-discover/bacnet-icon.xpm b/apps/gtk-discover/bacnet-icon.xpm new file mode 100644 index 00000000..b01b095f --- /dev/null +++ b/apps/gtk-discover/bacnet-icon.xpm @@ -0,0 +1,140 @@ +/* XPM */ +static const char *bacnet_icon[] = { +/* columns rows colors chars-per-pixel */ +"81 70 64 1 ", +" c black", +". c #060906090609", +"X c gray3", +"o c #0D150D150D15", +"O c #111B111B111B", +"+ c #173C173C173C", +"@ c #1B0F1B0F1B0F", +"# c #1EFB1EFB1EFB", +"$ c #203320332033", +"% c #242524252425", +"& c #294429442944", +"* c #2D412D412D41", +"= c gray20", +"- c #351035103510", +"; c #3A333A333A33", +": c #3D623D623D62", +"> c #414141414141", +", c #477347734773", +"< c #4A4C4A4C4A4C", +"1 c #4E3E4E3E4E3E", +"2 c #503E503E503E", +"3 c #54C054C054C0", +"4 c #5A665A665A66", +"5 c #5F825F825F82", +"6 c #606060606060", +"7 c #653F653F653F", +"8 c #6A6A6A6A6A6A", +"9 c #6FC46FC46FC4", +"0 c #72B272B272B2", +"q c #767376737673", +"w c #799279927992", +"e c #7DA67DA67DA6", +"r c #805B805B805B", +"t c #857585758575", +"y c #888888888888", +"u c #8E968E968E96", +"i c #927E927E927E", +"p c #946794679467", +"a c #9B659B659B65", +"s c #9D9E9D9E9D9E", +"d c #A0D9A0D9A0D9", +"f c #A569A569A569", +"g c #ABE1ABE1ABE1", +"h c #AEDFAEDFAEDF", +"j c #B2C9B2C9B2C9", +"k c #B799B799B799", +"l c #B97EB97EB97E", +"z c gray", +"x c #C3ECC3ECC3EC", +"c c #C5A4C5A4C5A4", +"v c #CBCBCBCBCBCB", +"b c #CFB6CFB6CFB6", +"n c #D1C2D1C2D1C2", +"m c gray83", +"M c #DBBFDBBFDBBF", +"N c gainsboro", +"B c #E0F7E0F7E0F7", +"V c #E841E841E841", +"C c #EA2BEA2BEA2B", +"Z c #EF17EF17EF17", +"A c #F200F200F200", +"S c #F4EEF4EEF4EE", +"D c #FC4BFC4BFC4B", +"F c white", +/* pixels */ +"FFFFFFFFFFFFFFFFFFFFx9999999999999999999999999999999999999999xFFFFFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFFFFD DFFFFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFFFFu vFFFFFFFFFFFFFFF* rFFFFFFFFFFFFFFFFFFv uFFFFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFFFV 2FFFFFFFFFFFFFFFm *FFFFFFFFFFFFFFFFFFF1 VFFFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFFF4 VFFFFFFFFFFFFFFFe o mFFFFFFFFFFFFFFFFFFB 4FFFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFFb tFFFFFFFFFFFFFFFF% Xt rFFFFFFFFFFFFFFFFFFFt bFFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFF# SFFFFFFFFFFFFFFFb 2B &FFFFFFFFFFFFFFFFFFFS #FFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFg jFFFFFFFFFFFFFFFFq fF- nFFFFFFFFFFFFFFFFFFFj gFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFS %FFFFFFFFFFFFFFFFF# .AFt eFFFFFFFFFFFFFFFFFFFF% SFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFe nFFFFFFFFFFFFFFFFx BFFFFFFFFFFFFFFj >FFFFFFv $FFFFFFFFFFFV1 e; ZFFFFFFFFFF", +"FFFFFFFFFFF4 $ZFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFm@ *,% i 9FFFFFFFFFF", +"FFFFFFFFFFn *+ aFZZFFFFFFFFzzzzzzzzzzzzzzzzzzzzvFFFFZ# 6mFFFh. +9 MFFFFFFFFF", +"FFFFFFFFFF@ eFS: >- -mFFFFFz ZFFF9 OkFFFFFFi a -FFFFFFFFF", +"FFFFFFFFFf *FFFy OnFFFF. oX o. 2FFDo lFFFFFFFS. 7d lFFFFFFFF", +"FFFFFFFFD zFFF: 2r% 1FFFu df m0 nFn 1FFFFFFFFDX 2Fo DFFFFFFF", +"FFFFFFFF9 ,FFFj 4FFA# FFZ @F= % Fe. .NFFFFFFFFFFh hFFFF", +"FFFFS %FFFFFFFAq. 7Fq OX ks @5F, by OX vFM01 4Fx$ lFFFFFFFFFw *BF, aFFFFFFFFFFFFFFFFFF5 BFF", +"FFF< CFFFFFFFFFFFFFFdDc OpFwlFFFFFFFFFFF0iFeX SFFFFFFFFFFFFFFFFFC 2 zFFF; otct :FFFFF3o o@FFFFFFFFFFFF; ZFFFFFFFFFF", +"FFFFFFFFFFFFs zFFFFFFFF> X8w$ 1FFx yFFF> bFFFFFg uFFFFFFFFFFFFz sFFFFFFFFFFF", +"FFFFFFFFFFFFD. DFFFFFFF> gFFm %FFp #***+ aFFFFFg uFFFFFFFFFFFD XFFFFFFFFFFFF", +"FFFFFFFFFFFFFx pFFFFFFF> ZFFFO @FFw yFFFFFg uFFFFFFFFFFFi xFFFFFFFFFFFF", +"FFFFFFFFFFFFFF, CFFFFFF> SFFF@ @FFp kFFFFFFFFFFFFg uFFFFFFFFFFC SFFF@ @FFx tFFFkttBFFFFFg uFFFFFFFFFF6 BFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFe nFFFFF> SFFF@ @FFF= Xani. $FFFFFFg yFFFFFFFFFn eFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFA %FFFFF> SFFF@ @FFFcO +nFFFFFFh 1MFFFFFFFF% SFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFg jFFFF> SFFF@ @FFFFB5&X&0VFFFFFFFM FFFFFFFj gFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFF# SFFF> SFFF@ @FFFFFFFFFFFFFFFFFFFp#X%FFFFFFS #FFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFFb tFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFt bFFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFFF4 BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB 4FFFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFFFV 2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 VFFFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFFFFu vFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFv uFFFFFFFFFFFFFFFFFF", +"FFFFFFFFFFFFFFFFFFFD DFFFFFFFFFFFFFFFFFF" +}; diff --git a/apps/gtk-discover/install.sh b/apps/gtk-discover/install.sh new file mode 100755 index 00000000..87253696 --- /dev/null +++ b/apps/gtk-discover/install.sh @@ -0,0 +1,143 @@ +#!/bin/bash + +# Install script for BACnet GTK Discovery +# This script helps install the necessary dependencies and build the application + +set -e + +echo "BACnet GTK Discovery - Installation Script" +echo "=========================================" + +# Function to detect the Linux distribution +detect_distro() { + if [ -f /etc/os-release ]; then + . /etc/os-release + echo $ID + elif [ -f /etc/debian_version ]; then + echo "debian" + elif [ -f /etc/redhat-release ]; then + echo "rhel" + else + echo "unknown" + fi +} + +# Function to install GTK dependencies +install_gtk_deps() { + local distro=$(detect_distro) + + echo "Detected distribution: $distro" + echo "Installing GTK+ 3.0 development libraries..." + + case $distro in + ubuntu|debian|linuxmint) + sudo apt-get update + sudo apt-get install -y libgtk-3-dev pkg-config build-essential + ;; + fedora) + sudo dnf install -y gtk3-devel pkgconfig gcc make + ;; + rhel|centos) + sudo yum install -y gtk3-devel pkgconfig gcc make + ;; + opensuse|suse) + sudo zypper install -y gtk3-devel pkg-config gcc make + ;; + arch|manjaro) + sudo pacman -S --needed gtk3 pkgconfig gcc make + ;; + *) + echo "Unknown distribution. Please install GTK+ 3.0 development libraries manually." + echo "Required packages: gtk3-devel (or libgtk-3-dev), pkgconfig, gcc, make" + exit 1 + ;; + esac +} + +# Function to check if GTK is available +check_gtk() { + if pkg-config --exists gtk+-3.0; then + echo "GTK+ 3.0 development libraries are available." + echo "Version: $(pkg-config --modversion gtk+-3.0)" + return 0 + else + echo "GTK+ 3.0 development libraries are not available." + return 1 + fi +} + +# Function to build the GTK application +build_gtk_app() { + echo "Building BACnet GTK Discovery..." + + # Default to BACnet/IP + DATALINK=${1:-bip} + + make -C ../../ clean || true + make -C ../../ gtk-discover BACDL=$DATALINK + + if [ -f "./bacdiscover-gtk" ]; then + echo "BACnet GTK Discovery built successfully!" + echo "Run with: ./bacdiscover-gtk" + else + echo "Build failed. Please check the error messages above." + exit 1 + fi +} + +# Main installation process +main() { + echo "Checking for GTK+ 3.0 development libraries..." + + if ! check_gtk; then + echo "GTK+ 3.0 development libraries not found." + read -p "Do you want to install them automatically? (y/n): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + install_gtk_deps + if ! check_gtk; then + echo "Failed to install GTK+ 3.0 development libraries." + exit 1 + fi + else + echo "Please install GTK+ 3.0 development libraries manually and run this script again." + exit 1 + fi + fi + + # Ask user for datalink type + echo "" + echo "Choose BACnet datalink type:" + echo "1) BACnet/IP (default)" + echo "2) MS/TP (Master-Slave/Token-Passing)" + echo "3) Ethernet" + echo "" + read -p "Enter choice (1-3) [default: 1]: " choice + + case $choice in + 2) + DATALINK="mstp" + ;; + 3) + DATALINK="ethernet" + ;; + *) + DATALINK="bip" + ;; + esac + + echo "Building with datalink: $DATALINK" + build_gtk_app $DATALINK + + echo "" + echo "Installation completed successfully!" + echo "" + echo "To run the application:" + echo " ./bacdiscover-gtk" + echo "" + echo "To install system-wide:" + echo " sudo make install" +} + +# Run main function +main "$@" diff --git a/apps/gtk-discover/main.c b/apps/gtk-discover/main.c index 5ca72fa8..5f6ba16c 100644 --- a/apps/gtk-discover/main.c +++ b/apps/gtk-discover/main.c @@ -36,6 +36,8 @@ #include "bacnet/basic/tsm/tsm.h" #include "bacnet/datalink/datalink.h" #include "bacnet/datalink/dlenv.h" +/* Used ImageMagick: convert BACnet-Icon.svg bacnet-icon.xpm */ +#include "bacnet-icon.xpm" /* Global variables */ static GtkWidget *main_window; @@ -372,6 +374,8 @@ static void on_refresh_clicked(GtkButton *button, gpointer data) (void)data; /* unused parameter */ gtk_list_store_clear(device_store); + gtk_list_store_clear(object_store); + gtk_list_store_clear(property_store); process_discovered_devices(); } @@ -517,6 +521,7 @@ static void create_main_window(void) GtkWidget *scrolled_window; GtkWidget *discover_button, *refresh_button; GtkToolItem *tool_item; + GdkPixbuf *icon_pixbuf; /* Create main window */ main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); @@ -524,6 +529,12 @@ static void create_main_window(void) gtk_window_set_default_size(GTK_WINDOW(main_window), 1200, 800); gtk_container_set_border_width(GTK_CONTAINER(main_window), 5); + /* set the icon */ + icon_pixbuf = gdk_pixbuf_new_from_xpm_data(bacnet_icon); + if (icon_pixbuf) { + gtk_window_set_icon(GTK_WINDOW(main_window), icon_pixbuf); + } + /* Connect destroy signal */ g_signal_connect(main_window, "destroy", G_CALLBACK(gtk_main_quit), NULL); @@ -670,7 +681,7 @@ static void bacnet_server_init(void) mstimer_set(&BACnet_TSM_Timer, 50); /* Start BACnet background processing */ - bacnet_timeout_id = g_timeout_add(100, bacnet_task_timeout, NULL); + bacnet_timeout_id = g_timeout_add(10, bacnet_task_timeout, NULL); bacnet_initialized = true; printf("BACnet Stack initialized\n");