From e96ad23dce364a1bea9594dbbf508348e1d7a8ca Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 28 Aug 2009 13:33:25 -0400 Subject: [PATCH 01/28] debianize --- debian/changelog | 6 +++ debian/compat | 1 + debian/control | 13 +++++++ debian/copyright | 87 ++++++++++++++++++++++++++++++++++++++++++ debian/rules | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 205 insertions(+) create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100755 debian/rules diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..93298e2 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,6 @@ +alh (1.2.24-1) unstable; urgency=low + + * Initial release + + -- Michael Davidsaver Fri, 28 Aug 2009 13:24:29 -0400 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +7 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..5b7e372 --- /dev/null +++ b/debian/control @@ -0,0 +1,13 @@ +Source: alh +Section: admin +Priority: extra +Maintainer: Michael Davidsaver +Build-Depends: debhelper (>= 7), epics-dev (>= 3.14.10-4), epics-dev (< 3.14.11), epics-extensions-dev, htmldoc, libmotif-dev, libx11-dev, libxp-dev, libxmu-dev, libxtst-dev +Standards-Version: 3.7.3 +Homepage: http://www.aps.anl.gov/epics/extensions/alh/index.php + +Package: alh +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: EPICS Alarm Handler + A specialized EPICS client which listens for alarms on a preset list of channels. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..299f56e --- /dev/null +++ b/debian/copyright @@ -0,0 +1,87 @@ +This package was debianized by Michael Davidsaver on +Fri, 28 Aug 2009 13:24:29 -0400. + +It was downloaded from http://www.aps.anl.gov/epics/extensions/alh/index.php + +Upstream Author(s): + + Janet Anderson + +Copyright: + + Copyright (c) 2007 UChicago Argonne, LLC + as Operator of Argonne National Laboratory. + Copyright (c) 2002 Deutches Elektronen-Synchrotron + in der Helmholtz-Gemelnschaft (DESY). + Copyright (c) 2002 Berliner Speicherring-Gesellschaft + fuer Synchrotron-Strahlung mbH (BESSY). + +License: + + Copyright (c) 2002 University of Chicago. All rights reserved. + + ALH is distributed subject to the following license conditions: + + SOFTWARE LICENSE AGREEMENT + Software: Alarm Handler (ALH) + + 1. The "Software", below, refers to ALH (in either source code, or + binary form and accompanying documentation). Each licensee is + addressed as "you" or "Licensee." + + 2. The copyright holders shown above and their third-party licensors + hereby grant Licensee a royalty-free nonexclusive license, subject to + the limitations stated herein and U.S. Government license rights. + + 3. You may modify and make a copy or copies of the Software for use + within your organization, if you meet the following conditions: + a. Copies in source code must include the copyright notice and this + Software License Agreement. + b. Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other + materials provided with the copy. + + 4. You may modify a copy or copies of the Software or any portion of it, + thus forming a work based on the Software, and distribute copies of + such work outside your organization, if you meet all of the following + conditions: + a. Copies in source code must include the copyright notice and this + Software License Agreement; + b. Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other + materials provided with the copy; + c. Modified copies and works based on the Software must carry + prominent notices stating that you changed specified portions of + the Software. + + 5. Portions of the Software resulted from work developed under a U.S. + Government contract and are subject to the following license: the + Government is granted for itself and others acting on its behalf a + paid-up, nonexclusive, irrevocable worldwide license in this computer + software to reproduce, prepare derivative works, and perform publicly + and display publicly. + + 6. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT WARRANTY + OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY LICENSORS, THE + UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND THEIR + EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME + ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, + OR USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE + SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT + THAT THE SOFTWARE WILL FUNCTION UNINTERRUPTED, THAT IT IS ERROR-FREE + OR THAT ANY ERRORS WILL BE CORRECTED. + + 7. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR + THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT + OF ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, + CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, + INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY + REASON WHATSOEVER, WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF + CONTRACT, TORT (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR + OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE + POSSIBILITY OF SUCH LOSS OR DAMAGES. + +The Debian packaging is (C) 2009, Michael Davidsaver and +is licensed under the GPL, see `/usr/share/common-licenses/GPL'. diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..0741730 --- /dev/null +++ b/debian/rules @@ -0,0 +1,98 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +EPICS_HOST_ARCH:=$(shell /usr/epics/base/startup/EpicsHostArch) + +ENV=EPICS_HOST_ARCH=$(EPICS_HOST_ARCH) + +build: build-stamp + +build-stamp: + dh_testdir + + ln -s /usr/epics/extensions/configure + + sed -e '/TOP=/ s|\.\./\.\.|.|' Makefile > fixed.make + + $(MAKE) -f fixed.make $(ENV) USE_RPATH=NO + + $(MAKE) -C documentation HTMLDOC=htmldoc ALHUserGuide.html + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + rm -rf O.* bin + rm -f configure + rm -f fixed.make + rm -f documentation/ALHUserGuide.html + + dh_clean + +bindir=$(CURDIR)/debian/alh/usr/bin +docdir=$(CURDIR)/debian/alh/usr/share/doc/alh + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + install -d $(bindir) + install bin/$(EPICS_HOST_ARCH)/alh $(bindir) + install bin/$(EPICS_HOST_ARCH)/alh_printer $(bindir) + + install -d $(docdir) + install -d $(docdir)/images + install -t $(docdir) documentation/ALHUserGuide.html README.1st + install -t $(docdir)/images documentation/images/* + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples +# dh_install +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link + dh_strip + dh_compress + dh_fixperms +# dh_perl +# dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure From 0d69c66fccda02f1f7fb265a9e966925543451ad Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sat, 5 Dec 2009 19:04:16 -0500 Subject: [PATCH 02/28] switch to cdbs --- Makefile | 2 +- debian/alh.install | 2 + debian/control | 22 ++++++++-- debian/copyright | 6 ++- debian/rules | 105 ++++++++++----------------------------------- 5 files changed, 49 insertions(+), 88 deletions(-) create mode 100644 debian/alh.install diff --git a/Makefile b/Makefile index 5d7b1f2..4d8aca3 100755 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ # # Makefile,v 1.16 2007/10/02 19:08:22 jba Exp # -TOP=../.. +TOP=. include $(TOP)/configure/CONFIG #=========================== diff --git a/debian/alh.install b/debian/alh.install new file mode 100644 index 0000000..c053cdd --- /dev/null +++ b/debian/alh.install @@ -0,0 +1,2 @@ +usr/bin/alh +usr/bin/alh_printer diff --git a/debian/control b/debian/control index 5b7e372..406135b 100644 --- a/debian/control +++ b/debian/control @@ -2,12 +2,26 @@ Source: alh Section: admin Priority: extra Maintainer: Michael Davidsaver -Build-Depends: debhelper (>= 7), epics-dev (>= 3.14.10-4), epics-dev (< 3.14.11), epics-extensions-dev, htmldoc, libmotif-dev, libx11-dev, libxp-dev, libxmu-dev, libxtst-dev -Standards-Version: 3.7.3 +Build-Depends: debhelper (>= 7), cdbs, + epics-dev (>= 3.14.10-4), epics-dev (<< 3.14.11), + epics-extensions-dev (>= 20091204), + htmldoc, + libmotif-dev, libx11-dev, libxp-dev, libxmu-dev, libxtst-dev +Standards-Version: 3.8.0 Homepage: http://www.aps.anl.gov/epics/extensions/alh/index.php +Package: alh-doc +Section: doc +Architecture: all +Description: EPICS Alarm Handler + A specialized EPICS client which listens for alarms on a preset list + of channels. + Package: alh Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} +Depends: epics-libs (>= 3.14.10-4), epics-libs (<< 3.14.11), + ${shlibs:Depends}, ${misc:Depends}, +Suggests: alh-doc (= ${binary:Version}) Description: EPICS Alarm Handler - A specialized EPICS client which listens for alarms on a preset list of channels. + A specialized EPICS client which listens for alarms on a preset list + of channels. diff --git a/debian/copyright b/debian/copyright index 299f56e..ec789b8 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,9 +3,13 @@ Fri, 28 Aug 2009 13:24:29 -0400. It was downloaded from http://www.aps.anl.gov/epics/extensions/alh/index.php -Upstream Author(s): +Upstream Authors: + Ben-Chin Cha Janet Anderson + Mark Anderson + Marty Kraimer + Albert Kagarmanov Copyright: diff --git a/debian/rules b/debian/rules index 0741730..8626031 100755 --- a/debian/rules +++ b/debian/rules @@ -1,98 +1,39 @@ #!/usr/bin/make -f # -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. -# Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -EPICS_HOST_ARCH:=$(shell /usr/epics/base/startup/EpicsHostArch) +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/class/makefile.mk +include /usr/share/cdbs/1/rules/utils.mk -ENV=EPICS_HOST_ARCH=$(EPICS_HOST_ARCH) +EPICS_HOST_ARCH:=$(shell /usr/epics/base/startup/EpicsHostArch) +# chop out the source version from Changelog (ie 3.14.10) +SOV=$(shell echo "$(DEB_NOEPOCH_VERSION)"| cut -f 1 -d '-') -build: build-stamp +DEB_MAKE_MAKEVARS = EPICS_HOST_ARCH=$(EPICS_HOST_ARCH) USE_RPATH=NO -build-stamp: - dh_testdir +DEB_MAKE_INVOKE = $(DEB_MAKE_ENVVARS) $(MAKE) -C $(DEB_BUILDDIR) $(DEB_MAKE_MAKEVARS) - ln -s /usr/epics/extensions/configure +DEB_MAKE_CLEAN_TARGET = +DEB_MAKE_BUILD_TARGET = all +DEB_MAKE_INSTALL_TARGET = all INSTALL_LOCATION=$(CURDIR)/debian/tmp/usr +DEB_MAKE_CHECK_TARGET = - sed -e '/TOP=/ s|\.\./\.\.|.|' Makefile > fixed.make +# prevent debug targets from being stripped +DEB_DH_STRIP_ARGS := -Xdebug - $(MAKE) -f fixed.make $(ENV) USE_RPATH=NO +DEB_INSTALL_DOCS_alh-doc := documentation/* - $(MAKE) -C documentation HTMLDOC=htmldoc ALHUserGuide.html +post-patches:: configure - touch $@ +configure: + ln -s /usr/epics/extensions/configure . -clean: - dh_testdir - dh_testroot - rm -f build-stamp configure-stamp +install/alh:: + mv $(CURDIR)/debian/tmp/usr/bin/$(EPICS_HOST_ARCH)/alh* $(CURDIR)/debian/tmp/usr/bin + rmdir $(CURDIR)/debian/tmp/usr/bin/$(EPICS_HOST_ARCH) - rm -rf O.* bin +clean:: + rm -rf bin O.$(EPICS_HOST_ARCH) rm -f configure - rm -f fixed.make - rm -f documentation/ALHUserGuide.html - - dh_clean - -bindir=$(CURDIR)/debian/alh/usr/bin -docdir=$(CURDIR)/debian/alh/usr/share/doc/alh - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - install -d $(bindir) - install bin/$(EPICS_HOST_ARCH)/alh $(bindir) - install bin/$(EPICS_HOST_ARCH)/alh_printer $(bindir) - - install -d $(docdir) - install -d $(docdir)/images - install -t $(docdir) documentation/ALHUserGuide.html README.1st - install -t $(docdir)/images documentation/images/* - - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_installexamples -# dh_install -# dh_installmenu -# dh_installdebconf -# dh_installlogrotate -# dh_installemacsen -# dh_installpam -# dh_installmime -# dh_python -# dh_installinit -# dh_installcron -# dh_installinfo - dh_installman - dh_link - dh_strip - dh_compress - dh_fixperms -# dh_perl -# dh_makeshlibs - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install configure From a6c3c17df8890e9e556545458e1a7b931be544da Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sat, 5 Dec 2009 19:05:56 -0500 Subject: [PATCH 03/28] 1.2.24-2 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 93298e2..479c91f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +alh (1.2.24-2) unstable; urgency=low + + * Fix dependencies + + -- Michael Davidsaver Fri, 04 Dec 2009 10:04:35 -0500 + alh (1.2.24-1) unstable; urgency=low * Initial release From 8910e4c72f29fe9dfaef3c83ed9f4e8d0c9b1e90 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sat, 5 Dec 2009 19:10:50 -0500 Subject: [PATCH 04/28] remove dependency on libXp --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 406135b..4dea803 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,7 @@ Build-Depends: debhelper (>= 7), cdbs, epics-dev (>= 3.14.10-4), epics-dev (<< 3.14.11), epics-extensions-dev (>= 20091204), htmldoc, - libmotif-dev, libx11-dev, libxp-dev, libxmu-dev, libxtst-dev + libmotif-dev, libx11-dev, libxmu-dev, libxtst-dev Standards-Version: 3.8.0 Homepage: http://www.aps.anl.gov/epics/extensions/alh/index.php From e540e965cde5282f6a90d5522faa4cbdee87b935 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sat, 5 Dec 2009 19:44:09 -0500 Subject: [PATCH 05/28] seperate documentation --- debian/alh-doc.install | 1 + debian/alh.lintian-overrides | 2 ++ debian/control | 15 ++++++++------- debian/rules | 6 ++++-- 4 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 debian/alh-doc.install create mode 100644 debian/alh.lintian-overrides diff --git a/debian/alh-doc.install b/debian/alh-doc.install new file mode 100644 index 0000000..90374d6 --- /dev/null +++ b/debian/alh-doc.install @@ -0,0 +1 @@ +usr/share/doc/alh diff --git a/debian/alh.lintian-overrides b/debian/alh.lintian-overrides new file mode 100644 index 0000000..49e36c0 --- /dev/null +++ b/debian/alh.lintian-overrides @@ -0,0 +1,2 @@ +alh: binary-without-manpage +# No manpage is provided diff --git a/debian/control b/debian/control index 4dea803..d49ec4f 100644 --- a/debian/control +++ b/debian/control @@ -10,13 +10,6 @@ Build-Depends: debhelper (>= 7), cdbs, Standards-Version: 3.8.0 Homepage: http://www.aps.anl.gov/epics/extensions/alh/index.php -Package: alh-doc -Section: doc -Architecture: all -Description: EPICS Alarm Handler - A specialized EPICS client which listens for alarms on a preset list - of channels. - Package: alh Architecture: any Depends: epics-libs (>= 3.14.10-4), epics-libs (<< 3.14.11), @@ -25,3 +18,11 @@ Suggests: alh-doc (= ${binary:Version}) Description: EPICS Alarm Handler A specialized EPICS client which listens for alarms on a preset list of channels. + +Package: alh-doc +Section: doc +Architecture: all +Conflicts: alh (<< 1.2.25-1) +Description: EPICS Alarm Handler + A specialized EPICS client which listens for alarms on a preset list + of channels. diff --git a/debian/rules b/debian/rules index 8626031..d75974d 100755 --- a/debian/rules +++ b/debian/rules @@ -23,8 +23,6 @@ DEB_MAKE_CHECK_TARGET = # prevent debug targets from being stripped DEB_DH_STRIP_ARGS := -Xdebug -DEB_INSTALL_DOCS_alh-doc := documentation/* - post-patches:: configure configure: @@ -34,6 +32,10 @@ install/alh:: mv $(CURDIR)/debian/tmp/usr/bin/$(EPICS_HOST_ARCH)/alh* $(CURDIR)/debian/tmp/usr/bin rmdir $(CURDIR)/debian/tmp/usr/bin/$(EPICS_HOST_ARCH) +install/alh-doc:: + install -d $(CURDIR)/debian/tmp/usr/share/doc/alh + cp -r documentation/* $(CURDIR)/debian/tmp/usr/share/doc/alh/ + clean:: rm -rf bin O.$(EPICS_HOST_ARCH) rm -f configure From ae0b96ec59937c9d382f2aabf86b87e07c5e0e24 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sat, 5 Dec 2009 19:45:46 -0500 Subject: [PATCH 06/28] 1.2.25-1 --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/changelog b/debian/changelog index 479c91f..952e407 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +alh (1.2.25-1) unstable; urgency=low + + * New Upstream Version + * Move html manual to alh-doc package + + -- Michael Davidsaver Fri, 04 Dec 2009 10:17:13 -0500 + alh (1.2.24-2) unstable; urgency=low * Fix dependencies From 8956fe1918a608abb50885ff173955fc98ad991e Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sat, 5 Dec 2009 20:14:14 -0500 Subject: [PATCH 07/28] Revert "remove dependency on libXp" The libXp is not used, but its headers are. This reverts commit 8910e4c72f29fe9dfaef3c83ed9f4e8d0c9b1e90. --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index d49ec4f..7344a9d 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,7 @@ Build-Depends: debhelper (>= 7), cdbs, epics-dev (>= 3.14.10-4), epics-dev (<< 3.14.11), epics-extensions-dev (>= 20091204), htmldoc, - libmotif-dev, libx11-dev, libxmu-dev, libxtst-dev + libmotif-dev, libx11-dev, libxp-dev, libxmu-dev, libxtst-dev Standards-Version: 3.8.0 Homepage: http://www.aps.anl.gov/epics/extensions/alh/index.php From 67d836b7ef6b66c4604ce85aec50debf902a3f0e Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sun, 27 Dec 2009 18:19:23 -0500 Subject: [PATCH 08/28] library dep will be generated --- debian/control | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/debian/control b/debian/control index 7344a9d..c74d86d 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: admin Priority: extra Maintainer: Michael Davidsaver Build-Depends: debhelper (>= 7), cdbs, - epics-dev (>= 3.14.10-4), epics-dev (<< 3.14.11), + epics-dev (>= 3.14.10-10), epics-dev (<< 3.14.11), epics-extensions-dev (>= 20091204), htmldoc, libmotif-dev, libx11-dev, libxp-dev, libxmu-dev, libxtst-dev @@ -12,8 +12,7 @@ Homepage: http://www.aps.anl.gov/epics/extensions/alh/index.php Package: alh Architecture: any -Depends: epics-libs (>= 3.14.10-4), epics-libs (<< 3.14.11), - ${shlibs:Depends}, ${misc:Depends}, +Depends: ${shlibs:Depends}, ${misc:Depends}, Suggests: alh-doc (= ${binary:Version}) Description: EPICS Alarm Handler A specialized EPICS client which listens for alarms on a preset list From 59c3907063749d8953e9eec80d4f655d2176f132 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sun, 27 Dec 2009 18:19:44 -0500 Subject: [PATCH 09/28] 1.2.25-2 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 952e407..2b8b20a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +alh (1.2.25-2) unstable; urgency=low + + * Update dependencies + + -- Michael Davidsaver Sun, 27 Dec 2009 18:19:29 -0500 + alh (1.2.25-1) unstable; urgency=low * New Upstream Version From cb2c62e7129f1a391cc3437c5ffce7644c299401 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 16 Aug 2010 16:56:47 -0400 Subject: [PATCH 10/28] Base now in /usr/lib/epics --- debian/control | 4 ++-- debian/rules | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/control b/debian/control index c74d86d..60a9685 100644 --- a/debian/control +++ b/debian/control @@ -3,8 +3,8 @@ Section: admin Priority: extra Maintainer: Michael Davidsaver Build-Depends: debhelper (>= 7), cdbs, - epics-dev (>= 3.14.10-10), epics-dev (<< 3.14.11), - epics-extensions-dev (>= 20091204), + epics-dev (>= 3.14.11-2), + epics-extensions-dev (>= 20091204.1), htmldoc, libmotif-dev, libx11-dev, libxp-dev, libxmu-dev, libxtst-dev Standards-Version: 3.8.0 diff --git a/debian/rules b/debian/rules index d75974d..be9a536 100755 --- a/debian/rules +++ b/debian/rules @@ -7,7 +7,7 @@ include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/makefile.mk include /usr/share/cdbs/1/rules/utils.mk -EPICS_HOST_ARCH:=$(shell /usr/epics/base/startup/EpicsHostArch) +EPICS_HOST_ARCH:=$(shell /usr/lib/epics/startup/EpicsHostArch) # chop out the source version from Changelog (ie 3.14.10) SOV=$(shell echo "$(DEB_NOEPOCH_VERSION)"| cut -f 1 -d '-') @@ -26,7 +26,7 @@ DEB_DH_STRIP_ARGS := -Xdebug post-patches:: configure configure: - ln -s /usr/epics/extensions/configure . + ln -s /usr/lib/epics/extensions/configure . install/alh:: mv $(CURDIR)/debian/tmp/usr/bin/$(EPICS_HOST_ARCH)/alh* $(CURDIR)/debian/tmp/usr/bin From 53ff9fbada268276a1b6b1561fbfcc179c787a90 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 16 Aug 2010 17:28:15 -0400 Subject: [PATCH 11/28] 1.2.25-3 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 2b8b20a..a2f0792 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +alh (1.2.25-3) unstable; urgency=low + + * Base in /usr/lib/epics + + -- Michael Davidsaver Mon, 16 Aug 2010 17:27:51 -0400 + alh (1.2.25-2) unstable; urgency=low * Update dependencies From 1cdb85d5972a14d314f70731d8b38e8326a37f56 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 18 Aug 2010 19:40:06 -0400 Subject: [PATCH 12/28] mark section for contrib --- debian/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index 60a9685..5b18853 100644 --- a/debian/control +++ b/debian/control @@ -1,5 +1,5 @@ Source: alh -Section: admin +Section: contrib/admin Priority: extra Maintainer: Michael Davidsaver Build-Depends: debhelper (>= 7), cdbs, @@ -19,7 +19,7 @@ Description: EPICS Alarm Handler of channels. Package: alh-doc -Section: doc +Section: contrib/doc Architecture: all Conflicts: alh (<< 1.2.25-1) Description: EPICS Alarm Handler From 41635f2c670ad6982371bf86866b3c2f959e2455 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 8 Mar 2012 11:47:42 -0500 Subject: [PATCH 13/28] 1.2.26-1 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index a2f0792..d699153 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +alh (1.2.26-1) unstable; urgency=low + + * New upstream version + + -- Michael Davidsaver Thu, 08 Mar 2012 11:47:08 -0500 + alh (1.2.25-3) unstable; urgency=low * Base in /usr/lib/epics From 039f53563978ba349c091d7a951f55173f2af4ff Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 9 Oct 2012 18:57:57 -0400 Subject: [PATCH 14/28] BEEPCMD Add option to run arbitrary shell command instead of X bell Command does not run from gui thread. Command will not be run concurrently. --- alConfig.c | 33 +++++++++++++++ alh.h | 1 + os/default/alAudio.c | 97 +++++++++++++++++++++++++++++++++++++++++++- test.alhConfig | 1 + 4 files changed, 131 insertions(+), 1 deletion(-) diff --git a/alConfig.c b/alConfig.c index c8ca3bb..4078bb3 100644 --- a/alConfig.c +++ b/alConfig.c @@ -441,6 +441,37 @@ int context,int caConnect,struct mainGroup *pmainGroup) return; } + if (strncmp(&buf[1],"BEEPCMD",7)==0) { + unsigned int start=8, end = strlen(buf) - 1; + + /* skip leading whitespace to find start of command */ + for(; start<=end && (buf[start]=='\t' || buf[start]==' '); start++) {} + + if(start>end) { + print_error(buf, "expected argument after BEEPCMD"); + return; + } + + /* back track to trim trailing whitespace */ + for(; end>=start && (buf[end]=='\0' || isspace(buf[end])); end--) {} + + if(end>start) { + if(psetup.beepCmd) + free(psetup.beepCmd); + psetup.beepCmd = malloc(end-start+2); + if(!psetup.beepCmd) { + print_error(buf, "Not enough memory for BEEPCMD"); + } else { + memcpy(psetup.beepCmd, &buf[start], end-start+1); + psetup.beepCmd[end-start+1] = '\0'; + } + } else { + print_error(buf, "Missing argument for BEEPCMD"); + } + + return; + } + if (strncmp(&buf[1],"HEARTBEATPV",11)==0) { /*HEARTBEATPV*/ if (pmainGroup->heartbeatPV.name) return; @@ -774,6 +805,8 @@ void alWriteConfig(char *filename,struct mainGroup *pmainGroup) if (!fw) return; if (psetup.beepSevr > 1) fprintf(fw,"$BEEPSEVERITY %s\n",alhAlarmSeverityString[psetup.beepSevr]); + if (psetup.beepCmd) + fprintf(fw,"$BEEPCMD %s\n", psetup.beepCmd); /*alWriteGroupConfig(fw,(SLIST *)&(pmainGroup->p1stgroup));*/ alWriteGroupConfig(fw,(SLIST *)pmainGroup); fclose(fw); diff --git a/alh.h b/alh.h index c0047d6..7e922d0 100644 --- a/alh.h +++ b/alh.h @@ -181,6 +181,7 @@ struct setup { char logFile[NAMEDEFAULT_SIZE]; /* alarm log file name */ char opModFile[NAMEDEFAULT_SIZE]; /* opMod log file name */ char saveFile[NAMEDEFAULT_SIZE]; /* save config file name */ + char *beepCmd; /* Optional command in place of X bell*/ Boolean silenceForever; /* 1 - beepoff forever is true */ short silenceOneHour; /* 1 - beepoff one hour is true */ short silenceCurrent; /* 1 - current beep on 0 - off */ diff --git a/os/default/alAudio.c b/os/default/alAudio.c index 6e58266..d72a4f6 100644 --- a/os/default/alAudio.c +++ b/os/default/alAudio.c @@ -18,9 +18,85 @@ * */ +#include #include +#include +#include +#include + #include "alh.h" +static pthread_mutex_t beep_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t beep_wake = PTHREAD_COND_INITIALIZER; +static pthread_once_t beep_setup = PTHREAD_ONCE_INIT; +/* states: -2 done, -1 shutdown, 0 idle, 1 playing, 2 request play */ +static int beeping = 0; +static pthread_t beeper; + +#define LOCK() assert(pthread_mutex_lock(&beep_lock)==0) +#define UNLOCK() assert(pthread_mutex_unlock(&beep_lock)==0) + +static void beeper_shutdown(void) +{ + /* request shutdown and spin until beeper thread stops */ + LOCK(); + beeping = -1; + while(beeping!=-2) { + UNLOCK(); + pthread_cond_broadcast(&beep_wake); + usleep(10000); /* 10ms */ + LOCK(); + } + /* thread is stopped now */ + free(psetup.beepCmd); + psetup.beepCmd = NULL; + + UNLOCK(); +} + +static void* beeper_thread(void* junk) +{ + LOCK(); + + atexit(&beeper_shutdown); + + while(beeping>=0) { + + assert(pthread_cond_wait(&beep_wake, &beep_lock)==0); + + if(beeping==2) { + beeping=1; + UNLOCK(); + + system(psetup.beepCmd); + + LOCK(); + /* be careful not to overwrite the shutdown command */ + if(beeping==1) + beeping=0; + } + } + UNLOCK(); + beeping=-2; + return NULL; +} + +static void setup(void) +{ + if(!psetup.beepCmd) + return; + + if(pthread_create(&beeper, NULL, &beeper_thread, NULL)) { + printf("Error creating beeper thread!\n"); + /* clear beepCmd so that future calls to alBeep() will + * call XBell(). + */ + free(psetup.beepCmd); + psetup.beepCmd = NULL; + return; + } +} + /* Audio device not implemented */ /****************************************************** @@ -28,9 +104,28 @@ ******************************************************/ int alBeep(Display *displayBB) { - /* system("play /path/to/beep.wav"); */ + pthread_once(&beep_setup, &setup); + + if(!psetup.beepCmd) { XBell(displayBB,0); return 0; + + } else { + LOCK(); + + /* wakeup for new command. + * also if still waiting for wakeup + * if beeper didn't start fast enough + * on the previous call. + */ + if(beeping==0 || beeping==2) { + beeping=2; + pthread_cond_broadcast(&beep_wake); + } + + UNLOCK(); + return 0; + } } diff --git a/test.alhConfig b/test.alhConfig index 2475da1..84c96c8 100644 --- a/test.alhConfig +++ b/test.alhConfig @@ -1,3 +1,4 @@ +$BEEPCMD sleep 5;date -R >> alhtest $BEEPSEVERITY MAJOR GROUP NULL JBA_TEST_MAIN_GROUP $COMMAND xload From d6d484343bc0c2e093d2cd7741bc6be0f70ade14 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 9 Oct 2012 18:58:15 -0400 Subject: [PATCH 15/28] workaround crash on startup with test.alhConfig --- axRunW.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axRunW.c b/axRunW.c index f45c9af..631f64a 100644 --- a/axRunW.c +++ b/axRunW.c @@ -378,7 +378,7 @@ void silenceCurrentReset(void *area) { if (psetup.silenceCurrent) { psetup.silenceCurrent = FALSE; - if (((ALINK*)area)->silenceCurrent) { + if (area && ((ALINK*)area)->silenceCurrent) { XmToggleButtonGadgetSetState(((ALINK*)area)->silenceCurrent, FALSE,FALSE); } From 6b5fc916e4e830643cc33d480baeaccc5a7b2b09 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 9 Oct 2012 19:00:33 -0400 Subject: [PATCH 16/28] 1.2.26-2 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index d699153..2fe86e7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +alh (1.2.26-2) squeeze-2012A; urgency=low + + * Add BEEPCMD option to run as shell command instead of XBell() + + -- Michael Davidsaver Tue, 09 Oct 2012 18:58:25 -0400 + alh (1.2.26-1) unstable; urgency=low * New upstream version From bfa2cfc10f5e5ea27b427176f94c573fb32bfab4 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 5 Dec 2012 17:57:18 -0500 Subject: [PATCH 17/28] 1.2.26-2.1 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 2fe86e7..6ff8ec3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +alh (1.2.26-2.1) unstable; urgency=low + + * Rebuild for epics 3.14.12 + + -- Michael Davidsaver Wed, 05 Dec 2012 17:56:34 -0500 + alh (1.2.26-2) squeeze-2012A; urgency=low * Add BEEPCMD option to run as shell command instead of XBell() From d74670cfc491eff77fd1d29bd9266e11d3482286 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 10 Mar 2016 19:54:31 -0500 Subject: [PATCH 18/28] missing -lpthread --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 1f15de2..48a2dae 100755 --- a/Makefile +++ b/Makefile @@ -185,6 +185,8 @@ X11_DIR = $(X11_LIB) RCS_WIN32 += alh.rc +PROD_SYS_LIBS += pthread + include $(TOP)/configure/RULES alh.res:../alh.ico From 98c0de2b0946b5a7e96f042c5e07b5c84c608585 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 11 Mar 2016 09:30:04 -0500 Subject: [PATCH 19/28] 1.2.26-3 --- debian/changelog | 8 ++++++++ debian/control | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 6ff8ec3..b8273ca 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +alh (1.2.26-3) unstable; urgency=medium + + * Build against Base 3.15.3 + * Missing -lpthread + * Depend on epics-extensions-dev w/ RULES_PYTHON fix + + -- Michael Davidsaver Fri, 11 Mar 2016 09:29:02 -0500 + alh (1.2.26-2.1) unstable; urgency=low * Rebuild for epics 3.14.12 diff --git a/debian/control b/debian/control index 5b18853..da3656a 100644 --- a/debian/control +++ b/debian/control @@ -1,10 +1,10 @@ Source: alh Section: contrib/admin Priority: extra -Maintainer: Michael Davidsaver +Maintainer: Michael Davidsaver Build-Depends: debhelper (>= 7), cdbs, epics-dev (>= 3.14.11-2), - epics-extensions-dev (>= 20091204.1), + epics-extensions-dev (>= 20130514.5), htmldoc, libmotif-dev, libx11-dev, libxp-dev, libxmu-dev, libxtst-dev Standards-Version: 3.8.0 From e1fc352f7910d96623329f28ce7281e470363b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schr=C3=B6der?= Date: Wed, 11 Mar 2020 10:43:02 +0100 Subject: [PATCH 20/28] remove libxp-dev dependency --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index da3656a..4bcc56c 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,7 @@ Build-Depends: debhelper (>= 7), cdbs, epics-dev (>= 3.14.11-2), epics-extensions-dev (>= 20130514.5), htmldoc, - libmotif-dev, libx11-dev, libxp-dev, libxmu-dev, libxtst-dev + libmotif-dev, libx11-dev, libxmu-dev, libxtst-dev Standards-Version: 3.8.0 Homepage: http://www.aps.anl.gov/epics/extensions/alh/index.php From 8835aa4e40001612f11878227cef2304b4fd213d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schr=C3=B6der?= Date: Wed, 11 Mar 2020 10:43:23 +0100 Subject: [PATCH 21/28] set compat level to 9 --- debian/compat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/compat b/debian/compat index 7f8f011..ec63514 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -7 +9 From cf9e67531cd3128729abecaf198a1364bd59c983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schr=C3=B6der?= Date: Wed, 11 Mar 2020 10:44:49 +0100 Subject: [PATCH 22/28] epics-debhelper>=8.12 uses LINKER_USE_RPATH instead of USE_RPATH --- debian/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index be9a536..7b1709b 100755 --- a/debian/rules +++ b/debian/rules @@ -11,7 +11,7 @@ EPICS_HOST_ARCH:=$(shell /usr/lib/epics/startup/EpicsHostArch) # chop out the source version from Changelog (ie 3.14.10) SOV=$(shell echo "$(DEB_NOEPOCH_VERSION)"| cut -f 1 -d '-') -DEB_MAKE_MAKEVARS = EPICS_HOST_ARCH=$(EPICS_HOST_ARCH) USE_RPATH=NO +DEB_MAKE_MAKEVARS = EPICS_HOST_ARCH=$(EPICS_HOST_ARCH) LINKER_USE_RPATH=NO DEB_MAKE_INVOKE = $(DEB_MAKE_ENVVARS) $(MAKE) -C $(DEB_BUILDDIR) $(DEB_MAKE_MAKEVARS) From 05526c78bf82d9e54c83cc3028ba43b97a7743e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schr=C3=B6der?= Date: Thu, 12 Mar 2020 14:59:43 +0100 Subject: [PATCH 23/28] update dependencies --- debian/control | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian/control b/debian/control index 4bcc56c..74cf4d2 100644 --- a/debian/control +++ b/debian/control @@ -2,9 +2,9 @@ Source: alh Section: contrib/admin Priority: extra Maintainer: Michael Davidsaver -Build-Depends: debhelper (>= 7), cdbs, - epics-dev (>= 3.14.11-2), - epics-extensions-dev (>= 20130514.5), +Build-Depends: debhelper (>= 9), cdbs, + epics-dev (>= 3.15.5-1~), epics-debhelper (>= 8.17~), + epics-extensions-dev (>= 20130514.5~), htmldoc, libmotif-dev, libx11-dev, libxmu-dev, libxtst-dev Standards-Version: 3.8.0 From 2dae2011c887d7e4c120aa7097615b97c9e908b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schr=C3=B6der?= Date: Thu, 12 Mar 2020 15:01:48 +0100 Subject: [PATCH 24/28] fix i386 build --- debian/rules | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index 7b1709b..6606805 100755 --- a/debian/rules +++ b/debian/rules @@ -11,7 +11,16 @@ EPICS_HOST_ARCH:=$(shell /usr/lib/epics/startup/EpicsHostArch) # chop out the source version from Changelog (ie 3.14.10) SOV=$(shell echo "$(DEB_NOEPOCH_VERSION)"| cut -f 1 -d '-') -DEB_MAKE_MAKEVARS = EPICS_HOST_ARCH=$(EPICS_HOST_ARCH) LINKER_USE_RPATH=NO +ifeq "$(DEB_BUILD_ARCH)" "i386" +EPICS_HOST_ARCH:=linux-x86 +else ifeq "$(DEB_BUILD_ARCH)" "amd64" +EPICS_HOST_ARCH:=linux-x86_64 +else +EPICS_HOST_ARCH:=$(shell /usr/lib/epics/startup/EpicsHostArch) +endif + +DEB_MAKE_MAKEVARS = EPICS_HOST_ARCH=$(EPICS_HOST_ARCH) LINKER_USE_RPATH=NO USE_SDDS=NO +DEB_MAKE_MAKEVARS+= SHRLIB_VERSION=$(SOV) DEB_MAKE_INVOKE = $(DEB_MAKE_ENVVARS) $(MAKE) -C $(DEB_BUILDDIR) $(DEB_MAKE_MAKEVARS) From 64a0f552d5e65e04ec9d6a1a53ff0dea6fe570d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schr=C3=B6der?= Date: Thu, 12 Mar 2020 15:11:19 +0100 Subject: [PATCH 25/28] DEB_DH_STRIP_ARGS is deprecated --- debian/rules | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/debian/rules b/debian/rules index 6606805..6ddd7b6 100755 --- a/debian/rules +++ b/debian/rules @@ -29,9 +29,6 @@ DEB_MAKE_BUILD_TARGET = all DEB_MAKE_INSTALL_TARGET = all INSTALL_LOCATION=$(CURDIR)/debian/tmp/usr DEB_MAKE_CHECK_TARGET = -# prevent debug targets from being stripped -DEB_DH_STRIP_ARGS := -Xdebug - post-patches:: configure configure: @@ -48,3 +45,9 @@ install/alh-doc:: clean:: rm -rf bin O.$(EPICS_HOST_ARCH) rm -f configure + +# prevent debug targets from being stripped +override_dh_strip: + dh_strip -Xdebug + +.PHONY: override_dh_strip From 650a622b946d7d1713a6a95f113ac8ecb8974bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schr=C3=B6der?= Date: Thu, 12 Mar 2020 15:27:10 +0100 Subject: [PATCH 26/28] New upstream version 1.2.35 --- Makefile | 6 +- alConfig.c | 19 +- alLib.c | 74 +++-- alLog.c | 122 ++++---- alh.c | 6 +- alh.h | 10 +- alh.notes | 109 ++++++- alh_DB.c | 7 +- awAlh.c | 176 +++++++++--- ax.h | 4 +- axArea.c | 21 +- axArea.h | 6 +- axRunW.c | 58 ++-- browser.c | 232 ++------------- current.c | 15 +- dialog.c | 37 ++- documentation/ALH.html | 149 +++++++--- documentation/ALH.title.html | 4 +- documentation/Makefile | 22 +- documentation/images/alhAlarmLogFile.gif | Bin 14246 -> 20480 bytes .../images/alhCurrentAlarmHistory.gif | Bin 8553 -> 13363 bytes documentation/images/alhDisplayFilter.gif | Bin 0 -> 4764 bytes documentation/images/alhMainWindowAlarms.gif | Bin 10714 -> 45944 bytes .../images/alhMainWindowNoAlarms.gif | Bin 12938 -> 42482 bytes documentation/images/alhMessage.gif | Bin 4278 -> 8046 bytes documentation/images/alhSendMessage.gif | Bin 3217 -> 10233 bytes documentation/images/alhSetupMenu.gif | Bin 2616 -> 2761 bytes .../images/alhSilenceIntervalSelections.gif | Bin 0 -> 1699 bytes fallback.h | 2 + file.c | 165 ++++++++--- force.c | 30 +- mask.c | 6 +- os/Linux/alAudio.c | 49 ++++ os/Linux/alAudio.h | 20 ++ os/WIN32/alAudio.c | 10 +- os/default/alAudio.c | 12 +- os/solaris/alAudio.c | 9 +- process.c | 2 +- property.c | 49 ++-- scroll.c | 267 +++++++----------- showmask.c | 8 +- version.h | 8 +- 42 files changed, 968 insertions(+), 746 deletions(-) create mode 100755 documentation/images/alhDisplayFilter.gif create mode 100755 documentation/images/alhSilenceIntervalSelections.gif create mode 100644 os/Linux/alAudio.c create mode 100644 os/Linux/alAudio.h diff --git a/Makefile b/Makefile index 9b1e57d..d8848e3 100755 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ # in the file LICENSE that is included with this distribution. #************************************************************************* # -# Makefile,v 1.18 2008/12/03 17:20:17 jba Exp +# Makefile,v 1.22 2013/04/22 16:07:23 jba Exp # TOP=../.. include $(TOP)/configure/CONFIG @@ -157,11 +157,11 @@ alh_DB_SRCS = alh_DB.c alh_printer_SRCS = printer.c -PROD_HOST_DEFAULT = alh alh_printer +PROD_HOST_DEFAULT = alh alh_printer alh_DB PROD_HOST_WIN32 = alh WIN32_RUNTIME=MD -USR_CFLAGS_WIN32 += /DWIN32 /D_WINDOWS +USR_CFLAGS_WIN32 += -DWIN32 -D_WINDOWS ifndef BORLAND USR_LDFLAGS_WIN32 += /SUBSYSTEM:WINDOWS endif diff --git a/alConfig.c b/alConfig.c index c8ca3bb..50d0526 100644 --- a/alConfig.c +++ b/alConfig.c @@ -119,7 +119,10 @@ int caConnect) fp = fopen(filename,"r"); if(fp==NULL) { - perror("Could not open Alarm Configuration File"); + sprintf(buf, + "Could not open Alarm Configuration File: %.*s", + (int)MAX_STRING_LENGTH-42,filename); + perror(buf); exit(-1); } @@ -182,7 +185,7 @@ struct mainGroup *pmainGroup) parent_link = *pglink; - rtn = sscanf(buf,"%20s%32s%32s",command,parent,name); + rtn = sscanf(buf,"%20s%64s%64s",command,parent,name); if(rtn!=3) { print_error(buf,"Invalid GROUP command"); @@ -227,7 +230,7 @@ struct mainGroup *pmainGroup) parent_link = parent_link->parent; if(parent_link==NULL) { - print_error(buf,"Can not find parent"); + print_error(buf,"Cannot find parent"); return; } @@ -254,7 +257,7 @@ struct mainGroup *pmainGroup) if (pglink) parent_link = *pglink; - rtn = sscanf(buf,"%20s%32s%s",command,parent,name); + rtn = sscanf(buf,"%20s%64s%s",command,parent,name); if(rtn!=3) { print_error(buf,"Invalid INCLUDE command"); @@ -361,7 +364,7 @@ int caConnect,struct mainGroup *pmainGroup) parent_link = parent_link->parent; if(parent_link==NULL) { - print_error(buf,"Can not find parent"); + print_error(buf,"Cannot find parent"); return; } @@ -444,7 +447,7 @@ int context,int caConnect,struct mainGroup *pmainGroup) if (strncmp(&buf[1],"HEARTBEATPV",11)==0) { /*HEARTBEATPV*/ if (pmainGroup->heartbeatPV.name) return; - rtn = sscanf(buf,"%20s%32s%f%d",command,name,&rateIn,&valueIn); + rtn = sscanf(buf,"%20s%64s%f%d",command,name,&rateIn,&valueIn); if(rtn>=2) { if(rtn>=3) rate = rateIn; if(rtn>=4) value = valueIn; @@ -491,7 +494,7 @@ int context,int caConnect,struct mainGroup *pmainGroup) if (gcdata->pforcePV && gcdata->pforcePV->name) return; if (!gcdata->pforcePV) gcdata->pforcePV=(FORCEPV*)calloc(1,sizeof(FORCEPV)); dbl=0.0; - rtn = sscanf(buf,"%20s%32s%6s%lf%9s",command,name,mask,&dbl,string); + rtn = sscanf(buf,"%20s%64s%6s%lf%9s",command,name,mask,&dbl,string); if(rtn>=3) alSetMask(mask,&(gcdata->pforcePV->forceMask)); if (rtn >= 4) gcdata->pforcePV->forceValue = dbl; else gcdata->pforcePV->forceValue=1; @@ -598,7 +601,7 @@ int context,int caConnect,struct mainGroup *pmainGroup) if (strncmp(&buf[1],"SEVRPV",6)==0) { /*SEVRPV*/ if(strcmp(gcdata->sevrPVName,"-") != 0) return; - rtn = sscanf(buf,"%20s%32s",command,name); + rtn = sscanf(buf,"%20s%64s",command,name); if(rtn>=2) { gcdata->sevrPVName = (char *)calloc(1,strlen(name)+1); strcpy(gcdata->sevrPVName,name); diff --git a/alLib.c b/alLib.c index 8537117..304371f 100644 --- a/alLib.c +++ b/alLib.c @@ -48,6 +48,7 @@ static void alNewAlarmProcess(int stat,int sev, int acks,int ackt, void alSetAckTChan(CLINK *clink,int ackt); short alHighestBeepSeverity(int sevr[ALH_ALARM_NSEV], int beepSevr); static void alSetBeepSevCount(GLINK* glink,int beepSevr,int oldBeepSevr); +static void alAlarmFilterReset(CLINK *clink); char *Strncat( char *dest, @@ -57,7 +58,8 @@ char *Strncat( /* max must be >= 0 and no more than stringsize - 1 */ /* for char string[10]; max must be <= 9 */ -size_t l, newMax; +int newMax; +size_t l; char *s; l = strlen( dest ); @@ -578,23 +580,14 @@ static void alarmCountFilter_callback(XtPointer cd, XtIntervalId *id) { COUNTFILTER *countFilter=(COUNTFILTER *)cd; time_t alarmTime; - int j; #if DEBUG_CALLBACKS - { - static int n=0; - - printf("alarmCountFilter_callback: n=%d\n",n++); - } + { static int n=0; printf("alarmCountFilter_callback: n=%d\n",n++); } #endif alarmTime = countFilter->alarmTime; countFilter->alarmTime=0; countFilter->timeoutId=0; - /* reset alarm count filter when new alarm is processed */ - if (countFilter->inputCount){ - for (j=0;j<=2*(countFilter->inputCount)-1;j++){countFilter->alarmTimeHistory[j]=0;} - } - countFilter->countIndex=0; + alAlarmFilterReset(countFilter->clink); alNewAlarmProcess(countFilter->stat,countFilter->sev, countFilter->acks,countFilter->ackt, countFilter->value,countFilter->clink,alarmTime); @@ -668,7 +661,7 @@ void alNewEvent(int stat,int sevr,int acks,int acktCA,char *value,CLINK *clink) void alNewAlarmFilter(int stat,int sev,int acks,int ackt,char *value,CLINK *clink) { struct chanData *cdata; - int sevr_prev, i, j; + int sevr_prev, i; time_t alarmTime; COUNTFILTER *countFilter; @@ -693,8 +686,8 @@ void alNewAlarmFilter(int stat,int sev,int acks,int ackt,char *value,CLINK *clin return; } - /* Process if inputCount or inputSeconds is zero */ - if (countFilter->inputSeconds==0 || countFilter->inputCount==0) { + /* Process if inputSeconds is zero */ + if (countFilter->inputSeconds==0 ) { alNewAlarmProcess(stat,sev,acks,ackt,value,clink,alarmTime); return; } @@ -726,8 +719,10 @@ void alNewAlarmFilter(int stat,int sev,int acks,int ackt,char *value,CLINK *clin } - /* process changes in acks and ackt and if no timeout then add timeout */ if ( cdata->curSevr!=0 && sev==0 ){ + if ( countFilter->inputCount != -1 ) { + + /* if inputCount not -1 process changes in acks and ackt and add timeout */ alNewAlarmProcess(cdata->curStat,cdata->curSevr,acks,ackt,value,clink,alarmTime); if (countFilter->timeoutId==0) { countFilter->timeoutId = XtAppAddTimeOut(appContext, @@ -735,23 +730,23 @@ void alNewAlarmFilter(int stat,int sev,int acks,int ackt,char *value,CLINK *clin alarmCountFilter_callback,(XtPointer)countFilter); countFilter->alarmTime=alarmTime; } + } else { + + /* if inputCount is -1 dont start a timeout, reset filter and process new alarm state*/ + alAlarmFilterReset(clink); + alNewAlarmProcess(stat,sev,acks,ackt,value,clink,alarmTime); + } } /* check in/out alarm count within time interval*/ + if ( countFilter->inputCount > 0 ) { if ( (sevr_prev==0 && sev!=0) || (sevr_prev!=0 && sev==0)){ i = countFilter->countIndex; if ( !countFilter->alarmTimeHistory || (countFilter->alarmTimeHistory[i] && (((int)difftime(alarmTime,countFilter->alarmTimeHistory[i]))<=countFilter->inputSeconds))){ - /* reset alarm count filter when new alarm is processed */ - if (countFilter->inputCount){ - for (j=0;j<=2*(countFilter->inputCount)-1;j++){countFilter->alarmTimeHistory[j]=0;} - } - if (countFilter->timeoutId){ - XtRemoveTimeOut(countFilter->timeoutId); - countFilter->timeoutId=0; - } - countFilter->countIndex=0; + + alAlarmFilterReset(clink); alNewAlarmProcess(stat,sev,acks,ackt,value,clink,alarmTime); } else { countFilter->alarmTimeHistory[i] = alarmTime; @@ -761,8 +756,37 @@ void alNewAlarmFilter(int stat,int sev,int acks,int ackt,char *value,CLINK *clin } } } + } } + +/*********************************************************** + alNewAlarmFilterReset +************************************************************/ +void alAlarmFilterReset(CLINK *clink) +{ + COUNTFILTER *countFilter; + struct chanData *cdata; + int j; + + if (clink == NULL ) return; + cdata = clink->pchanData; + if (cdata == NULL ) return; + countFilter = cdata->countFilter; + if (countFilter == NULL ) return; + + /* reset alarm count filter when new alarm is processed */ + countFilter->countIndex=0; + if (countFilter->inputCount){ + for (j=0;j<=2*(countFilter->inputCount)-1;j++){countFilter->alarmTimeHistory[j]=0;} + } + if (countFilter->timeoutId){ + XtRemoveTimeOut(countFilter->timeoutId); + countFilter->timeoutId=0; + } +} + + /*********************************************************** alNewAlarmProcess ************************************************************/ diff --git a/alLog.c b/alLog.c index b09e92a..4c8c7bc 100644 --- a/alLog.c +++ b/alLog.c @@ -91,12 +91,16 @@ struct setup psetup = { /* initial files & beeping setup */ "", /* alarm log file name */ "", /* opMod log file name */ "", /* save config file name */ + "", /* sound wav file name */ + "", /* lock files basename */ 0, /* silenceForever */ 0, /* silenceOneHour */ 0, /* silenceCurrent */ 1, /* 1,2,3,4,5 */ 0, /* system highest sevr */ 0, /* system highest unack sevr */ + 0, /* system highest unack sevr >= beep sevr */ + 0, /* new unack sevr after beep sevr tests */ 0, /* config files directory */ 0}; /* log files directory */ @@ -137,10 +141,10 @@ char *displayName; #endif -int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord); +static int filePrintf(int fileType,char *buf,time_t *ptime,int typeOfRecord); #ifdef HAVE_SYSV_IPC -int write2MQ(int, char *); -int write2msgQ(int, char *); +static int write2MQ(int, char *); +static int write2msgQ(int, char *); #endif #ifdef CMLOG @@ -197,6 +201,7 @@ void alLogAlarmMessage(time_t *ptimeofdayAlarm,int messageCode,CLINK* clink,cons (alhArea ? alhArea->blinkString : "N/A"), cdata->value); #endif + if (_xml_flag) /* Use XML-ish entries which are easier to parse. SNS */ { if (!_description_field_flag) @@ -239,7 +244,7 @@ void alLogAlarmMessage(time_t *ptimeofdayAlarm,int messageCode,CLINK* clink,cons if (!_description_field_flag) { if (_global_flag) - sprintf(buff, "%-28s %-12s %-16s %-12s %-5s %-40.40s\n", + sprintf(buff, "%-28s %-12s %-16s %-12s %-5s %-40.40s", cdata->name, alhAlarmStatusString[cdata->curStat], alhAlarmSeverityString[cdata->curSevr], @@ -247,7 +252,7 @@ void alLogAlarmMessage(time_t *ptimeofdayAlarm,int messageCode,CLINK* clink,cons ackTransientsString[cdata->curMask.AckT], cdata->value); else - sprintf(buff, "%-28s %-12s %-16s %-40.40s\n", + sprintf(buff, "%-28s %-12s %-16s %-40.40s", cdata->name, alhAlarmStatusString[cdata->curStat], alhAlarmSeverityString[cdata->curSevr], @@ -256,20 +261,20 @@ void alLogAlarmMessage(time_t *ptimeofdayAlarm,int messageCode,CLINK* clink,cons else { /* _description_field_flag is ON */ if (_global_flag) - sprintf(buff, "%-28s %-28s %-40.40s %-12s %-16s %-12s %-5s\n", + sprintf(buff, "%-28s %-28s %-40.40s %-12s %-16s %-12s %-5s", cdata->name,cdata->description,cdata->value, alhAlarmStatusString[cdata->curStat], alhAlarmSeverityString[cdata->curSevr], alhAlarmSeverityString[cdata->unackSevr], ackTransientsString[cdata->curMask.AckT]); else - sprintf(buff, "%-28s %-28s %-40.40s %-12s %-16s\n", + sprintf(buff, "%-28s %-28s %-40.40s %-12s %-16s", cdata->name,cdata->description,cdata->value, alhAlarmStatusString[cdata->curStat], alhAlarmSeverityString[cdata->curSevr]); } } - filePrintf(fl,buff,ptimeofdayAlarm,messageCode); + filePrintf(ALARM_FILE,buff,ptimeofdayAlarm,messageCode); } @@ -281,6 +286,7 @@ void alLogOpModMessage(int messageCode,GCLINK* gclink,const char* fmt,...) va_list vargs; static char text[1024]; /* DANGER: Fixed buffer size */ struct gcData *gcdata=NULL; + size_t len; if (gclink) gcdata = gclink->pgcData; @@ -306,6 +312,8 @@ void alLogOpModMessage(int messageCode,GCLINK* gclink,const char* fmt,...) (alhArea ? alhArea->blinkString : "N/A")); } #endif + len = strlen(text); + if (text[len-1] == '\n' ) text[len-1]=' '; if (!alhArea || !alhArea->blinkString){ sprintf(buff,"%s",text); @@ -317,7 +325,7 @@ void alLogOpModMessage(int messageCode,GCLINK* gclink,const char* fmt,...) } } - filePrintf(fo,buff,NULL,messageCode); + filePrintf(OPMOD_FILE,buff,NULL,messageCode); } @@ -355,9 +363,8 @@ void alLogOpModAckMessage(int messageCode,GCLINK* gclink,const char* fmt,...) (alhArea ? alhArea->blinkString : "N/A")); } #endif - if (!alhArea || !alhArea->blinkString){ - sprintf(buff," : : %s \n",text); + sprintf(buff," : : %s",text); } else { if (!gcdata){ sprintf(buff,"%s: : %s %-16s",alhArea->blinkString,text, @@ -368,7 +375,7 @@ void alLogOpModAckMessage(int messageCode,GCLINK* gclink,const char* fmt,...) } } - filePrintf(fo,buff,NULL,messageCode); + filePrintf(OPMOD_FILE,buff,NULL,messageCode); } @@ -378,7 +385,7 @@ void alLogOpModAckMessage(int messageCode,GCLINK* gclink,const char* fmt,...) void alLogNotSaveStart(int not_save_time) { sprintf(buff,"Stop log start during %d min",not_save_time); - filePrintf(fl,buff,NULL,STOP_LOGGING_ALARM); + filePrintf(ALARM_FILE,buff,NULL,STOP_LOGGING_ALARM); } /*********************************************************************** @@ -387,7 +394,7 @@ void alLogNotSaveStart(int not_save_time) void alLogNotSaveFinish() { sprintf(buff,"Stop log finish"); - filePrintf(fl,buff,NULL,STOP_LOGGING_ALARM); + filePrintf(ALARM_FILE,buff,NULL,STOP_LOGGING_ALARM); } /*********************************************************************** @@ -399,7 +406,7 @@ save all recordName if someone acknowledges group) void alLog2DBAckChan (char *name) { sprintf(buff,"Ack Channel--- %-28s",name); - filePrintf(fo,buff,NULL,ACK_GROUP); /* update the file */ + filePrintf(OPMOD_FILE,buff,NULL,ACK_GROUP); /* update the file */ } /*********************************************************************** @@ -409,7 +416,7 @@ save all recordName if someone acknowledges group) void alLog2DBMask (char *name) { sprintf(buff,"Group Mask ID --- %-28s",name); - filePrintf(fo,buff,NULL,CHANGE_MASK_GROUP); /* update the file */ + filePrintf(OPMOD_FILE,buff,NULL,CHANGE_MASK_GROUP); /* update the file */ } @@ -434,7 +441,7 @@ Parameters: 1) filePointer ***********************************************************************/ -int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) +static int filePrintf(int fileType,char *buf,time_t *ptime,int typeOfRecord) { int ret=0; int status; @@ -444,10 +451,10 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) char buf_tmp[1024]; time_t timeofday; - if(!fPointer) return (-1); + if(!fileType) return (-1); - if((!masterFlag) && (fPointer==fl)) return (0); - if(_message_broadcast_flag && notsave && (fPointer==fl) ) return (0); + if ((_lock_flag && !masterFlag) && (fileType==ALARM_FILE)) return (0); + if(_message_broadcast_flag && notsave && (fileType==ALARM_FILE) ) return (0); if (ptime == NULL) /* Current time */ { @@ -468,9 +475,10 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) psetup.logFile[strlen(psetup.logFile) - 11] = 0; strncat(psetup.logFile, buf_tmp, strlen(buf_tmp)); - fclose(fl); + if (fl) fclose(fl); fl = fopen(psetup.logFile,"a"); - fclose(fl); + if (fl) fclose(fl); + fl=0; if(_read_only_flag) fl = fopen(psetup.logFile,"r"); else if (_lock_flag) fl = fopen(psetup.logFile,"a"); else fl = fopen(psetup.logFile,"r+"); @@ -478,9 +486,9 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) /* The same with psetup.opModFile: */ psetup.opModFile[strlen(psetup.opModFile) - 11] = 0; strncat(psetup.opModFile, buf_tmp, strlen(buf_tmp)); - fclose(fo); + if (fo) fclose(fo); fo = fopen(psetup.opModFile,"a"); - fclose(fo); + if (fo) fclose(fo); if(_read_only_flag) fo = fopen(psetup.opModFile,"r"); else if (_lock_flag) fo = fopen(psetup.opModFile,"a"); else fo = fopen(psetup.opModFile,"r+"); @@ -507,8 +515,12 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) buf_tmp[20]=0; sprintf(bufSave,"%-20s : %s\n",buf_tmp,buf); } - if (alarmLogFileMaxRecords&&(fPointer==fl)) - { + + /* Write into Alarm log file*/ + + + if (fileType==ALARM_FILE) { + if (alarmLogFileMaxRecords && fl) { if (alarmLogFileOffsetBytes != ftell(fl)) fseek(fl,alarmLogFileOffsetBytes,SEEK_SET); if (alarmLogFileOffsetBytes >= alarmLogFileStringLength*alarmLogFileMaxRecords) { @@ -516,30 +528,36 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) status=truncateFile(psetup.logFile,alarmLogFileOffsetBytes); alarmLogFileOffsetBytes = 0; } - } - - - ret=fprintf(fPointer,"%s",bufSave); - - if (ret<0 && !_read_only_flag) { - fprintf(stderr,"Can't write '%s' to file=%s!!!\n", - bufSave,(fPointer==fl)?"LOGfile":"OpModFile" ); - } - - if (alarmLogFileMaxRecords&&(fPointer==fl)){ - if (!alarmLogFileOffsetBytes) alarmLogFileStringLength=ftell(fl); - alarmLogFileOffsetBytes = ftell(fl); - } + } + if (!fl) ret=0; + else ret=fprintf(fl,"%s",bufSave); + if (ret<0 && !_read_only_flag) { + fprintf(stderr,"Can't write '%s' to file=%s!!!\n", bufSave,"LOGfile"); + errMsg("Error writing '%s' to file=%s!!!\n", bufSave,"LOGfile"); + } + if (alarmLogFileMaxRecords && fl){ + if (!alarmLogFileOffsetBytes) alarmLogFileStringLength=ftell(fl); + alarmLogFileOffsetBytes = ftell(fl); + } + if (fl) fflush(fl); + updateAlarmLog(ALARM_FILE,bufSave); + } - fflush(fPointer); + /* Write into Op Mod log file*/ + else if (fileType==OPMOD_FILE) { + if (!fo) ret=0; + else ret=fprintf(fo,"%s",bufSave); + if (ret<0 && !_read_only_flag) { + errMsg("Error writing '%s' to file=%s!!!\n", bufSave,"OpModFile"); + } + if (fo) fflush(fo); + updateLog(OPMOD_FILE,bufSave); + } + else fprintf(stderr,"\nBad file type for writing\n"); - if(fPointer==fl) updateAlarmLog(ALARM_FILE,bufSave); - else if (fPointer==fo) updateLog (OPMOD_FILE,bufSave); - else fprintf(stderr,"\nBad fPointer for writing\n"); - - if( (_printer_flag) && (fPointer==fl) &&printerMsgQId ) - { + + if( (_printer_flag) && (fileType==ALARM_FILE) &&printerMsgQId ) { sprintf(DBbuff,"%d %d %s %s",ALARM_LOG_DB, typeOfRecord+1,buf_tmp,buff); #ifdef HAVE_SYSV_IPC write2MQ(printerMsgQId, DBbuff); @@ -548,13 +566,13 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) if(_DB_call_flag && DBMsgQId ) { - if (fPointer==fo) /* write into AlarmOp Database */ + if (fileType==OPMOD_FILE) /* write into AlarmOp Database */ { if(typeOfRecord ==0) return(ret); sprintf(DBbuff,"%d %d %s %s %s %s %s %s %s",OP_MOD_DB,typeOfRecord,applicationName, deviceName,userID.loginid,userID.myhostname,userID.displayName,buf_tmp,buff); } - else if (fPointer==fl) /* write into AlarmLOG Database */ + else if (fileType==ALARM_FILE) /* write into AlarmLOG Database */ { if(typeOfRecord ==0) return(ret); sprintf(DBbuff,"%d %d %s %s %s %s %s %s %s", ALARM_LOG_DB, typeOfRecord,applicationName, @@ -562,7 +580,7 @@ int filePrintf(FILE *fPointer,char *buf,time_t *ptime,int typeOfRecord) } else { - fprintf(stderr,"\nBad fPointer for writing\n"); + fprintf(stderr,"\nBad file type for writing\n"); return (ret); } #ifdef HAVE_SYSV_IPC @@ -579,7 +597,7 @@ return (ret); ***********************************************************************/ #ifdef HAVE_SYSV_IPC -int write2MQ(int mq,char *message) +static int write2MQ(int mq,char *message) { char buf[256]; static int lostFlag=0; @@ -645,7 +663,7 @@ int write2MQ(int mq,char *message) } -int write2msgQ(int mq, char *mes) +static int write2msgQ(int mq, char *mes) { if (msgsnd(mq,mes,strlen(mes),IPC_NOWAIT /* 0*/) == -1 ) { diff --git a/alh.c b/alh.c index 375fde1..3863675 100644 --- a/alh.c +++ b/alh.c @@ -23,6 +23,7 @@ #include #include +#include #include "alh.h" #include "epicsVersion.h" @@ -56,13 +57,16 @@ int main(int argc,char *argv[]) int interval=0; /* OS specific initialization */ +#ifdef HCLXMINIT #ifdef WIN32 HCLXmInit(); #endif +#endif #ifdef HP_UX _main(); #endif - + + /* Xt initialize the application */ topLevelShell = XtAppInitialize(&appContext, "Alarm", NULL, 0, &argc, argv, fallbackResources, NULL, 0); diff --git a/alh.h b/alh.h index c0047d6..37feac8 100644 --- a/alh.h +++ b/alh.h @@ -29,7 +29,7 @@ #include "alarm.h" #include "cadef.h" -#if (!defined(WIN32) && !defined(__APPLE__)) +#if !defined(WIN32) #define HAVE_SYSV_IPC #endif @@ -181,9 +181,11 @@ struct setup { char logFile[NAMEDEFAULT_SIZE]; /* alarm log file name */ char opModFile[NAMEDEFAULT_SIZE]; /* opMod log file name */ char saveFile[NAMEDEFAULT_SIZE]; /* save config file name */ - Boolean silenceForever; /* 1 - beepoff forever is true */ - short silenceOneHour; /* 1 - beepoff one hour is true */ - short silenceCurrent; /* 1 - current beep on 0 - off */ + char soundFile[NAMEDEFAULT_SIZE]; /* sound wav file name */ + char lockFileBase[NAMEDEFAULT_SIZE]; /* lock files basename */ + short silenceForever; /* 1 - beepoff forever is true */ + short silenceSelectedMinutes; /* 1 - beepoff selected minutes is true */ + short silenceCurrent; /* 1 - current beep on 0 - off */ short beepSevr; /* 1,2,3,4,5 */ short highestSevr; /* system highest sevr */ short highestUnackSevr; /* system highest unack sevr */ diff --git a/alh.notes b/alh.notes index 369292b..39325eb 100644 --- a/alh.notes +++ b/alh.notes @@ -181,7 +181,7 @@ Thu Mar 11 10:12:06 CST 1999 create/modify alarmLog and alarmOpMod files. -S Passive Mode --- means that operator can't acknowledge alarms and can't save alarmLog and alarmOpMod files. - -T AlarmLogDated --- 1) alarmLog and OpMod files will have "date" extensions + -T AlarmLogDated --- 1) alarmLog and OpMod files will have "date" extension like YYYY-MM-DD, and automatical switching this files in midnight. @@ -200,16 +200,17 @@ Thu Mar 11 10:12:06 CST 1999 and modificate Makefile.Unix. -L locking --- allow multiple work with the same config files, - only one process is real master and write to alhLog - other is slave and they wait until master will not killed + only one process is real master and write to alhLog + other is slave and they wait until master will not + killed - -0 Database(Oracle) --- simultaneously runtime add Alarm to Database. - it works asynchronous, so we add additional task "alh_DB" + -0 Database(Oracle) --- simultaneously runtime add Alarm to Database. It + works asynchronous, so we add additional task "alh_DB" - -B - message broadcasting -- allow send messages between operators work with the - same config file. Most important case: "REBOOT MESSAGE": - allow don't save alarm during reboot time. - (NOT IMPLEMENTED YET ;) ) + -B - message broadcasting -- allow send messages between operators work with + same config file. Most important case: "REBOOT + MESSAGE": allow don't save alarm during reboot + time. (NOT IMPLEMENTED YET ;) ) Mon Mar 15 08:57:01 CST 1999 ANSI c changes to eliminate warning messages on Linux build. @@ -413,7 +414,7 @@ Fri Feb 28 16:38:19 CST 2003 ALH_1_2_11Beta4 Mon Mar 3 09:24:38 CST 2003 ALH_1_2_11Beta5 Moved channel beepSevr modified indicators to preceed possible return. - Added code for display of highest existing beepSevr in sub groups and channels. + Added code for display of highest existing beepSevr in sub groups and channels Modified alarm log file output. Now calculate alarmLogFileStringLength. Changed fopen of alarm log file from r+ to w+(truncate or create). Modified forcePV opMod log messages text. @@ -464,9 +465,9 @@ Tue Apr 5 10:06:27 CDT 2005 Tue Jun 21 13:23:04 CDT 2005 ALH_1_2_20 Silence One Hour: - Set color of newly created row widgets to color of parent widget. - Change color of ALL widget children except ack button, sevr indicator, - and name push button. + Set color of newly created row widgets to color of parent widget. + Change color of ALL widget children except ack button, sevr indicator, + and name push button. Write errMsg text to opMod log file when errors occur. Remove extra carriage returns in opMod log file. Remove group and channel data from opMod log message if they do not exist. @@ -584,7 +585,87 @@ Fri Jul 9 15:14:24 CDT 2010 ALH_1_2_26 Portablility changes. Bug fix: set current value to -999 to recalculate and test the force pv expression after user changes are Applied from the ForcePV dialog box. - Core dump bug fix: Test for existance before trying to modify runtime + Core dump bug fix: Test for existance before trying to modify runtime window string. Alh may be started with main window only (-mainwindow). Removed references to Alarm Configuration Tool in ALH Users Manual. +Fri Feb 25 14:23:01 CST 2011 ALH_1_2_27 + Use alBeep instead of calling XBell directly. Changed call to XBell + to call to XkbBell. Portability changes. alLog.c: Added static qualifier + to local routines. Remove extra carrige return in alarm log output. + Check for _lock_flag also when checking masterFlag. + +Tue Jul 26 13:56:13 CDT 2011 + Changed code to allow up to 99 chars in group, channel, and pv names. + Modified Current Alarm Histroy Window to use 7x14 fixed font and to + truncate long channel names to 31 characters. Fixed formating bug in + error messagelogs. Modified main windows and popup Action dialogs to + allow long group/channel names and pv names. + +Tue May 22 16:29:19 CDT 2012 ALH_1_2_28 + Added following changes and command line options by Andreas Luedeke + Changed silenced bg color from lightpink to blue + Add file name to config file open error message. + -p file use wave file for sound instead of alarm beep (OS dependent) + -maskcolor Print mask colored when channel/group contains silencing flag + makes it easier to find all canceled/disabled/noAck channels. + -Lfile dir lockfile directory name for lock files [configdir] + +Thu Jun 21 15:26:50 CDT 2012 ALH_1_2_29 + Changed silenced and noack bg color from blue to lightpink. + Modified popup dialogs for WIN32 to allow use with Xming X server. + +Wed Aug 29 16:32:14 CDT 2012 ALH_1_2_30 + Increased size of group and channel config file input fields. Portability + changes. Bug fix in initialization of psetup. Change darwin default to + HAVE_SYSV_IPC. + +Thu Nov 29 15:13:46 CST 2012 ALH_1_2_31 + Added code to browser.c (from ) and Makefile to use + xdg-open on Linux systems to open an url from alh if the compiler macro + USE_XDGOPEN was defined during the build. + Fixed bugs in AlarmLogDated (-T option) code. + +Mon Apr 22 11:05:07 CDT 2012 + Modified text in 2 error messages. Changed alarm bell function from Xbell + to XkbBell. Used more modern tools to open default browser. Changed + silenced background color back to blue. + +Tue Apr 23 10:57:01 CDT 2013 + SilenceOneHour feature changed: Added setup/select_silence_interval menu + item with interval selections 5, 10, 15, 30, 60 minutes. SilenceOneHour + button text now shows selected interval (default is 1 hour). Pressing + silence button on message window will silence beeps for selected time + interval. Changing interval selection will terminate an existing silence + interval. + +Wed Apr 24 16:11:47 CDT 2013 + Added two more 'ALARMCOUNTFILTER counts seconds' filters. If counts is + zero, counts is not used in determining alarm/no-alarm state. Seconds only + are used for a channel going in and out of alarm. If counts is -1, seconds + only are used for channel going from no-alarm to alarm state. Change in + channel from alarm to no-alarm state is not filtered. + +Thu Apr 25 10:22:57 CDT 2013 + Changed log file handling on alh startup. Now when error opening alarmLog or + opModLog file, an error message popup will be displayed and alh will continue + without the file. The file can be opened/created after startup via setup menu. + +Tue May 14 11:19:07 CDT 2013 ALH_1_2_32 + Minor text changes. Updated User's Guide text and images. + +Mon May 20 13:49:51 CDT 2013 ALH_1_2_33 + Fixed code for the -maskcolor command line option. Accidental commit on May 14 + broke the -maskcolor code. + +Thu Jul 17 14:10:37 CDT 2014 ALH_1_2_34 + Changed way beeping option -p works. Used fork() and execlp() to get play + process to run in the background. Ignore SIGCHLD signals so alh doesn't have to + wait for child processes to finish. + +Mon Aug 25 14:09:19 CDT 2014 ALH_1_2_35 + Changed beeping option with -p again. Used system() with '&' at command + end. Created a "test beep" setup menu item to test the beeping sound. + An error message is displayed if the command line sound file cannot be + opened for read access. Changed default silence interval to .5 hour. + diff --git a/alh_DB.c b/alh_DB.c index 057084c..e72aa65 100644 --- a/alh_DB.c +++ b/alh_DB.c @@ -81,7 +81,6 @@ int DBMsgQId; int DBMsgQKey; int port; int bytes=250; -int socket; if (argc != 4) { fprintf(stderr,"usage:%s TCPName TCPport Key\n",argv[0]); @@ -99,10 +98,10 @@ int socket; fprintf(stderr,"msgQ with key=%d is OK\n",DBMsgQKey); if (msgctl(DBMsgQId,IPC_STAT,&infoBuf) != 1) { - fprintf(stderr,"owner = %d.%d, perms = %04o, max bytes = %d\n", + fprintf(stderr,"owner = %d.%d, perms = %04o, max bytes = %ld\n", infoBuf.msg_perm.uid,infoBuf.msg_perm.gid, infoBuf.msg_perm.mode,infoBuf.msg_qbytes); - fprintf(stderr,"%d msgs = %d bytes on queue\n", + fprintf(stderr,"%ld msgs = %ld bytes on queue\n", infoBuf.msg_qnum, infoBuf.msg_cbytes); } else {perror("msgctl()"); exit(1);} @@ -178,8 +177,6 @@ xdr_DBSend(xdrs, objp) DBSend *objp; { - register long *buf; - if (!xdr_string(xdrs, &objp->msg, ~0)) return (FALSE); return (TRUE); diff --git a/awAlh.c b/awAlh.c index 4ac8f1d..a06654a 100644 --- a/awAlh.c +++ b/awAlh.c @@ -118,22 +118,27 @@ void awUpdateRowWidgets(line) Update line widgets #define MENU_SETUP_FILTER_NONE 10503 #define MENU_SETUP_FILTER_ACTIVE 10504 #define MENU_SETUP_FILTER_UNACK 10505 -#define MENU_SETUP_SILENCE_FOREVER 10506 -#define MENU_SETUP_ALARMLOG 10507 -#define MENU_SETUP_OPMOD 10508 - -#define MENU_ACTION_BEEP_MINOR 10500 -#define MENU_ACTION_BEEP_MAJOR 10501 -#define MENU_ACTION_BEEP_INVALID 10502 +#define MENU_SETUP_SILENCE_INTERVAL_5 10506 +#define MENU_SETUP_SILENCE_INTERVAL_10 10507 +#define MENU_SETUP_SILENCE_INTERVAL_15 10509 +#define MENU_SETUP_SILENCE_INTERVAL_30 10510 +#define MENU_SETUP_SILENCE_INTERVAL_60 10511 +#define MENU_SETUP_SILENCE_FOREVER 10512 +#define MENU_SETUP_ALARMLOG 10513 +#define MENU_SETUP_OPMOD 10514 +#define MENU_SETUP_TESTBEEPSOUND 10515 #define MENU_HELP_HELP 10900 #define MENU_HELP_ABOUT 10906 /* external variables */ +extern Display *display; +extern Pixel silenced_bg_pixel; extern char alhVersionString[100]; extern char *bg_char[]; extern Pixel bg_pixel[]; extern Pixel channel_bg_pixel; +extern Pixel noack_bg_pixel; extern struct setup psetup; extern Widget versionPopup; extern int _message_broadcast_flag; /* messages sending flag. Albert1*/ @@ -146,6 +151,7 @@ extern int max_not_save_time; extern int amIsender; extern int DEBUG; extern int _main_window_flag; +extern int _mask_color_flag; char FS_filename[128]; /* Filename for FSBox. Albert*/ struct UserInfo { @@ -395,21 +401,21 @@ static Widget mkDragIcon ( unsigned long gcValueMask; char tmpStr[131+1], *str; - Display *display = XtDisplay(w); - int screenNum = DefaultScreen(display); + Display *disp = XtDisplay(w); + int screenNum = DefaultScreen(disp); Pixmap sourcePixmap = (Pixmap)NULL; if ( !g_ddFixedFont_created ) { g_ddFixedFont_created = 1; - g_ddFixedFont = XLoadQueryFont( display, "fixed" ); + g_ddFixedFont = XLoadQueryFont( disp, "fixed" ); } #define X_SHIFT 8 #define MARGIN 2 - bg = BlackPixel(display,screenNum); - fg = WhitePixel(display,screenNum); + bg = BlackPixel(disp,screenNum); + fg = WhitePixel(disp,screenNum); fontHeight = g_ddFixedFont->ascent + g_ddFixedFont->descent; @@ -425,14 +431,14 @@ static Widget mkDragIcon ( maxWidth = X_SHIFT + ( textWidth + MARGIN ); maxHeight = fontHeight + 2 * MARGIN; - sourcePixmap = XCreatePixmap(display, - RootWindow(display, screenNum), + sourcePixmap = XCreatePixmap(disp, + RootWindow(disp, screenNum), maxWidth,maxHeight, - DefaultDepth(display,screenNum) ); + DefaultDepth(disp,screenNum) ); if ( !g_ddgc_created ) { g_ddgc_created = 1; - g_ddgc = XCreateGC( display, sourcePixmap, 0, NULL ); + g_ddgc = XCreateGC( disp, sourcePixmap, 0, NULL ); } gcValueMask = GCForeground|GCBackground|GCFunction|GCFont; @@ -442,14 +448,14 @@ static Widget mkDragIcon ( gcValues.function = GXcopy; gcValues.font = g_ddFixedFont->fid; - XChangeGC( display, g_ddgc, gcValueMask, &gcValues ); + XChangeGC( disp, g_ddgc, gcValueMask, &gcValues ); - XFillRectangle( display, sourcePixmap, g_ddgc, 0, 0, maxWidth, + XFillRectangle( disp, sourcePixmap, g_ddgc, 0, 0, maxWidth, maxHeight); - XSetForeground( display, g_ddgc, fg ); + XSetForeground( disp, g_ddgc, fg ); - XDrawString( display, sourcePixmap, g_ddgc, + XDrawString( disp, sourcePixmap, g_ddgc, X_SHIFT, g_ddFixedFont->ascent + MARGIN, tmpStr, strlen(tmpStr) ); @@ -457,7 +463,7 @@ static Widget mkDragIcon ( XtSetArg(args[n],XmNpixmap,sourcePixmap); n++; XtSetArg(args[n],XmNwidth,maxWidth); n++; XtSetArg(args[n],XmNheight,maxHeight); n++; - XtSetArg(args[n],XmNdepth,DefaultDepth(display,screenNum)); n++; + XtSetArg(args[n],XmNdepth,DefaultDepth(disp,screenNum)); n++; sourceIcon = XmCreateDragIcon(XtParent(w),"sourceIcon",args,n); return sourceIcon; @@ -658,6 +664,20 @@ static MenuItem action_menuNew[] = { {NULL}, }; + static MenuItem setup_silence_interval_menu[] = { + { "5 minutes", PushButtonGadgetClass, 0, NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_INTERVAL_5, (MenuItem *)NULL, 0 }, + { "10 minutes", PushButtonGadgetClass, 0, NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_INTERVAL_10, (MenuItem *)NULL, 0 }, + { "15 minutes", PushButtonGadgetClass, 0, NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_INTERVAL_15, (MenuItem *)NULL, 0 }, + { "30 minutes", PushButtonGadgetClass, 0, NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_INTERVAL_30, (MenuItem *)NULL, 0 }, + { "1 hour", PushButtonGadgetClass, 0, NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_INTERVAL_60, (MenuItem *)NULL, 0 }, + {NULL}, + }; + static MenuItem setup_filter_menu[] = { { "No filter", PushButtonGadgetClass, 'N', NULL, NULL, alhSetupCallback, (XtPointer)MENU_SETUP_FILTER_NONE, (MenuItem *)NULL, 0 }, @@ -677,12 +697,16 @@ static MenuItem action_menuNew[] = { { "Audio Setup...", ToggleButtonGadgetClass, 'D', NULL, NULL, alhAudioSetupCallback, NULL, (MenuItem *)NULL, 0 }, #endif + { "Select silence interval...",PushButtonGadgetClass, 'S', NULL, NULL, + 0, 0, (MenuItem *)setup_silence_interval_menu, 0 }, { "Silence Forever", ToggleButtonGadgetClass, 'S', NULL, NULL, alhSetupCallback, (XtPointer)MENU_SETUP_SILENCE_FOREVER,(MenuItem *)NULL, 0 }, { "New Alarm Log File Name...", PushButtonGadgetClass, 'L', NULL, NULL, alhSetupCallback, (XtPointer)MENU_SETUP_ALARMLOG, (MenuItem *)NULL, 0 }, { "New Oper. Log File Name...", PushButtonGadgetClass, 'O', NULL, NULL, alhSetupCallback, (XtPointer)MENU_SETUP_OPMOD, (MenuItem *)NULL, 0 }, + { "Test Beep Sound", PushButtonGadgetClass, 'B', NULL, NULL, + alhSetupCallback, (XtPointer)MENU_SETUP_TESTBEEPSOUND,(MenuItem *)NULL, 0 }, {NULL}, }; @@ -1129,16 +1153,14 @@ static void messBroadcast(Widget widget,XtPointer item,XtPointer cbs) /* Albert if(amIsender) { createDialog(area->form_main,XmDIALOG_INFORMATION, - "You send some message before. \n" "\n" - "Please wait a few seconds \n",""); + "You send some message before. \n\n Please wait a few seconds \n",""); return; } if ( lockf(messBroadcastDeskriptor, F_TLOCK, 0L) < 0 ) { if ((errno == EAGAIN || errno == EACCES )) { if(DEBUG) fprintf(stderr,"file is busy;Deskriptor=%d\n",messBroadcastDeskriptor); createDialog(area->form_main,XmDIALOG_INFORMATION, - "Some other operator type a message. \n" "\n" - "Please wait a few seconds \n",""); + "Some other operator type a message. \n\nPlease wait a few seconds\n",""); return; } else { @@ -1149,7 +1171,7 @@ static void messBroadcast(Widget widget,XtPointer item,XtPointer cbs) /* Albert { if(DEBUG) fprintf(stderr,"file is free;Deskriptor=%d\n",messBroadcastDeskriptor); - dialog = XmCreatePromptDialog(area->form_main, "dialog", NULL, 0); + dialog = XmCreatePromptDialog(area->form_main, "ALH MessageEntryDialog", NULL, 0); XtVaSetValues(dialog,XtVaTypedArg, XmNselectionLabelString, XmRString, "Type message (See help for detail):", 40,NULL); @@ -1208,7 +1230,6 @@ int type; return; } - timeID=time(0L); time_tmp=timeID; @@ -1257,10 +1278,9 @@ int type; } fprintf(fp,"%ld\n%s",timeID,buff); - createDialog(ar->form_main,XmDIALOG_MESSAGE,"Broadcast Message: \n""\n""\n",buff); + createDialog(ar->form_main,XmDIALOG_MESSAGE,"Broadcast Message: \n\n\n",buff); fclose(fp); - XtFree(string); amIsender=1; XtAppAddTimeOut(appContext,messBroadcastLockDelay,messBroadcastFileUnlock,NULL); @@ -1328,7 +1348,7 @@ static void alhSetupCallback( Widget widget, XtPointer calldata, XtPointer cbs) { int item=(long)calldata; ALINK *area; - + XmString silence_string; XtVaGetValues(widget, XmNuserData, &area, NULL); @@ -1367,6 +1387,66 @@ static void alhSetupCallback( Widget widget, XtPointer calldata, XtPointer cbs) changeBeepSeverityText(area); break; + case MENU_SETUP_SILENCE_INTERVAL_5: + + if (area->silenceMinutes != 5) { + area->silenceMinutes=5; + silenceSelectedMinutesReset(area); + } + silence_string = XmStringCreateLocalized ("Silence 5 minutes"); + XtVaSetValues(area->silenceSelectedMinutes, XmNlabelString, silence_string, NULL); + XmStringFree (silence_string); + alLogOpModMessage(0,0,"Silence interval set to 5 minutes"); + break; + + case MENU_SETUP_SILENCE_INTERVAL_10: + + if (area->silenceMinutes != 10) { + area->silenceMinutes=10; + silenceSelectedMinutesReset(area); + } + silence_string = XmStringCreateLocalized ("Silence 10 minutes"); + XtVaSetValues(area->silenceSelectedMinutes, XmNlabelString, silence_string, NULL); + XmStringFree (silence_string); + alLogOpModMessage(0,0,"Silence interval set to 10 minutes"); + break; + + case MENU_SETUP_SILENCE_INTERVAL_15: + + if (area->silenceMinutes != 15) { + area->silenceMinutes=15; + silenceSelectedMinutesReset(area); + } + silence_string = XmStringCreateLocalized ("Silence 15 minutes"); + XtVaSetValues(area->silenceSelectedMinutes, XmNlabelString, silence_string, NULL); + XmStringFree (silence_string); + alLogOpModMessage(0,0,"Silence interval set to 15 minutes"); + break; + + case MENU_SETUP_SILENCE_INTERVAL_30: + + if (area->silenceMinutes != 30) { + area->silenceMinutes=30; + silenceSelectedMinutesReset(area); + } + silence_string = XmStringCreateLocalized ("Silence 30 minutes"); + XtVaSetValues(area->silenceSelectedMinutes, XmNlabelString, silence_string, NULL); + XmStringFree (silence_string); + alLogOpModMessage(0,0,"Silence interval set to 30 minutes"); + break; + + case MENU_SETUP_SILENCE_INTERVAL_60: + + if (area->silenceMinutes != 60) { + area->silenceMinutes=60; + silenceSelectedMinutesReset(area); + } + silence_string = XmStringCreateLocalized ("Silence 1 hour"); + XtVaSetValues(area->silenceSelectedMinutes, XmNlabelString, silence_string, NULL); + XmStringFree (silence_string); + alLogOpModMessage(0,0,"Silence interval set to 1 hour"); + break; + case MENU_SETUP_SILENCE_FOREVER: silenceForeverChangeState(area); @@ -1392,6 +1472,11 @@ static void alhSetupCallback( Widget widget, XtPointer calldata, XtPointer cbs) "Operator Modification File", OPMOD_PATTERN,psetup.logDir); break; + case MENU_SETUP_TESTBEEPSOUND: + + /* Test beep sound */ + alBeep(display); + break; } } @@ -1445,8 +1530,9 @@ void awRowWidgets(struct anyLine *line,void *area) Position nextX; Dimension width; Widget parent; - Pixel backgroundColor; - + Pixel backgroundColor=1; + Pixel bgMask; + subWindow=line->pwindow; parent = ((struct subWindow *)subWindow)->drawing_area; wline=(WLINE *)line->wline; @@ -1474,7 +1560,8 @@ void awRowWidgets(struct anyLine *line,void *area) if ( glink->pgroupData->treeSym) { str = XmStringCreateSimple(glink->pgroupData->treeSym); wline->treeSym = XtVaCreateManagedWidget("treeSym", - xmLabelGadgetClass, wline->row_widget, + xmLabelWidgetClass, wline->row_widget, + XmNbackground, backgroundColor, XmNlabelString, str, XmNmarginHeight, 0, NULL); @@ -1552,7 +1639,7 @@ void awRowWidgets(struct anyLine *line,void *area) XmNuserData, (XtPointer)area, XmNx, nextX, XmNy, 2, - XmNbackground, backgroundColor, + /* XmNbackground, backgroundColor,*/ (XtPointer)NULL); if (line->linkType == GROUP && sllFirst(&(glink->subGroupList))){ XtManageChild(wline->arrow); @@ -1599,6 +1686,8 @@ void awRowWidgets(struct anyLine *line,void *area) nextX = nextX + width + 3; } + /* A.Luedeke : Added color when mask is silencing: 'C', 'D', 'A' or 'H' */ + if (_mask_color_flag&&(line->mask[1]!='-'||line->mask[2]!='-'||line->mask[3]!='-')) {bgMask=noack_bg_pixel;} else {bgMask=bg_pixel[0];} /* A.L.: added color */ str = XmStringCreateSimple(line->mask); wline->mask = XtVaCreateManagedWidget("mask", xmLabelWidgetClass, wline->row_widget, @@ -1610,6 +1699,11 @@ void awRowWidgets(struct anyLine *line,void *area) XmStringFree(str); XtVaGetValues(wline->mask,XmNwidth,&width,NULL); nextX = nextX + width + 3; +#if XmVersion && XmVersion >= 1002 + XmChangeColor(wline->mask,bgMask); /* A.L.: added color */ +#else + XtVaSetValues(wline->mask,XmNbackground,bgMask,NULL); /* A.L.: added color */ +#endif str = XmStringCreateSimple(line->highestBeepSevrString); wline->highestbeepsevr = XtVaCreateManagedWidget("highestbeepsevr", @@ -1790,6 +1884,8 @@ void awUpdateRowWidgets(struct anyLine *line) XmString str; WLINE *wline; Pixel bg; + Pixel bgMask; + Pixel backgroundColor; XmString strOld; Boolean sensitiveOld; @@ -1852,13 +1948,23 @@ void awUpdateRowWidgets(struct anyLine *line) XtVaGetValues(wline->mask, XmNlabelString, &strOld, + XmNbackground, &backgroundColor, NULL); str = XmStringCreateSimple(line->mask); - if (!XmStringCompare(str,strOld)) + /* A.Luedeke : Added color when mask is silencing: 'C', 'D', 'A' or 'H' */ + + if (_mask_color_flag&&(line->mask[1]!='-'||line->mask[2]!='-'||line->mask[3]!='-')) {bgMask=noack_bg_pixel;} else {bgMask=bg_pixel[0];} /* A.L.: added color */ + if (!XmStringCompare(str,strOld)) { XtVaSetValues(wline->mask, XmNlabelString, str, NULL); +#if XmVersion && XmVersion >= 1002 + XmChangeColor(wline->mask,bgMask); /* A.L.: added color */ +#else + XtVaSetValues(wline->mask,XmNbackground,bgMask,NULL); /* A.L.: added color */ +#endif + } XmStringFree(str); XmStringFree(strOld); diff --git a/ax.h b/ax.h index e56e85a..7341a98 100644 --- a/ax.h +++ b/ax.h @@ -70,7 +70,9 @@ void createRuntimeWindow( ALINK *area); void silenceCurrentReset(void *area); void silenceCurrent_callback( Widget w, ALINK* area, XmAnyCallbackStruct *call_data); void silenceForeverChangeState( ALINK *area); -void silenceOneHour_callback( Widget w, ALINK* area, XmAnyCallbackStruct *call_data); +void silenceSelectedMinutes_callback( Widget w, ALINK* area, XmAnyCallbackStruct *call_data); +void changeTreeColor(Widget widget,Pixel color); +void silenceSelectedMinutesReset(void *area); /******************************************************************** diff --git a/axArea.c b/axArea.c index 249ff18..42b9555 100644 --- a/axArea.c +++ b/axArea.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -47,9 +48,9 @@ #include "ax.h" Pixmap ALH_pixmap; -char *silenceString[] = {"Off","On"}; -const char *executionStateString[] = {"Active","Passive"}; -char *disabledForcePVCountString[] = {" ","Disabled forcePVs:"}; +static char *silenceString[] = {"Off","On"}; +static const char *executionStateString[] = {"Active","Passive"}; +static char *disabledForcePVCountString[] = {" ","Disabled forcePVs:"}; /* global variables */ extern int _global_flag; @@ -596,9 +597,9 @@ void createMainWindowWidgets(ALINK *area) NULL); XmStringFree(str); - - /* Create a Silence One Hour Toggle Button in the messageArea */ - area->silenceOneHour = XtVaCreateManagedWidget("SilenceOneHour", + /* Create a Silence Selected Minutes Toggle Button in the messageArea */ + area->silenceMinutes = 30; + area->silenceSelectedMinutes = XtVaCreateManagedWidget("Silence 30 minutes", xmToggleButtonGadgetClass, area->messageArea, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, area->scale, @@ -607,10 +608,10 @@ void createMainWindowWidgets(ALINK *area) NULL); /* Create a Silence Current Toggle Button in the messageArea */ - area->silenceCurrent = XtVaCreateManagedWidget("SilenceCurrent", + area->silenceCurrent = XtVaCreateManagedWidget("Silence current", xmToggleButtonGadgetClass, area->messageArea, XmNtopAttachment, XmATTACH_WIDGET, - XmNtopWidget, area->silenceOneHour, + XmNtopWidget, area->silenceSelectedMinutes, XmNrightAttachment, XmATTACH_FORM, XmNuserData, (XtPointer)area, NULL); @@ -667,8 +668,8 @@ void createMainWindowWidgets(ALINK *area) NULL); XmStringFree(str); - XtAddCallback(area->silenceOneHour, XmNvalueChangedCallback, - (XtCallbackProc)silenceOneHour_callback,area); + XtAddCallback(area->silenceSelectedMinutes, XmNvalueChangedCallback, + (XtCallbackProc)silenceSelectedMinutes_callback,area); XtAddCallback(area->silenceCurrent, XmNvalueChangedCallback, (XtCallbackProc)silenceCurrent_callback,area); diff --git a/axArea.h b/axArea.h index f3cab6d..b35b2a4 100644 --- a/axArea.h +++ b/axArea.h @@ -53,7 +53,7 @@ typedef struct areaLink{ Widget label_groupAlarm; Widget label_channelAlarm; Widget label_mask; - Widget silenceOneHour; + Widget silenceSelectedMinutes; Widget silenceCurrent; Widget silenceForever; Widget silenceForeverLabel; @@ -93,9 +93,11 @@ typedef struct areaLink{ int currentAlarmIndex; Widget currentAlarmForm; Widget currentAlarm[10]; - char currentAlarmString[10][128]; + char currentAlarmString[10][228]; int w; int h; + /* ----- Silence minutes info ----- */ + int silenceMinutes; } ALINK; typedef struct _menu_item { diff --git a/axRunW.c b/axRunW.c index f45c9af..a2b60e5 100644 --- a/axRunW.c +++ b/axRunW.c @@ -15,6 +15,7 @@ /* axRunW.c */ #include +#include #include #include @@ -40,7 +41,8 @@ static XtIntervalId blinkTimeoutId = (XtIntervalId)0; static char *bg_color[] = {"lightblue","yellow","red","white","white","grey"}; static char *channel_bg_color = "lightblue"; -static char *silenced_bg_color = "lightpink"; +static char *silenced_bg_color = "blue"; +static char *noack_bg_color = "blue"; /* global variabless */ @@ -49,9 +51,11 @@ extern Display *display; extern struct setup psetup; extern char *programName; extern Pixmap ALH_pixmap; +extern int _mask_color_flag; Pixel bg_pixel[ALH_ALARM_NSEV]; Pixel channel_bg_pixel; Pixel silenced_bg_pixel; +Pixel noack_bg_pixel; const char *bg_char[] = {" ", "Y", "R", "V", "E"," " }; /* forward declarations */ @@ -60,8 +64,7 @@ static void axExitArea_callback(Widget w,ALINK *area,XmAnyCallbackStruct *call_d static void blinking(XtPointer pointer, XtIntervalId *id); static void createMainWindow_callback(Widget w,ALINK *area,XmAnyCallbackStruct *call_data); static void icon_update(Widget blinkButton); -static void silenceOneHourReset(void *area); -static void changeTreeColor(Widget widget,Pixel color); + char *Strncat( char *dest, const char *src, @@ -174,11 +177,11 @@ void createRuntimeWindow(ALINK *area) XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, - XmNactivateCallback, (XtPointer)NULL, + XmNactivateCallback, (XtPointer)NULL, XmNuserData, (XtPointer)area, XmNlabelString, str, XmNfontList, fontList, - (XtPointer)NULL); + NULL); XmStringFree(str); XtAddCallback(area->blinkButton,XmNactivateCallback, @@ -206,7 +209,7 @@ void createRuntimeWindow(ALINK *area) /* reinitialize silence beep */ silenceCurrentReset(area); - silenceOneHourReset(area); + silenceSelectedMinutesReset(area); icon_update(area->blinkButton); @@ -348,7 +351,7 @@ static void blinking(XtPointer pointer, XtIntervalId *id) XmChangeColor(blinkButton,blinkPixel); } if (!psetup.silenceForever && - !psetup.silenceOneHour && + !psetup.silenceSelectedMinutes && !psetup.silenceCurrent && (psetup.highestUnackBeepSevr >= psetup.beepSevr)) { @@ -386,13 +389,13 @@ void silenceCurrentReset(void *area) } /*********************************************** - reset silenceOneHourReset + reset silenceSelectedMinutesReset ************************************************/ -static void silenceOneHourReset(void *area) +void silenceSelectedMinutesReset(void *area) { - if (psetup.silenceOneHour) { - XmToggleButtonGadgetSetState(((ALINK*)area)->silenceOneHour,FALSE,FALSE); - silenceOneHour_callback(((ALINK*)area)->silenceOneHour,area,NULL); + if (psetup.silenceSelectedMinutes) { + XmToggleButtonGadgetSetState(((ALINK*)area)->silenceSelectedMinutes,FALSE,FALSE); + silenceSelectedMinutes_callback(((ALINK*)area)->silenceSelectedMinutes,area,NULL); } } @@ -410,42 +413,46 @@ XmAnyCallbackStruct *call_data) } /*************************************************** - silenceOneHour button toggle callback + silenceSelectedMinutes button toggle callback ****************************************************/ -void silenceOneHour_callback(Widget w,ALINK* area, +void silenceSelectedMinutes_callback(Widget w,ALINK* area, XmAnyCallbackStruct *call_data) { static XtIntervalId intervalId = 0; - int seconds = 3600; + int seconds = 60*area->silenceMinutes; - psetup.silenceOneHour = psetup.silenceOneHour?FALSE:TRUE; - if (psetup.silenceOneHour) { + psetup.silenceSelectedMinutes = psetup.silenceSelectedMinutes?FALSE:TRUE; + if (psetup.silenceSelectedMinutes) { intervalId = XtAppAddTimeOut(appContext, (unsigned long)(1000*seconds), - (XtTimerCallbackProc)silenceOneHourReset, + (XtTimerCallbackProc)silenceSelectedMinutesReset, (XtPointer)area); XmChangeColor(area->messageArea,silenced_bg_pixel); - changeTreeColor(area->treeWindowForm,silenced_bg_pixel); - changeTreeColor(area->groupWindowForm,silenced_bg_pixel); + if (!_mask_color_flag) { + changeTreeColor(area->treeWindowForm,silenced_bg_pixel); + changeTreeColor(area->groupWindowForm,silenced_bg_pixel); + } changeTreeColor(area->scale,silenced_bg_pixel); - alLogOpModMessage(0,0,"Silence One Hour set to TRUE"); + alLogOpModMessage(0,0,"Silence Selected Minutes set to TRUE"); } else { if (intervalId) { XtRemoveTimeOut(intervalId); intervalId = 0; } XmChangeColor(area->messageArea,bg_pixel[0]); - changeTreeColor(area->treeWindowForm,bg_pixel[0]); - changeTreeColor(area->groupWindowForm,bg_pixel[0]); + if (!_mask_color_flag) { + changeTreeColor(area->treeWindowForm,bg_pixel[0]); + changeTreeColor(area->groupWindowForm,bg_pixel[0]); + } changeTreeColor(area->scale,bg_pixel[0]); - alLogOpModMessage(0,0,"Silence One Hour set to FALSE"); + alLogOpModMessage(0,0,"Silence Selected Minutes set to FALSE"); } } /*************************************************** changeTreeColor ****************************************************/ -static void changeTreeColor(Widget widget,Pixel color) +void changeTreeColor(Widget widget,Pixel color) { int i; Widget *children; @@ -527,6 +534,7 @@ void pixelData(Widget iconBoard) channel_bg_pixel = COLOR(dsply,channel_bg_color); silenced_bg_pixel = COLOR(dsply,silenced_bg_color); + noack_bg_pixel = COLOR(dsply,noack_bg_color); /* retrieve the background color of the iconBoard */ XtVaGetValues(iconBoard, XmNbackground, &bg_pixel[0], NULL); diff --git a/browser.c b/browser.c index 0e7f815..a69fc59 100644 --- a/browser.c +++ b/browser.c @@ -15,7 +15,7 @@ /* browser.c */ /************************DESCRIPTION*********************************** - Invokes Netscape browser + Invokes default browser Original Author : Kenneth Evans, Jr. **********************************************************************/ @@ -33,28 +33,18 @@ #include #include #include -#include -#include #include #include #include #include -#include - -#ifndef NETSCAPEPATH -#define NETSCAPEPATH "netscape" -#endif /* Function prototypes */ extern int kill(pid_t, int); /* May not be defined for strict ANSI */ int callBrowser(char *url); -static Window checkNetscapeWindow(Window w); static int execute(char *s); -static Window findNetscapeWindow(void); -static int ignoreXError(Display *display, XErrorEvent *xev); /* Global variables */ extern Display *display; @@ -65,12 +55,9 @@ int callBrowser(char *url) /* url is the URL that the browser is to display */ /* or "quit" to terminate the browser */ { - int (*oldhandler)(Display *, XErrorEvent *); - static Window netscapew=(Window)0; static pid_t pid=0; int status; char command[BUFSIZ]; - char *envstring; /* Handle quit */ if(!strcmp(url,"quit")) { @@ -80,48 +67,19 @@ int callBrowser(char *url) } return 3; } - /* Set handler to ignore possible BadWindow error */ - /* (Would prefer a routine that tells if the window is defined) */ - oldhandler=XSetErrorHandler(ignoreXError); - /* Check if the stored window value is valid */ - netscapew=checkNetscapeWindow(netscapew); - /* Reset error handler */ - XSetErrorHandler(oldhandler); - /* If stored window is not valid, look for a valid one */ - if(!netscapew) { - netscapew=findNetscapeWindow(); - /* If no window found, exec Netscape */ - if(!netscapew) { - envstring=getenv("BROWSER"); - if(!envstring) envstring=getenv("NETSCAPEPATH"); - if(!envstring) { - sprintf(command,"%s -install '%s' &",NETSCAPEPATH,url); - } - else { - sprintf(command,"%s -install '%s' &",envstring,url); - } -#if DEBUG - printf("execute(before): cmd=%s\n",command); -#endif - status=execute(command); -#if DEBUG - printf("execute(after): cmd=%s status=%d\n",command,status); -#endif - return 1; - } - } - /* Netscape window is valid, send url via -remote */ - /* (Use -id for speed) */ - envstring=getenv("BROWSER"); - if(!envstring) envstring=getenv("NETSCAPEPATH"); - if(!envstring) { - sprintf(command,"%s -id 0x%x -remote 'openURL(%s)' &", - NETSCAPEPATH,(unsigned int)netscapew,url); - } - else { - sprintf(command,"%s -id 0x%x -remote 'openURL(%s)' &", - envstring,(unsigned int)netscapew,url); - } +#if defined __linux__ /* defined by gnu compiler preprocessor */ + sprintf(command,"xdg-open \"%s\" &",url); +#elif defined SOLARIS /* defined in EPICS base configure files */ + sprintf(command,"sdtwebclient \"%s\" &",url); +#elif defined darwin /* defined in EPICS base configure files */ + sprintf(command,"open \"%s\" &",url); +#elif defined __CYGWIN32__ /* defined by gnu compiler preprocessor */ + sprintf(command,"cygstart \"%s\" &",url); +#elif defined USE_HTMLVIEW + sprintf(command,"htmlview \"%s\" &",url); +#else + return 1; +#endif #if DEBUG printf("execute(before): cmd=%s\n",command); #endif @@ -131,35 +89,7 @@ int callBrowser(char *url) #endif return 2; } -/**************************** checkNetscapeWindow ************************/ -static Window checkNetscapeWindow(Window w) -/* Checks if this window is the Netscape window and returns the window - * if it is or 0 otherwise */ -{ - Window wfound=(Window)0; - static Atom typeatom,versionatom=(Atom)0; - unsigned long nitems,bytesafter; - int format,status; - unsigned char *version=NULL; - /* If window is NULL, return it */ - if(!w) return w; - /* Get the atom for the version property (once) */ - if(!versionatom) versionatom=XInternAtom(display,"_MOZILLA_VERSION",False); - /* Get the version property for this window if it exists */ - status=XGetWindowProperty(display,w,versionatom,0, - (65536/sizeof(long)),False,AnyPropertyType, - &typeatom,&format,&nitems,&bytesafter,&version); - /* If the version property exists, it is the Netscape window */ - if(version && status == Success) wfound=w; -#if DEBUG - printf("XGetWindowProperty: status=%d version=%d w=%x wfound=%x\n", - status,version,w,wfound); -#endif - /* Free space and return */ - if(version) XFree((void *)version); - return wfound; -} /**************************** execute ************************************/ static int execute(char *s) /* From O'Reilly, Vol. 1, p. 438 */ @@ -182,47 +112,13 @@ static int execute(char *s) signal(SIGQUIT,qstat); return(status); } -/**************************** findNetscapeWindow *************************/ -static Window findNetscapeWindow(void) -{ - int screen=DefaultScreen(display); - Window rootwindow=RootWindow(display,screen); - Window *children,dummy,w,wfound=(Window)0; - unsigned int nchildren; - int i; - - /* Get the root window tree */ - if(!XQueryTree(display,rootwindow,&dummy,&dummy,&children,&nchildren)) - return (Window)0; - /* Look at the children from the top of the stacking order */ - for(i=nchildren-1; i >= 0; i--) { - w=XmuClientWindow(display,children[i]); - /* Check if this is the Netscape window */ -#if DEBUG - printf("Child %d ",i); -#endif - wfound=checkNetscapeWindow(w); - if(wfound) break; - } - if(children) XFree((void *)children); - return wfound; -} -/**************************** ignoreXError *******************************/ -static int ignoreXError(Display *display, XErrorEvent *xev) -{ -#if DEBUG - printf("In ignoreXError\n"); -#endif - return 0; -} -#else /*ifndef WIN32 */ +#else /*************************************************************************/ /*************************************************************************/ /* WIN32 Version */ /*************************************************************************/ /*************************************************************************/ - #include #include #include @@ -256,47 +152,13 @@ int callBrowser(char *url) ComSpec = getenv("ComSpec"); } if (!ComSpec) return(0); /* Abort with no message like the UNIX version*/ - /* Spawn the process that handles a url */ -#if 0 - /* Works, command window that goes away */ - sprintf(command,"start \"%s\"",url); - status = _spawnl(_P_WAIT, ComSpec, ComSpec, "/C", command, NULL); - - /* Works, command window that goes away */ - sprintf(command,"start \"%s\"",url); - status = _spawnl(_P_DETACH, ComSpec, ComSpec, "/C", command, NULL); - - /* Works, command window that goes away */ - sprintf(command,"\"%s\"",url); - status = _spawnl(_P_NOWAIT, "c:\\windows\\command\\start.exe", - "c:\\windows\\command\\start.exe", command, NULL); - - /* Works, command window that goes away */ - sprintf(command,"\"%s\"",url); - status = _spawnl(_P_WAIT, ComSpec, "start", command, NULL); - - /* Works, command window that goes away */ - sprintf(command,"start \"%s\"",url); - status = _spawnl(_P_NOWAIT, ComSpec, ComSpec, "/C", command, NULL); - - /* Doesn't work on 95 (No such file or directory), works on NT */ - sprintf(command,"start \"%s\"",url); - status = _spawnl(_P_NOWAIT, ComSpec, "/C", command, NULL); - - /* Works on 95, not NT, no command window - * No start.exe for NT */ - sprintf(command,"\"%s\"",url); - status = _spawnlp(_P_DETACH, "start", "start", command, NULL); - /* Doesn't work on 95 */ - sprintf(command,"\"start %s\"",url); - status = _spawnl(_P_DETACH, ComSpec, ComSpec, "/C", command, NULL); -#else + /* Spawn the process that handles a url */ /* This seems to work on 95 and NT, with a command box on 95 * It may have trouble if the URL has spaces */ sprintf(command,"start %s",url); status = _spawnl(_P_DETACH, ComSpec, ComSpec, "/C", command, NULL); -#endif + if(status == -1) { char *errstring=strerror(errno); @@ -308,67 +170,7 @@ int callBrowser(char *url) } return(1); } -#endif /* #ifndef WIN32 */ - -#if 0 -/*************************************************************************/ -/*************************************************************************/ -/* Mosaic Version */ -/*************************************************************************/ -/*************************************************************************/ - -#ifndef MOSAICPATH -/* #define MOSAICPATH "/usr/bin/X11/mosaic" */ -/* #define MOSAICPATH "/opt/local/bin/mosaic" */ -#define MOSAICPATH "mosaic" #endif -/**************************** callBrowser ********************************/ -int callBrowser(char *url) -/* Returns non-zero on success, 0 on failure */ -/* url is the URL that Mosaic is to display */ -/* or "quit" to terminate Mosaic */ -{ - static pid_t pid=0; - char filename[32]; - FILE *file; - char path[BUFSIZ]; - char *envstring; - signal(SIGCHLD,SIG_IGN); - /* Handle quit */ - if(!strcmp(url,"quit")) { - if (pid) { - sprintf(filename,"/tmp/Mosaic.%d",pid); - unlink(filename); - kill(pid,SIGTERM); - pid=0; - } - return 3; - } - /* If Mosaic is not up, exec it */ - if ((!pid) || kill(pid,0)) { - if (!(pid=fork())) { - envstring=getenv("MOSAICPATH"); - if(!envstring) { - sprintf(path,"%s",MOSAICPATH); - } - else { - sprintf(path,"%s",envstring); - } - execlp(path,path,url,(char *)0); - perror(path); - _exit(127); - } - return 1; - } - /* Mosaic is up, send message through file */ - sprintf(filename,"/tmp/Mosaic.%d",pid); - if (!(file=fopen(filename,"w"))) return 0; - fprintf(file,"goto\n%s\n",url); - fclose(file); - kill(pid,SIGUSR1); - return 2; -} -#endif diff --git a/current.c b/current.c index c58fec3..06a2bbd 100644 --- a/current.c +++ b/current.c @@ -55,6 +55,7 @@ void currentAlarmHistoryWindow(ALINK *area,Widget menuButton) Atom WM_DELETE_WINDOW; int i; char *app_name; + XmString xstr; if (!area->currentAlarmForm) { app_name = (char*) calloc(1,strlen(programName)+6); @@ -103,21 +104,24 @@ void currentAlarmHistoryWindow(ALINK *area,Widget menuButton) previous = button; /* add title line */ - title = XtVaCreateManagedWidget( - " TIME_STAMP PROCESS_VARIABLE_NAME " - "STATUS SEVERITY VALUE ", + xstr = XmStringCreateSimple( + " TIME_STAMP PROCESS_VARIABLE_NAME " + "STATUS SEVERITY VALUE "); + title = XtVaCreateManagedWidget("CurrentTitle", xmLabelGadgetClass, area->currentAlarmForm, + XmNlabelString, xstr, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 10, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, button, XmNrightAttachment, XmATTACH_FORM, NULL); + XmStringFree(xstr); /* create 10 label widgets */ for ( i=0;i<10;i++){ - area->currentAlarm[i] = XtVaCreateManagedWidget( "-----", + area->currentAlarm[i] = XtVaCreateManagedWidget( "CurrentAlarm", xmLabelGadgetClass, area->currentAlarmForm, XmNmarginHeight, 1, XmNalignment, XmALIGNMENT_BEGINNING, @@ -186,7 +190,7 @@ char value[],int stat,int sevr) if ( !area ) return; n = area->currentAlarmIndex; sprintf(area->currentAlarmString[n], - " %-24s : %-28s %-10s %-10s %s", + " %-24s %-31.31s %-10.10s %-10.10s %s", ctime(ptimeofday), name, alhAlarmStatusString[stat], @@ -194,6 +198,7 @@ char value[],int stat,int sevr) value); n = (n+1)%10; area->currentAlarmIndex = n; + } /****************************************************************** diff --git a/dialog.c b/dialog.c index b0d622b..98051dd 100644 --- a/dialog.c +++ b/dialog.c @@ -181,7 +181,10 @@ void createDialog(Widget parent,int dialogType,char *message1,char *message2) string2 = XmStringConcat(str3,str); XtVaSetValues(dialog, +#ifndef WIN32 + /* 6/2012 Xming hangs when dialogType is set */ XmNdialogType, dialogType, +#endif XmNdialogTitle, string2, XmNmessageString, string, (XtPointer)NULL); @@ -201,7 +204,7 @@ void createActionDialog(Widget parent,int dialogType,char *message1, XtCallbackProc okCallback,XtPointer okParm,XtPointer userParm) { static Widget dialog = 0; /* make it static for reuse */ - XmString str,str1,str2,str3; + XmString str,str2; static XtCallbackProc oldOkCallback = 0; static XtPointer oldOkParm = 0; @@ -226,36 +229,36 @@ XtCallbackProc okCallback,XtPointer okParm,XtPointer userParm) switch(dialogType) { case XmDIALOG_WARNING: - str = XmStringCreateSimple("WarningDialog"); + str = XmStringCreateSimple("ALH WarningDialog"); break; case XmDIALOG_ERROR: - str = XmStringCreateSimple("ErrorDialog"); + str = XmStringCreateSimple("ALH ErrorDialog"); break; case XmDIALOG_INFORMATION: - str = XmStringCreateSimple("InformationDialog"); + str = XmStringCreateSimple("ALH InformationDialog"); break; case XmDIALOG_MESSAGE: - str = XmStringCreateSimple("MessageDialog"); + str = XmStringCreateSimple("ALH MessageDialog"); break; case XmDIALOG_QUESTION: - str = XmStringCreateSimple("QuestionDialog"); + str = XmStringCreateSimple("ALH QuestionDialog"); break; case XmDIALOG_WORKING: - str = XmStringCreateSimple("WorkingDialog"); + str = XmStringCreateSimple("ALH WorkingDialog"); break; default: - str = XmStringCreateSimple("InformationDialog"); + str = XmStringCreateSimple("ALH InformationDialog"); break; } - str1 = XmStringCreateLtoR("ALH ",XmFONTLIST_DEFAULT_TAG); - str3 = XmStringConcat(str1,str); - str2=XmStringCreateLtoR(message1,XmSTRING_DEFAULT_CHARSET); XtVaSetValues(dialog, XmNuserData, userParm, +#ifndef WIN32 + /* 6/2012 Xming hangs when dialogType is set */ XmNdialogType, dialogType, - XmNdialogTitle, str3, +#endif + XmNdialogTitle, str, XmNmessageString, str2, (XtPointer)NULL); XmStringFree(str); @@ -326,16 +329,20 @@ void errMsg(const char *fmt, ...) warningboxMessages += 1; XtManageChild(warningbox); } else { - XBell(display,50); - XBell(display,50); - XBell(display,50); + alBeep(display); + alBeep(display); + alBeep(display); cstring=XmStringCreateLtoR(lstring,XmSTRING_DEFAULT_CHARSET); nargs=0; XtSetArg(args[nargs],XmNtitle,"ALH Warning"); nargs++; XtSetArg(args[nargs],XmNmessageString,cstring); nargs++; +#ifndef WIN32 warningbox=XmCreateWarningDialog(topLevelShell,"warningMessage", +#else + warningbox=XmCreateMessageDialog(topLevelShell,"warningMessage", +#endif args,nargs); XmStringFree(cstring); XtDestroyWidget(XmMessageBoxGetChild(warningbox,XmDIALOG_CANCEL_BUTTON)); diff --git a/documentation/ALH.html b/documentation/ALH.html index e5cd718..7fbfb54 100644 --- a/documentation/ALH.html +++ b/documentation/ALH.html @@ -115,7 +115,7 @@

Availability

The alarm handler is a Motif and X11 Window based application written in C language, and it runs on -Unix, Linux, and Windows 98/XP hosts. The Alarm Handler source code is +Unix, Linux, and Windows 98/XP/.../8 hosts. The Alarm Handler source code is available via WWW as an EPICS extension.

Purpose of the Alarm Handler

@@ -137,7 +137,7 @@

Purpose of the Alarm Handler

System Requirements

The Alarm Handler currently requires either -an IBM personal computer with Windows 95/NT and Hummingbird's +an IBM personal computer with Windows 98/XP/.../8 and Hummingbird's Exceed software or a workstation running a Unix type operating system with X Windows and Motif Version 1.2 or above. The Alarm Handler also requires the global alarm acknowledgment in EPICS base Version 3.11 or above.

@@ -306,6 +306,10 @@

Alarm Configuration File

desired alarm configuration file using a file selection window at Alarm Handler start-up, or on the command line.

+

The user can change to a new alarm configuration +file while the Alarm Handler is running by using the File/Open item on the +main window menu bar.

+

Alarm Log File

The Alarm Log output file contains a log of alarm @@ -345,7 +349,7 @@

ALARMHANDLER

variable ALARMHANDLER can be used to point the Alarm Handler to a desired working directory. If ALARMHANDLER is not set, the current working directory is assumed. If the alarm configuration file -resides on a different directory +resides in a different directory (e.g. /home/cs/appl/ah/dev) from the current working directory, under UNIX ALARMHANDLER can be set to point to the desired path by issuing the UNIX c shell command:

@@ -397,7 +401,7 @@

Command Line Syntax

-aCM - Alarm log using CMLOG + Alarm log using CMLOG (if built using CMLOG) -B @@ -445,6 +449,10 @@

Command Line Syntax

-L Use Locking System + + -Lfile lockfile + Basename for .LOCK lock file + -l logdir Directory for log files [.] @@ -457,6 +465,12 @@

Command Line Syntax

-mainwindow Start with Main Window + + -maskcolor + Print mask colored when channel/group contains silencing flag +
(makes it easier to find all canceled/disabled/noAck channels) + + -noerrorpopup Do not display error popup window (errors are logged) @@ -478,6 +492,10 @@

Command Line Syntax

-P key Print to TCP printer + + -p file + Use wave file for sound instead of alarm beep (OS dependent) + -S Passive state (no ca_puts to ACKS and ACKT fields and severity PV) @@ -619,6 +637,13 @@

Locking System

(i.e. actively logging) process dies, another Alarm Handler will seamlessly take over logging. Default is not to use this locking mechanism.

+

Locking File

+ +

The '-L lockfile' option specifies a lock +file directory with file name prefix. A ".LOCK" suffix will be appended. The +default is the configure filename with directory from the -f option or the +current working directory. +

Directory for Log Files

The '-l logdir' @@ -640,6 +665,13 @@

Start with Main Window

useful in conjunction with the `-filter f-opt' option to start Alarm Handlers from operator panels. The default is to start with the Runtime Window.

+

Colored Masks

+ +

The `-maskcolor' option makes the Alarm +display colored masks when the channel/group contains a silencing flag. This +makes it easier to find all the canceled/disabled/noAck channels. +

+

Do not use Popup Boxes for Displaying Errors

The `-noerrorpopup' option tells the Alarm @@ -673,6 +705,13 @@

TCP Printing

asynchronously by adding an additional task "alh_printer". (This option is still under construction and will use pipes in the future)

+

Wave File Sound

+ +

The '-p file' option specifies that alh should +play the specified wave sound file instead of alarm beeping. This option is +available for Linux systems only. +

+

Silent Mode

The '-s' @@ -787,7 +826,7 @@

Runtime Window

Exiting the Alarm Handler

To exit the Alarm Handler, -use the Window Manager Menu on +click on the X in the window title bar or use the Window Manager Menu on the Runtime Window and choose the Close menu item.

Message Area abbreviation codes and status data which appear in the group summary and channel status lines.

-

There are two Silence buttons which toggle beeping on or off. -The Silence Current button turns off current -alarm beeping until a new alarm occurs. The Silence -One Hour button toggles on/off beeping of current and future alarms for one -hour. When pushed in, beeping is turned off, when out, beeping is on. Beeping +

+There are two Silence buttons which toggle beeping on or off. The Silence Current +button turns off current alarm beeping until a new alarm occurs. The Silence Interval +button toggles beeping of current and future alarms off for a specified interval. +When pushed in, beeping is turned off, when out, beeping is toggled on. Beeping occurs only when there are unacknowledged alarms. The main window background -color is changed to pink when Silence One Hour is active.

+color is changed when beeping is turned off. Setup menu items can be used to +change the specified time interval.

Group Summary Line

This display line -summarizer the status of all alarms for the group named in this line and all +summarizes the status of all alarms for the group named in this line and all lower level groups. The group summary display consists of the following items:

Acknowledgment Button

@@ -1204,7 +1244,9 @@

Action Menu Commands

selections which affect the currently selected Alarm Group or Channel. The action selections "Acknowledge Alarm", "Display Guidance", and "Start Related Process" can also be accomplished by clicking -buttons on the tree structure or group contents display.

+buttons on the tree structure or group contents display. The "Send Message" +item is present only when the Message Broadcasting option, "-B", +is present on the command line.

@@ -1249,8 +1291,8 @@

Display Guidance

The guidance text display is a popup window displaying lines of ascii text if text was specified in the alarm configuration file. If a URL address was specified in the -configuration file, Netscape will be invoked and display the text at the -specified URL address.

+configuration file, the default browser will be invoked and display the text +at the specified URL address.

Start Related Process

@@ -1362,9 +1404,11 @@

Message Broadcasting

Message" menu item is selected. The operator can then type in a message that will be sent to other alh processes when OK is pressed. A popup message dialog containing the sent message will appear on other Alarm Handler processes -when they receive the message.

+when they receive the message. The "Send Message" menu item appears on +the Action menu only if the Message Broadcasting option, "-B", is +present on the alh command line.

-

View Menu Commands

Expand One Level

-

The user selects this -menu item to expand a collapsed the currently selected Alarm Group to -graphically display one level of its alarm subgroups on the alarm configuration -tree display.

+

The user selects this menu item to expand the +currently selected collapsed Alarm Group in the tree structure display to +graphically display one level of its alarm subgroups in the tree structure display.

Expand Branch

-

The user can choose this -item to expand the currently selected collapsed Alarm Group in the alarm -configuration tree display to graphically show all levels of its subgroups on -the alarm configuration tree structure display.

+

The user can choose this item to expand the +currently selected Alarm Group in the alarm configuration tree display to +graphically show all levels of its subgroups on the tree structure display.

-

Expend All

+

Expand All

-

The user uses this menu -item to expand all collapsed groups in the configuration tree structure display -to graphically show all the groups and subgroups in the current alarm -configuration.

+

The user uses this menu item to expand or collapse +all groups in the alarm configuration tree structure display to graphically +show all the groups and subgroups on the current alarm configuration tree +structure display.

Collapse Branch

@@ -1515,11 +1557,14 @@

Display Filter

The user is allowed to set an alarm filter to display active alarms only. When the filter is set to Active Alarms Only, only those groups or channels with an outstanding alarm -will be displayed. When the filter is set to Unacknowldged Alarms Only, only those +will be displayed. When the filter is set to Unacknowledged Alarms Only, only those groups or channels with an outstanding unacknowledged alarm will be displayed. When the selection is set to No Filter, all Alarm Groups and Alarm Channels in the current configuration will be available for display.

+

+

ALH Beep Severity

The operator can specify @@ -1534,13 +1579,33 @@

ALH Beep Severity

-

New Alarm Log File

+

Silence Time Interval

+ +

The Silence Time Interval menu item allows the user to +select a silence interval of 5, 10, 15, 30, or 60 minutes. The selected interval +determines the silence interval for the Silence Time Interval button on the Main +Window message area and text for the selected interval appears next to the Silence +Time Interval button. +

+ +

+ +

Silence Forever

+ +

The Silence Forever button toggles On/Off the +beeping of all current and future unacknowledged alarms. Beeping normally +occurs when there are unacknowledged alarms. +

+ +

New Alarm Log File

The alarm log file contains the log of alarm changes of states. The Alarm Handler allows the operator to specify an alarm log file name that differs from the current setting. If it does not exist, it will be automatically created. All new alarm state changes -will be logged to this file.

+will be logged to this file. A file selection dialog window is used to set a +new Alarm Log File name.

New Operation Modification Log File

@@ -1548,7 +1613,8 @@

New Operation Modification Log File

the operator to specify an operation modification log file that differs from the current setting. If it does not exist, it will be automatically created by ALH. All subsequent operation changes will be logged to this new operation -modification file.

+modification file. A file selection dialog window is used to set a new +Operation Modification Log File name.

Help Menu

@@ -1635,7 +1701,7 @@

Input Format

Heartbeat Process Variable

The line starting with $HEARTBEATPV is optional. -It is required only when a user wants a monitored pv to show weather or not +It is required only when a user wants a monitored pv to show whether or not ALH is running. If the $HEARTBEATPV line is present, ALH will do CA puts of the specified value to the specified pv at the specified rate (in seconds). The heartbeatPVName must be an existing PV in the EPICS database and can be @@ -1651,8 +1717,7 @@

Group or Channel

NULL as the parent group name. Group or Channel lines must start with the keyword GROUP or CHANNEL. The GroupName is the name of a user specified Alarm Group. The ChannelName must be the name of a specific record defined -in an EPICS database. The length of a GroupName or ChannelName must not -exceed 28 characters. The parentName is the name of the parent Alarm +in an EPICS database. The parentName is the name of the parent Alarm Group. There is no restriction on the number of group definitions.

GROUP parentName GroupName

@@ -1825,7 +1890,7 @@

Related Commands

names and command strings separated by exclamation points, "!", using the following syntax

$COMMAND   -cmd 1 name!cmd 1 string!cmd 2 name!cmd 2 string!...cmd n name!cmd n string +cmd_1_name!cmd_1_string!cmd_2_name!cmd_2_string!...cmd_n_name!cmd_n_string

Severity Command

@@ -1868,6 +1933,14 @@

Alarm Count Filter

channel must enter into an alarm state from a no-alarm state more than inputCount times within inputSeconds seconds.

+

If inputCounts is zero, inputCounts is not used +in determining alarm/no-alarm states, only inputSeconds is used to filter a +channel going in and out of alarm state. If inputCounts is -1, inputSeconds +only is used for filtering a channel going from no-alarm to alarm state, +and a change in channel from alarm state to no-alarm state is not filtered. + +

+

$ALARMCOUNTFILTER inputCount inputSeconds

Beep Severity

diff --git a/documentation/ALH.title.html b/documentation/ALH.title.html index d0ee639..f3defdf 100644 --- a/documentation/ALH.title.html +++ b/documentation/ALH.title.html @@ -10,8 +10,8 @@

Alarm Handler User's Guide



-

ALH 1.2.26

-

December 2010

+

ALH 1.2.35

+

August 2014




diff --git a/documentation/Makefile b/documentation/Makefile index 1a458b3..af5d9a1 100644 --- a/documentation/Makefile +++ b/documentation/Makefile @@ -1,9 +1,9 @@ # Makefile for generating published alhUserGuide files -HTMLDOC = "/home/phoebus/ANJ/bin/solaris-sparc/htmldoc" +HTMLDOC = "/home/phoebus/JBA/bin/solaris-sparc/htmldoc" WEBSITE = /net/epics/Public/epics/EpicsDocumentation/ExtensionsManuals/AlarmHandler -VERSION = 1.2.16 +VERSION = 1.2.35 # Content options: @@ -37,15 +37,15 @@ FILES = ALH.html # ALHUserGuide.html is name of file in alh/Makefile.Host -all: alhUserGuide.ps.gz alhUserGuide.pdf ALHUserGuide.html +all: alhUserGuide-$(VERSION).ps.gz alhUserGuide-$(VERSION).pdf ALHUserGuide-$(VERSION).html -alhUserGuide.ps: $(FILES) Makefile +alhUserGuide-$(VERSION).ps: $(FILES) Makefile $(HTMLDOC) $(PSOPTS) -f $@ $(FILES) -alhUserGuide.pdf: $(FILES) Makefile +alhUserGuide-$(VERSION).pdf: $(FILES) Makefile $(HTMLDOC) $(PDFOPTS) -f $@ $(FILES) -ALHUserGuide.html: $(FILES) Makefile +ALHUserGuide-$(VERSION).html: $(FILES) Makefile rm -rf $@ $(HTMLDOC) $(HTMLOPTS) -f $@ $(FILES) @@ -54,13 +54,13 @@ ALHUserGuide.html: $(FILES) Makefile gzip $< install: all - /bin/cp -f alhUserGuide.ps.gz $(WEBSITE)/alhUserGuide-$(VERSION).ps.gz - /bin/cp -f alhUserGuide.pdf $(WEBSITE)/alhUserGuide-$(VERSION).pdf - #/bin/cp -rf alhUserGuide $(WEBSITE)/alhUserGuide-$(VERSION) + /bin/cp -f alhUserGuide-$(VERSION).ps.gz $(WEBSITE)/alhUserGuide-$(VERSION).ps.gz + /bin/cp -f alhUserGuide-$(VERSION).pdf $(WEBSITE)/alhUserGuide-$(VERSION).pdf + /bin/cp -rf alhUserGuide $(WEBSITE)/alhUserGuide-$(VERSION) rm -rf $(WEBSITE)/alhUserGuide-$(VERSION) mkdir $(WEBSITE)/alhUserGuide-$(VERSION) /bin/cp -rf . $(WEBSITE)/alhUserGuide-$(VERSION) clean: - rm alhUserGuide.ps alhUserGuide.pdf ALHUserGuide.html \ - alhUserGuide.ps.gz alhUserGuide.pdf.gz + rm alhUserGuide-$(VERSION).ps alhUserGuide-$(VERSION).pdf ALHUserGuide-$(VERSION).html \ + alhUserGuide-$(VERSION).ps.gz alhUserGuide-$(VERSION).pdf.gz diff --git a/documentation/images/alhAlarmLogFile.gif b/documentation/images/alhAlarmLogFile.gif index 131b98483b99d4e98ee6dc336cdf0d5aa10db17b..8379aac04123db7e9f3a016adfdf1d1acd8e6555 100644 GIT binary patch literal 20480 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 UbyZolRbBN}VKr7IH6Q>0JKkAxsQ>@~ literal 14246 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 B<=+4R diff --git a/documentation/images/alhCurrentAlarmHistory.gif b/documentation/images/alhCurrentAlarmHistory.gif index e4f64988033e60fbb886fe62cc9a9b936e7782a9..b0bce31e16ff26bbc1aff26a5d2e84dc072bacfc 100644 GIT binary patch literal 13363 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 Y63jdAl3NC7ML1$KD$NMcKmfu22QTD7Pyhe` literal 8553 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 v6IkC?kU^FBysPRNkyN>|9Z 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 H3poBi($)jD literal 0 HcmV?d00001 diff --git a/documentation/images/alhMainWindowAlarms.gif b/documentation/images/alhMainWindowAlarms.gif index f77aab8b7a2c1b8920df405bf215b0684f18646d..e48a8c454d320079587001fa847a54a7465c4af6 100644 GIT binary patch literal 45944 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 literal 10714 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%0AoK1hQ>nmC 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 A`v3p{ diff --git a/documentation/images/alhMessage.gif b/documentation/images/alhMessage.gif index ca4d24204ffe8c40049c4a324627debd04ce2488..0e270030d9a78d25154d5ca0dd7d8a7027224e01 100644 GIT binary patch literal 8046 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 Cjm4b+ diff --git a/documentation/images/alhSendMessage.gif b/documentation/images/alhSendMessage.gif index 08731189633201d22dfe6a775f67d12177a067b7..e0c64b2cc9d4c4dae4c91d8a097da13bb73aa32a 100644 GIT binary patch literal 10233 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 literal 3217 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 Zwzjt&0E>A0+u#njxW`TIayuj-06VVeC2Ifx literal 2616 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 Xzf;%${q}C+*}vZ(yjOQ{V6X-Ns$A(* literal 0 HcmV?d00001 diff --git a/fallback.h b/fallback.h index af1120d..949f5eb 100644 --- a/fallback.h +++ b/fallback.h @@ -39,6 +39,8 @@ static String fallbackResources[] = { "*scale.value: 50", "*scale.highlightOnEnter: FALSE", "*scale.scaleMultiple: 5", + "*CurrentTitle.fontList: 7x14", + "*CurrentAlarm.fontList: 7x14", "*treeSym.fontList: 12x24", "*XmCascadeButtonGadget.fontList: 8x13", "*XmCascadeButtonWidget.fontList: 8x13", diff --git a/file.c b/file.c index fa33789..254b253 100644 --- a/file.c +++ b/file.c @@ -135,6 +135,8 @@ int use_CMLOG_opmod = 0; #endif int _xml_flag = 0; /* Use XML-ish log format. SNS */ +int _mask_color_flag = 0; /* SLS (Andreas Luedeke): if channel/group mask disables sound, then change bg color of mask */ + /* this helps to quickly check for all disabled channels, e.g. before an application restart */ extern int DEBUG; @@ -148,13 +150,15 @@ struct command_line_data { char* configDir; char* logDir; + char* lockFileBase; /* Andreas Luedeke */ + char* soundFile; /* Andreas Luedeke */ char* configFile; char* logFile; char* opModFile; int alarmLogFileMaxRecords; }; static struct command_line_data commandLine = { - NULL,NULL,NULL,NULL,NULL,0}; + NULL,NULL,NULL,NULL,NULL,NULL,NULL,0}; #define PARM_DEBUG 0 #define PARM_ACT 1 @@ -182,6 +186,9 @@ static struct command_line_data commandLine = { #define PARM_ALARM_FILTER 23 #define PARM_DESC_FIELD 24 #define PARM_XML 25 +#define PARM_LOCK_FILE 26 +#define PARM_SOUND_FILE 27 +#define PARM_NOACK_MASK_COLOR 28 struct parm_data { char* parm; @@ -193,37 +200,40 @@ struct parm_data static struct parm_data ptable[] = { #ifdef CMLOG - { "-aCM", 4, PARM_ALARM_LOG_CMLOG }, + { "-aCM", 4, PARM_ALARM_LOG_CMLOG }, #endif - { "-a", 2, PARM_ALARM_LOG_FILE }, - { "-B", 2, PARM_MESSAGE_BROADCAST }, /* Albert */ - { "-c", 2, PARM_ACT }, - { "-caputackt", 10, PARM_CAPUT_ACK_TRANSIENTS }, - { "-D", 2, PARM_READONLY }, - { "-debug", 6 , PARM_DEBUG }, - { "-desc_field", 11 , PARM_DESC_FIELD }, - { "-filter", 7, PARM_ALARM_FILTER }, - { "-f", 2, PARM_ALL_FILES_DIR }, - { "-global", 7, PARM_GLOBAL }, - { "-help", 5, PARM_HELP }, - { "-L", 2, PARM_LOCK }, /* Albert */ - { "-l", 2, PARM_LOG_DIR }, + { "-a", 2, PARM_ALARM_LOG_FILE }, + { "-B", 2, PARM_MESSAGE_BROADCAST }, /* Albert */ + { "-c", 2, PARM_ACT }, + { "-caputackt", 10, PARM_CAPUT_ACK_TRANSIENTS }, + { "-D", 2, PARM_READONLY }, + { "-debug", 6 , PARM_DEBUG }, + { "-desc_field", 11 , PARM_DESC_FIELD }, + { "-f", 2, PARM_ALL_FILES_DIR }, + { "-filter", 7, PARM_ALARM_FILTER }, + { "-global", 7, PARM_GLOBAL }, + { "-help", 5, PARM_HELP }, + { "-L", 2, PARM_LOCK }, /* Albert */ + { "-Lfile", 6, PARM_LOCK_FILE }, /* Andreas Luedeke */ + { "-l", 2, PARM_LOG_DIR }, + { "-m", 2, PARM_ALARM_LOG_MAX }, { "-mainwindow", 11, PARM_MAIN_WINDOW }, - { "-m", 2, PARM_ALARM_LOG_MAX }, + { "-maskcolor", 10, PARM_NOACK_MASK_COLOR }, { "-noerrorpopup", 13, PARM_NO_ERROR_POPUP }, - { "-O", 2, PARM_DATABASE }, /* Albert */ + { "-O", 2, PARM_DATABASE }, /* Albert */ + { "-o", 2, PARM_OPMOD_LOG_FILE }, #ifdef CMLOG - { "-oCM", 4, PARM_OPMOD_LOG_CMLOG }, + { "-oCM", 4, PARM_OPMOD_LOG_CMLOG }, #endif - { "-o", 2, PARM_OPMOD_LOG_FILE }, - { "-P", 2, PARM_PRINTER }, - { "-S", 2, PARM_PASSIVE }, - { "-s", 2, PARM_SILENT }, - { "-T", 2, PARM_DATED }, - { "-v", 2, PARM_VERSION }, - { "-version", 8, PARM_VERSION }, - { "-xml", 4, PARM_XML }, /* SNS */ - { NULL, -1, -1 }}; + { "-p", 2, PARM_SOUND_FILE }, + { "-P", 2, PARM_PRINTER }, + { "-S", 2, PARM_PASSIVE }, + { "-s", 2, PARM_SILENT }, + { "-T", 2, PARM_DATED }, + { "-v", 2, PARM_VERSION }, + { "-version", 8, PARM_VERSION }, + { "-xml", 4, PARM_XML }, /* SNS */ + { NULL, -1, -1 }}; /* forward declarations */ static void saveConfigFile_callback(Widget widget,char *filename, @@ -233,7 +243,7 @@ static void fileSetup(char *filename,ALINK *area,int fileType,int programId, Widget widget); static int checkFilename(char *filename,int fileType); static int getCommandLineParms(int argc, char** argv); -int getUserInfo(); +static int getUserInfo(); /*************************************************** exit and quit application @@ -250,8 +260,8 @@ void exit_quit(Widget w, XtPointer clientdata, XtPointer calldata) } alLogOpModMessage(0,0,"Setup---Exit"); - fclose(fl); - fclose(fo); + if (fl) { fclose(fl); fl=0; } + if (fo) { fclose(fo); fo=0; } if (area && area->pmainGroup) proot = area->pmainGroup->p1stgroup; /* @@ -408,7 +418,7 @@ static int checkFilename(char *filename,int fileType) break; } - fclose(tt); + if (tt) fclose(tt); return 0; } @@ -479,7 +489,9 @@ int programId,Widget widget) strncat(filename, &buf[0], strlen(buf)); } /* _______ End. Albert______________________________*/ + error = checkFilename(filename,fileType); + if (error){ switch(fileType) { @@ -526,7 +538,7 @@ int programId,Widget widget) if (error){ fileSelectionBox = widget; /* Display file selection box */ - if ( XtIsShell(widget)) { + if (widget && XtIsShell(widget)) { long fileTypeLong=fileType; Atom WM_DELETE_WINDOW; fileSelectionBox = createFileDialog(widget, @@ -563,15 +575,27 @@ int programId,Widget widget) break; case 4: - /*createDialog(fileSelectionBox,XmDIALOG_ERROR,filename," write error.");*/ - fatalErrMsg("Write error for file %s.\n",filename); + errMsg("Error opening file %s\n",filename); + switch(fileType) { + case FILE_ALARMLOG: + errMsg("WARNING: Continuing without Alarm Log file\n"); + break; + case FILE_OPMOD: + errMsg("WARNING: Continuing without OpMod Log file\n"); + break; + default: + break; + } + + break; + default: break; } } else { /* unmanage the fileSelection dialog */ - if ( !XtIsShell(widget)) + if (widget && !XtIsShell(widget)) createFileDialog(0,0,0,0,0,0,0,0,0); switch(fileType) { @@ -585,8 +609,8 @@ int programId,Widget widget) if(_lock_flag) /* Albert */ { FILE *fp; - strcpy(lockFileName,psetup.configFile); - strcat(lockFileName,".LOCK"); + strcpy(lockFileName,psetup.lockFileBase); /* Andreas Luedeke */ + strcat(lockFileName,".LOCK"); /* allow lock to be generated outside logdir */ if (!(fp=fopen(lockFileName,"a"))) { perror("Can't open locking file for a"); @@ -698,24 +722,26 @@ int programId,Widget widget) break; case FILE_ALARMLOG: - if (fo) alLogOpModMessage(0,0,"Setup Alarm Log File : %s",filename); + alLogOpModMessage(0,0,"Setup Alarm Log File : %s",filename); strcpy(psetup.logFile,filename); if (fl) fclose(fl); /* RO-flag. Albert */ if(_read_only_flag) fl = fopen(psetup.logFile,"r"); else if((_time_flag)||(_lock_flag)) fl = fopen(psetup.logFile,"a"); else fl = fopen(psetup.logFile,"w+"); - if (!fl) perror("CAN'T OPEN LOG FILE"); /* Albert */ + if (!fl) perror("CAN'T OPEN ALARM LOG FILE"); /* Albert */ + if (!fl) errMsg("CAN'T OPEN ALARM LOG FILE"); if (alarmLogFileMaxRecords) alarmLogFileOffsetBytes = 0; break; case FILE_OPMOD: - if (fo) alLogOpModMessage(0,0,"Setup OpMod File : %s",filename); + alLogOpModMessage(0,0,"Setup OpMod File : %s",filename); strcpy(psetup.opModFile,filename); if (fo) fclose(fo); if(!_read_only_flag) fo=fopen(psetup.opModFile,"a"); /* RO-option. Albert */ else fo=fopen(psetup.opModFile,"r"); - if (!fo) perror("CAN'T OPEN OP FILE"); /* Albert */ + if (!fo) perror("CAN'T OPEN OPMOD LOG FILE"); /* Albert */ + if (!fo) errMsg("CAN'T OPEN OPMOD LOG FILE"); break; case FILE_SAVEAS: @@ -748,7 +774,7 @@ XmAnyCallbackStruct *cbs) XtVaGetValues(widget, XmNuserData, &area, NULL); - if (fo) alLogOpModMessage(0,0,"Setup Save New Config: %s",filename); + alLogOpModMessage(0,0,"Setup Save New Config: %s",filename); if ( DEBUG == 1 ) printf("\nSaving Config File to %s \n", filename); @@ -770,6 +796,7 @@ static int getCommandLineParms(int argc, char** argv) int i,j; int finished=0; int parm_error=0; + FILE *fp; alarmLogFileMaxRecords=commandLine.alarmLogFileMaxRecords=2000; /* Albert */ @@ -964,6 +991,38 @@ static int getCommandLineParms(int argc, char** argv) _xml_flag=1; finished=1; break; + case PARM_LOCK_FILE: /* Andreas Luedeke: place .LOCK file in special directory */ + if(++i>=argc) parm_error=1; + else + { + if(argv[i][0]=='-') parm_error=2; + else + { + commandLine.lockFileBase=argv[i]; + finished=1; + } + } + break; + case PARM_SOUND_FILE: /* Andreas Luedeke: WAV file as alarm sound (implemented for Linux with "play") */ + if(++i>=argc) parm_error=1; + else + { + if(argv[i][0]=='-') parm_error=2; + else + { + strncpy(psetup.soundFile,argv[i],NAMEDEFAULT_SIZE-1); + fp = fopen(psetup.soundFile,"r"); + if (!fp) perror("Can't open beep file\n"); + if (!fp) errMsg("Can't open beep file %s\n",psetup.soundFile); + finished=1; + } + } + break; + case PARM_NOACK_MASK_COLOR: /* Andreas Luedeke: if channel/group mask disables sound, then change bg color of mask */ + _mask_color_flag=1; + finished=1; + break; + default: parm_error=1; break; @@ -1012,7 +1071,7 @@ if(_DB_call_flag&&!_lock_flag) return 1; } - if (_xml_flag) puts ("XML!"); else puts("no XML!"); + if (_xml_flag) puts ("XML!"); return 0; } @@ -1045,15 +1104,18 @@ static void printUsage(char *pgm) fprintf(stderr," -global Global mode (acks and ackt fields) \n"); fprintf(stderr," -help Print usage\n"); fprintf(stderr," -L Locking system\n"); + fprintf(stderr," -Lfile lockfile Directory for lock files [configdir]\n"); /* Andreas Luedeke */ fprintf(stderr," -l logdir Directory for log files [.]\n"); fprintf(stderr," -m maxrecords Alarm log file max records [2000]\n"); fprintf(stderr," -mainwindow Start with main window\n"); + fprintf(stderr," -maskcolor Print mask colored when channel/group contains silencing flag\n"); fprintf(stderr," -noerrorpopup Do not display error popup window (errors are logged).\n"); fprintf(stderr," -O key Database call\n"); fprintf(stderr," -o opmodlogfile OpMod log filename ["DEFAULT_OPMOD"]\n"); #ifdef CMLOG fprintf(stderr," -oCM OpMod log using CMLOG\n"); #endif + fprintf(stderr," -p sound Use wave data from file instead of alarm beep (OS dependent)\n"); fprintf(stderr," -P key Print to TCP printer\n"); fprintf(stderr," -S Passive (no caputs - acks field, ackt field, sevrpv)\n"); fprintf(stderr," -s Silent (no alarm beeping)\n"); @@ -1077,6 +1139,7 @@ char *argv[]; char logFile[NAMEDEFAULT_SIZE]; char opModFile[NAMEDEFAULT_SIZE]; char *name = NULL; + programId = ALH; programName = (char *)calloc(1,4); strcpy(programName,"alh"); @@ -1118,7 +1181,7 @@ char *argv[]; strncat(psetup.opModFile,opModFile,NAMEDEFAULT_SIZE-len); } if (DEBUG == 1 ) printf("\nOpMod File is %s \n", psetup.opModFile); - fileSetup(psetup.opModFile,NULL,FILE_OPMOD,programId,widget); + fileSetup(psetup.opModFile,NULL,FILE_OPMOD,programId,0); /* ----- initialize and setup alarm log file ----- */ if (psetup.logDir) { @@ -1139,7 +1202,7 @@ char *argv[]; strncat(psetup.logFile,logFile,NAMEDEFAULT_SIZE-len); } if (DEBUG == 1 ) printf("\nAlarmLog File is %s \n", psetup.logFile); - fileSetup(psetup.logFile,NULL,FILE_ALARMLOG,programId,widget); + fileSetup(psetup.logFile,NULL,FILE_ALARMLOG,programId,0); /* ----- initialize and setup config file ----- */ if (psetup.configDir) { @@ -1161,6 +1224,14 @@ char *argv[]; } if (DEBUG == 1 ) printf("\nConfig File is %s \n", psetup.configFile); fileSetup(psetup.configFile,NULL,FILE_CONFIG,programId,widget); + + /* ----- initialize and setup lock file ----- */ + if (commandLine.lockFileBase) /* Andreas Luedeke */ + strncpy(psetup.lockFileBase,commandLine.lockFileBase,NAMEDEFAULT_SIZE-1); + else + strncpy(psetup.lockFileBase,psetup.configFile,NAMEDEFAULT_SIZE-1); + + if (DEBUG == 1 ) printf("\nLock File is %s.LOCK \n", psetup.lockFileBase); } @@ -1227,7 +1298,7 @@ fclose(fp); if(!amIsender) { createDialog(w,XmDIALOG_INFORMATION,"\nBROADCAST MESSAGE:\n",messBuff); - XBell(XtDisplay(w),50); + alBeep(XtDisplay(w)); } if(strncmp(messBuff,reloadMBString+2,strlen(reloadMBString)-3 )==0) { @@ -1282,7 +1353,7 @@ exit_quit(NULL,NULL,NULL); /* signal(SIGINT,broadcastMess_exit_quit); Albert */ } -int getUserInfo() +static int getUserInfo() { static char myhostname[256]; static char loginid[16]; diff --git a/force.c b/force.c index c60c816..607cc63 100644 --- a/force.c +++ b/force.c @@ -358,8 +358,7 @@ static void forcePVCreateDialog(ALINK *area) xmLabelGadgetClass, form, XmNalignment, XmALIGNMENT_END, XmNtopAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 50, + XmNleftAttachment, XmATTACH_FORM, XmNrecomputeSize, True, NULL); @@ -367,8 +366,9 @@ static void forcePVCreateDialog(ALINK *area) xmLabelGadgetClass, form, XmNalignment, XmALIGNMENT_BEGINNING, XmNtopAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_POSITION, - XmNleftPosition, 50, + XmNleftAttachment, XmATTACH_WIDGET, + XmNleftWidget, nameLabelW, + XmNrightAttachment, XmATTACH_FORM, XmNrecomputeSize, True, NULL); @@ -404,8 +404,8 @@ static void forcePVCreateDialog(ALINK *area) xmLabelGadgetClass, form2, XmNlabelString, string, XmNtopAttachment, XmATTACH_WIDGET, - XmNtopWidget, forcePVdisabledToggleButton, - XmNtopOffset, 10, + XmNtopWidget, forcePVdisabledToggleButton, + XmNtopOffset, 10, NULL); XmStringFree(string); @@ -413,12 +413,12 @@ static void forcePVCreateDialog(ALINK *area) xmTextFieldWidgetClass, form2, XmNspacing, 0, XmNmarginHeight, 0, - XmNcolumns, 30, XmNmaxLength, PVNAME_SIZE, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, forcePVnameLabel, XmNleftAttachment, XmATTACH_FORM, + XmNrightAttachment, XmATTACH_FORM, (XtPointer)NULL); XtAddCallback(forcePVnameTextW, XmNactivateCallback, @@ -491,8 +491,8 @@ static void forcePVCreateDialog(ALINK *area) XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, prev, - XmNleftAttachment, XmATTACH_WIDGET, - XmNleftWidget, forcePVforceValueLabel, + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 40, NULL); XtAddCallback(forcePVforceValueTextW, XmNactivateCallback, @@ -516,8 +516,8 @@ static void forcePVCreateDialog(ALINK *area) XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, forcePVforceValueTextW, - XmNleftAttachment, XmATTACH_WIDGET, - XmNleftWidget, forcePVresetValueLabel, + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 40, NULL); XtAddCallback(forcePVresetValueTextW, XmNactivateCallback, @@ -595,17 +595,17 @@ static void forcePVCreateDialog(ALINK *area) xmTextFieldWidgetClass, form3, XmNspacing, 0, XmNmarginHeight, 0, - XmNcolumns, 30, XmNmaxLength, PVNAME_SIZE, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, prev, +#if 0 XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, forcePVCalcPVLabel[i], -#if 0 - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 50, #endif + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 10, + XmNrightAttachment, XmATTACH_FORM, (XtPointer)NULL); prev = forcePVCalcPVTextW[i]; diff --git a/mask.c b/mask.c index 3f08290..20839c1 100644 --- a/mask.c +++ b/mask.c @@ -235,19 +235,15 @@ static void maskCreateDialog(ALINK *area) --------------------------------- */ nameLabelW = XtVaCreateManagedWidget("nameLabelW", xmLabelGadgetClass, form, - XmNalignment, XmALIGNMENT_END, XmNtopAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, (TIGHTNESS*(num_buttons+3) - 1)/2, + XmNleftAttachment, XmATTACH_FORM, XmNrecomputeSize, True, (XtPointer)NULL); nameTextW = XtVaCreateManagedWidget("nameTextW", xmLabelGadgetClass, form, - XmNalignment, XmALIGNMENT_BEGINNING, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, nameLabelW, - XmNrightAttachment, XmATTACH_NONE, XmNrecomputeSize, True, NULL); diff --git a/os/Linux/alAudio.c b/os/Linux/alAudio.c new file mode 100644 index 0000000..da416d0 --- /dev/null +++ b/os/Linux/alAudio.c @@ -0,0 +1,49 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 Deutches Elektronen-Synchrotron in der Helmholtz- +* Gemelnschaft (DESY). +* Copyright (c) 2002 Berliner Speicherring-Gesellschaft fuer Synchrotron- +* Strahlung mbH (BESSY). +* Copyright (c) 2002 Southeastern Universities Research Association, as +* Operator of Thomas Jefferson National Accelerator Facility. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* This file is distributed subject to a Software License Agreement found +* in the file LICENSE that is included with this distribution. +\*************************************************************************/ +/* alAudio.c + * + * alAudio.c,v 1.3 2003/02/27 17:20:08 jba Exp + * + */ + +#include +#include + +#include "alh.h" +#include "ax.h" +#include + +/* Audio device not implemented */ + +/****************************************************** + alBeep +******************************************************/ +void alBeep(Display *displayBB) +{ + static char cmd[NAMEDEFAULT_SIZE+9]=""; + if(strlen(psetup.soundFile)>0 ) { + if(strlen(cmd)==0 ) { + strcat(cmd,"play -q "); + strcat(cmd,psetup.soundFile); + strcat(cmd," &"); + /*strcat(cmd," > /dev/null 2>&1 &");*/ + } + system(cmd); + } else { + XkbBell(displayBB,None,0,None); + } + return; +} + diff --git a/os/Linux/alAudio.h b/os/Linux/alAudio.h new file mode 100644 index 0000000..9d49b62 --- /dev/null +++ b/os/Linux/alAudio.h @@ -0,0 +1,20 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 Deutches Elektronen-Synchrotron in der Helmholtz- +* Gemelnschaft (DESY). +* Copyright (c) 2002 Berliner Speicherring-Gesellschaft fuer Synchrotron- +* Strahlung mbH (BESSY). +* Copyright (c) 2002 Southeastern Universities Research Association, as +* Operator of Thomas Jefferson National Accelerator Facility. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* This file is distributed subject to a Software License Agreement found +* in the file LICENSE that is included with this distribution. +\*************************************************************************/ +/* alAudio.h */ + +/* do not #define AUDIO_BEEP */ + +/*extern void alhAudioSetupCallback( Widget widget, XtPointer calldata, XtPointer cbs);*/ + diff --git a/os/WIN32/alAudio.c b/os/WIN32/alAudio.c index e8095b3..d4e4656 100644 --- a/os/WIN32/alAudio.c +++ b/os/WIN32/alAudio.c @@ -14,7 +14,7 @@ \*************************************************************************/ /* alAudio.c * - alAudio.c,v 1.2 2002/08/02 15:37:47 jba Exp + alAudio.c,v 1.3 2010/12/23 19:37:40 jba Exp */ /************************DESCRIPTION*********************************** @@ -71,10 +71,10 @@ static struct beepsetup { short balance; short beepSource; unsigned char *beep; - unsigned long beepLength; + size_t beepLength; char *beepFileName; unsigned char *beepFileData; - unsigned long beepFileLength; + size_t beepFileLength; } audioSetup={NULL,NULL,AUDIO_DEFAULT_OUTPUT,AUDIO_CHANNELS_STEREO, 8000,50,BEEP_AUDIO_SOURCE_INTERNAL,0,0,0,0,0} ; @@ -518,9 +518,9 @@ static int audioSetupNewFilename(Widget widget, char *string) { char * filename; char * plast; - int filenameSize; + size_t filenameSize; unsigned long fileSize; - unsigned long beepLength; + size_t beepLength; FILE * fp; unsigned char* beep; diff --git a/os/default/alAudio.c b/os/default/alAudio.c index 6e58266..c6e36ab 100644 --- a/os/default/alAudio.c +++ b/os/default/alAudio.c @@ -14,11 +14,15 @@ \*************************************************************************/ /* alAudio.c * - * alAudio.c,v 1.4 2009/10/15 14:50:20 jba Exp + * alAudio.c,v 1.6 2014/08/25 18:57:49 jba Exp * */ #include + +#include +#include + #include "alh.h" /* Audio device not implemented */ @@ -26,11 +30,11 @@ /****************************************************** alBeep ******************************************************/ -int alBeep(Display *displayBB) +void alBeep(Display *displayBB) { /* system("play /path/to/beep.wav"); */ - XBell(displayBB,0); - return 0; + XkbBell(displayBB,None,0,None); + return; } diff --git a/os/solaris/alAudio.c b/os/solaris/alAudio.c index 6114c34..6c43161 100644 --- a/os/solaris/alAudio.c +++ b/os/solaris/alAudio.c @@ -14,7 +14,7 @@ \*************************************************************************/ /* alAudio.c * - alAudio.c,v 1.3 2002/08/02 15:37:48 jba Exp + alAudio.c,v 1.4 2011/01/27 15:00:54 jba Exp */ /************************DESCRIPTION*********************************** @@ -31,6 +31,9 @@ #include #include +#include +#include + #include #include #include @@ -251,10 +254,10 @@ void alBeep(Display *displayBB) percent = 100; if (audioSetup.port==AUDIO_NONE){ - XBell(displayBB,percent); + XkbBell(displayBB,None,percent,None); } else { if (alAudioBeep()){ - XBell(displayBB,percent); + XkbBell(displayBB,None,percent,None); } } } diff --git a/process.c b/process.c index bc284be..ff41162 100644 --- a/process.c +++ b/process.c @@ -100,7 +100,7 @@ Else if you're master-alh-process -- the same errMsg("processSpawn_callback: Cannot find command processor\n"); return; } - status = _spawnl(_P_DETACH, ComSpec, ComSpec, "/C", buff, NULL); + status = (int)_spawnl(_P_DETACH, ComSpec, ComSpec, "/C", buff, NULL); #else sprintf(buff,"%s &",command); status=system(buff); diff --git a/property.c b/property.c index a2d4073..d46d3a6 100644 --- a/property.c +++ b/property.c @@ -582,17 +582,12 @@ static void propCreateDialog(ALINK *area) xmTextFieldWidgetClass, form, XmNspacing, 0, XmNmarginHeight, 0, -/* - XmNcolumns, 30, - XmNrecomputeSize, True, -*/ XmNmaxLength, PVNAME_SIZE, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, nameLabelW, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 50, + XmNrightAttachment, XmATTACH_FORM, NULL); XtAddCallback(nameTextW, XmNactivateCallback, @@ -685,7 +680,8 @@ static void propCreateDialog(ALINK *area) --------------------------------- */ countFilterFrame = XtVaCreateManagedWidget("countFilterFrame", xmFrameWidgetClass, form, - XmNtopAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopWidget, nameTextW, XmNrightAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 50, @@ -769,7 +765,7 @@ static void propCreateDialog(ALINK *area) frame2 = XtVaCreateManagedWidget("frame2", xmFrameWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, - XmNtopWidget, prev, + XmNtopWidget, form1, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); @@ -803,13 +799,15 @@ static void propCreateDialog(ALINK *area) xmTextFieldWidgetClass, form2, XmNspacing, 0, XmNmarginHeight, 0, - XmNcolumns, 30, +/* XmNmaxLength, PVNAME_SIZE, +*/ XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, forcePVLabel, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, forcePVnameLabel, + XmNrightAttachment, XmATTACH_FORM, NULL); XtAddCallback(forcePVnameTextW, XmNactivateCallback, @@ -826,7 +824,9 @@ static void propCreateDialog(ALINK *area) XmStringFree(string); prev = forcePVForceMaskLabel; +/* string = XmStringCreateSimple("-----"); +*/ forcePVForceMaskStringLabelW = XtVaCreateManagedWidget("forcePVmaskStringLabelW", xmLabelGadgetClass, form2, XmNlabelString, string, @@ -835,7 +835,9 @@ static void propCreateDialog(ALINK *area) XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, forcePVForceMaskLabel, NULL); +/* XmStringFree(string); +*/ string = XmStringCreateSimple(" Force Value "); forcePVforceValueLabel = XtVaCreateManagedWidget("forcePVvalue", @@ -890,14 +892,14 @@ static void propCreateDialog(ALINK *area) (XtCallbackProc)XmProcessTraversal, (XtPointer)XmTRAVERSE_NEXT_TAB_GROUP); frame3 = XtVaCreateManagedWidget("frame3", - xmFrameWidgetClass, form2, + xmFrameWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, forcePVforceValueTextW, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); - form3 = XtVaCreateWidget("form2", + form3 = XtVaCreateWidget("form3", xmFormWidgetClass, frame3, XmNspacing, 0, XmNmarginHeight, 0, @@ -926,8 +928,6 @@ static void propCreateDialog(ALINK *area) xmTextFieldWidgetClass, form3, XmNspacing, 0, XmNmarginHeight, 0, - XmNcolumns, 40, - XmNmaxLength, 100, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, @@ -985,12 +985,8 @@ static void propCreateDialog(ALINK *area) XmNlabelString, string, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, prev, - XmNleftAttachment, XmATTACH_POSITION, - XmNleftPosition, 50, -/* - XmNleftAttachment, XmATTACH_WIDGET, - XmNleftWidget, forcePVCalcPVTextW[i-6], -*/ + XmNleftAttachment, XmATTACH_POSITION, + XmNleftPosition, 50, NULL); XmStringFree(string); @@ -998,8 +994,6 @@ static void propCreateDialog(ALINK *area) xmTextFieldWidgetClass, form3, XmNspacing, 0, XmNmarginHeight, 0, - XmNcolumns, 30, - XmNmaxLength, PVNAME_SIZE, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, prev, @@ -1029,7 +1023,7 @@ static void propCreateDialog(ALINK *area) xmLabelGadgetClass, form, XmNlabelString, string, XmNtopAttachment, XmATTACH_WIDGET, - XmNtopWidget, frame2, + XmNtopWidget, frame3, XmNleftAttachment, XmATTACH_FORM, NULL); XmStringFree(string); @@ -1042,7 +1036,7 @@ static void propCreateDialog(ALINK *area) XmNmaxLength, 10, XmNbackground, textBackground, XmNtopAttachment, XmATTACH_WIDGET, - XmNtopWidget, frame2, + XmNtopWidget, frame3, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, beepSeverityLabel, NULL); @@ -1786,6 +1780,7 @@ void *area; static void propEditableDialogWidgets(ALINK *area) { struct propWindow *propWindow; + int i; propWindow = (struct propWindow *)area->propWindow; @@ -1798,6 +1793,10 @@ static void propEditableDialogWidgets(ALINK *area) XtVaSetValues(propWindow->forcePVnameTextW,XmNeditable, FALSE, NULL); XtVaSetValues(propWindow->forcePVforceValueTextW,XmNeditable, FALSE, NULL); XtVaSetValues(propWindow->forcePVresetValueTextW,XmNeditable, FALSE, NULL); + XtVaSetValues(propWindow->forcePVCalcExpressionTextW,XmNeditable, FALSE, NULL); + for (i=0;iforcePVCalcPVTextW[i],XmNeditable, FALSE, NULL); + } XtVaSetValues(propWindow->aliasTextW,XmNeditable, FALSE, NULL); XtVaSetValues(propWindow->processTextW,XmNeditable, FALSE, NULL); XtVaSetValues(propWindow->sevrProcessTextW,XmNeditable, FALSE, NULL); @@ -1813,6 +1812,10 @@ static void propEditableDialogWidgets(ALINK *area) XtVaSetValues(propWindow->forcePVnameTextW,XmNeditable, TRUE, NULL); XtVaSetValues(propWindow->forcePVforceValueTextW,XmNeditable, TRUE, NULL); XtVaSetValues(propWindow->forcePVresetValueTextW,XmNeditable, TRUE, NULL); + XtVaSetValues(propWindow->forcePVCalcExpressionTextW,XmNeditable, TRUE, NULL); + for (i=0;iforcePVCalcPVTextW[i],XmNeditable, TRUE, NULL); + } XtVaSetValues(propWindow->aliasTextW,XmNeditable, TRUE, NULL); XtVaSetValues(propWindow->processTextW,XmNeditable, TRUE, NULL); XtVaSetValues(propWindow->sevrProcessTextW,XmNeditable, TRUE, NULL); diff --git a/scroll.c b/scroll.c index 0d30f25..9bf8106 100644 --- a/scroll.c +++ b/scroll.c @@ -87,7 +87,6 @@ char *Strncat( # define MAX(a,b) ((a) > (b) ? a : b) #endif - static int viewFileUsedLength[N_LOG_FILES]; /* used length of file. */ static int viewFileMaxLength[N_LOG_FILES]; /* max length of file. */ static char *viewFileString[N_LOG_FILES]; /* contents of file. */ @@ -100,157 +99,68 @@ extern int alarmLogFileOffsetBytes; /* alarm log file current offset in bytes */ extern int alarmLogFileStringLength; /* alarm log file record length*/ extern int alarmLogFileMaxRecords; /* alarm log file maximum # records */ - extern int DEBUG; extern struct setup psetup; /* current file setup */ -static char error_file_size[] = { - " Sorry: file size too big to view." - }; - - -typedef struct fplistTag { - struct fplistTag *flink; - struct fplistTag *blink; - FILE *f; -} fplistType, *fplistPtr; - -static fplistPtr g_head; +static char error_file_size[] = { " Sorry: file size too big to view." }; #define MAXCONFIGFILELINE 1023 + #ifdef WIN32 #define strtok_r strtok_s #endif -static void readFile ( - fplistPtr cur, - char *buf, - int *max, - int *size, - int *depth -) { - -char line[MAXCONFIGFILELINE+1], *result, *tk, *ctx, incFile[1023+1]; -fplistPtr new; -int i, l; - - if ( cur->f ) { - - do { - - result = fgets( line, MAXCONFIGFILELINE, cur->f ); - if ( result ) { +/**************************************************************** +static void readFile +****************************************************************/ +static int readFile (char *filename, char **buf, int *max, int *fsize, int *depth) +{ + FILE *fp; + char line[MAXCONFIGFILELINE+1], *result, *tk, *ctx; + int i; + int status; + + /* open the file */ + if ((fp = fopen(filename, "r")) == NULL) { + errMsg("Cannot open file view: file %s not found\n",filename); + return -1; /* bail out if no file found */ + } - *size += strlen(line) + *depth * 3; + /* read the file */ + while ( (result = fgets( line, MAXCONFIGFILELINE, fp)) ) { - if ( *size+10 > *max ) { - *max = (int)(*size + 0.5 * *size); - buf = (char *) XtRealloc( buf, *max ); + /* realloc buf if fsize is not large enough */ + *fsize += (int)strlen(line) + *depth * 3; + if ( *fsize+1 > *max ) { + *max = (int)(*fsize + 0.5 * *fsize); + *buf = (char *) XtRealloc( *buf, *max ); } - for ( i=0; i<*depth; i++ ) strcat( buf, " " ); + /* indent lines of an embedded file by 3 blanks * depth of INCLUDE */ + for ( i=0; i<*depth; i++ ) strcat( *buf, " " ); - strcat( buf, line ); + strcat( *buf, line ); - ctx = NULL; - tk = strtok_r( line, " \t\n", &ctx ); - if ( tk ) { - if ( strcmp( tk, "INCLUDE" ) == 0 ) { - tk = strtok_r( NULL, " \t\n", &ctx ); + /* test for a "INCLUDE groupname filename" line */ + ctx = NULL; + tk = strtok_r( line, " \t\n", &ctx); + if ( tk && strcmp( tk, "INCLUDE" )==0 ) { + tk = strtok_r( NULL, " \t\n", &ctx); /* ignore groupname */ if ( tk ) { - tk = strtok_r( NULL, " \t\n", &ctx ); + tk = strtok_r( NULL, " \t\n", &ctx); /* filename */ if ( tk ) { - new = (fplistPtr) calloc( 1, sizeof(fplistType) ); - g_head->blink->flink = new; - new->blink = g_head->blink; - new->flink = g_head; - g_head->blink = new; - if ( psetup.configDir ) { - strncpy( incFile, psetup.configDir, 1023 ); - incFile[1023] = 0; - l = strlen( incFile ); - if ( l > 0 ) { - if ( incFile[l-1] != '/' ) { - Strncat( incFile, "/", 1023 ); - incFile[1023] = 0; - } - } - } - else { - strcpy( incFile, "" ); - } - Strncat( incFile, tk, 1023 ); - incFile[1023] = 0; - new->f = fopen( incFile, "r" ); (*depth)++; - *size += strlen("----------------------------\n") + - *depth * 3; - if ( *size+10 > *max ) { - *max = (int)(*size + 0.5 * *size); - buf = (char *) XtRealloc( buf, *max ); - } - for ( i=0; i<*depth; i++ ) strcat( buf, " " ); - strcat( buf, "----------------------------\n" ); - readFile( new, buf, max, size, depth ); - *size += strlen("----------------------------\n") + *depth * 3; - if ( *size+10 > *max ) { - *max = (int)(*size + 0.5 * *size); - buf = (char *) XtRealloc( buf, *max ); - } - for ( i=0; i<*depth; i++ ) strcat( buf, " " ); - strcat( buf, "----------------------------\n" ); + status = readFile ( tk, buf, max, fsize, depth); + if (status) return status; (*depth)--; - if ( new->f ) fclose( new->f ); - new->blink->flink = new->flink; - new->flink->blink = new->blink; - free( new ); } } - } } - - } - - } while ( result ); - } - + fclose(fp); + return 0; } -static void readAll ( - char *buf, - int max, - int num, - FILE *fp -) { - -fplistPtr cur; -int size = 0; -int depth = 0; - - g_head = (fplistPtr) calloc( 1, sizeof(fplistType) ); - g_head->f = NULL; - g_head->flink = g_head; - g_head->blink = g_head; - - cur = (fplistPtr) calloc( 1, sizeof(fplistType) ); - cur->f = fp; - - /* link */ - cur->blink = g_head->blink; - g_head->blink->flink = cur; - cur->flink = g_head; - g_head->blink = cur; - - readFile( cur, buf, &max, &size, &depth ); - - cur->blink->flink = cur->flink; - cur->flink->blink = cur->blink; - free( cur ); - - free( g_head ); - -} /************************************************************************** create scroll window for file view @@ -290,11 +200,10 @@ void fileViewWindow(Widget w,int option,Widget menuButton) viewFileUsedLength[option] = 0; viewFileMaxLength[option] = 0; - XtFree(viewFileString[option]); viewFileString[option]=NULL; - XtUnmanageChild(app_shell); + XtUnmanageChild(app_shell); XtVaSetValues(menuButton, XmNset, FALSE, NULL); return; @@ -303,52 +212,78 @@ void fileViewWindow(Widget w,int option,Widget menuButton) XtVaSetValues(menuButton, XmNset, TRUE, NULL); if (stat(filename, &statbuf) == 0) - viewFileUsedLength[operandFile] = statbuf.st_size; + viewFileUsedLength[operandFile] = statbuf.st_size +1; else viewFileUsedLength[operandFile] = 1000000; /* arbitrary file length */ if (statbuf.st_size > 1000000) { XtVaSetValues(menuButton, XmNset, FALSE, NULL); - createDialog(XtParent(w),XmDIALOG_ERROR,filename, &error_file_size[0]); + createDialog(XtParent(w),XmDIALOG_ERROR,filename, error_file_size); return; } - /* allocate space for the file string */ - viewFileMaxLength[operandFile] = MAX(INITIAL_FILE_LENGTH, - 2*viewFileUsedLength[operandFile]); - viewFileString[operandFile] = (char *) - XtCalloc(1,viewFileMaxLength[operandFile]); - if(!viewFileString[operandFile]) { - XtVaSetValues(menuButton, XmNset, FALSE, NULL); - createDialog(XtParent(w),XmDIALOG_ERROR,"no free memory",""); - return; - } - - /* read the file string */ - if ((fp = fopen(filename, "r")) == NULL) { - XtVaSetValues(menuButton, XmNset, FALSE, NULL); - fprintf(stderr,"fileViewWindow: file %s not found\n",filename); - return; /* bail out if no file found */ - } switch (option) { case CONFIG_FILE: - readAll( viewFileString[operandFile], - viewFileUsedLength[operandFile], 1, fp ); + + { + int size = 0; + int depth = 0; + + /* allocate space for the file string */ + viewFileString[operandFile] = (char *) + XtCalloc(1,viewFileUsedLength[operandFile]); + if(!viewFileString[operandFile]) { + XtVaSetValues(menuButton, XmNset, FALSE, NULL); + createDialog(XtParent(w),XmDIALOG_ERROR,"no free memory",""); + return; + } + + readFile(filename, &viewFileString[operandFile], + &viewFileUsedLength[operandFile], &size, &depth); + } + break; default: - fread(viewFileString[operandFile], - viewFileUsedLength[operandFile],1, fp); - break; + + + { + /* allocate space for the file string */ + viewFileMaxLength[operandFile] = MAX(INITIAL_FILE_LENGTH, + 2*viewFileUsedLength[operandFile]); + viewFileString[operandFile] = (char *) + XtCalloc(1,viewFileMaxLength[operandFile]); + if(!viewFileString[operandFile]) { + XtVaSetValues(menuButton, XmNset, FALSE, NULL); + createDialog(XtParent(w),XmDIALOG_ERROR,"no free memory",""); + return; + } + + /* Open the file */ + if ((fp = fopen(filename, "r")) == NULL) { + XtVaSetValues(menuButton, XmNset, FALSE, NULL); + errMsg("Cannot open file view: file %s not found\n",filename); + return; /* bail out if no file found */ + } + + /* read the file */ + fread(viewFileString[operandFile], + viewFileUsedLength[operandFile],1, fp); + + clearerr(fp); + if (fclose(fp)) { + fprintf(stderr, "fileViewWindow: unable to close file %s.\n",filename); + errMsg("Error: unable to close file %s.\n",filename); + } + + break; } - clearerr(fp); - if (fclose(fp)) fprintf(stderr, - "fileViewWindow: unable to close file %s.\n",filename); + } /* create view window dialog */ if (!app_shell) { @@ -585,7 +520,7 @@ void updateLog(int fileIndex,char *string) #endif char *tmp; - int stringLength = strlen(string); + int stringLength = (int)strlen(string); int oldUsedLength = viewFileUsedLength[fileIndex]; @@ -643,12 +578,15 @@ void updateLog(int fileIndex,char *string) /* read the file string */ if ((fp = fopen(filename, "r")) == NULL) { fprintf(stderr,"updateLog: file %s open error.\n",filename); + errMsg("Error opening file %s\n",filename); return; /* bail out if no file found */ } fread(viewFileString[fileIndex], sizeof(char), viewFileUsedLength[fileIndex], fp); - if (fclose(fp)) fprintf(stderr, - "updateLog: unable to close file %s.\n",filename); + if (fclose(fp)) { + fprintf(stderr, "updateLog: unable to close file %s.\n",filename); + errMsg("Error closing file %s\n",filename); + } /* add the file string to the text widget */ XmTextSetString(viewTextWidget[fileIndex], viewFileString[fileIndex]); @@ -717,8 +655,8 @@ void browser_fileViewWindow(Widget w,int option,Widget menuButton) static Widget opmod_shell=NULL; Widget app_shell=NULL,title=0,button,button1; Widget previous; - char sbuf[120]; #ifndef WIN32 + char sbuf[120]; DIR *directory; #endif struct stat statbuf; /* Information on a file. */ @@ -779,8 +717,7 @@ void browser_fileViewWindow(Widget w,int option,Widget menuButton) } #endif if ((fp = fopen(filename, "r")) == NULL) { - sprintf(sbuf, "fileViewWindow: Can't open file %s\n",filename); - createDialog(w,XmDIALOG_WARNING,sbuf," "); + errMsg("Can't open file %s\n",filename); fprintf(stderr, "Can't open file %s\n",filename); return; } @@ -1354,7 +1291,7 @@ XtPointer call_data) XChangeWindowAttributes(display,XtWindow((Widget)client_data),CWCursor,&attrs); XFlush(display); - len=strlen(FSnameshort)-10; /* length of name without "extension" */ + len=(int)strlen(FSnameshort)-10; /* length of name without "extension" */ #ifndef WIN32 while((rdr=readdir(directory))) { @@ -1572,7 +1509,7 @@ XtPointer call_data) } XmTextSetHighlight(text_w,positionSearch,positionSearch+lenSearch, XmHIGHLIGHT_NORMAL); - lenSearch=strlen(search_pat); + lenSearch=(int)strlen(search_pat); positionSearch = XmTextGetCursorPosition(text_w); for(p=&string[positionSearch+1];(p=strchr((const char *)p,*search_pat));p++) if (!strncmp(p, search_pat, lenSearch)) { @@ -1620,7 +1557,7 @@ XtPointer call_data) } XmTextSetHighlight(text_w,positionSearch,positionSearch+lenSearch, XmHIGHLIGHT_NORMAL); - lenSearch=strlen(search_pat); + lenSearch=(int)strlen(search_pat); if((positionSearch=XmTextGetCursorPosition(text_w))>0) { for (p = &string[positionSearch-1]; p >= string; p--) diff --git a/showmask.c b/showmask.c index 26d3b29..7f74447 100644 --- a/showmask.c +++ b/showmask.c @@ -307,17 +307,17 @@ ALINK *area; xmLabelGadgetClass, form, XmNalignment, XmALIGNMENT_END, XmNtopAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 50, + XmNleftAttachment, XmATTACH_FORM, XmNrecomputeSize, True, - (XtPointer)NULL); + NULL); nameTextW = XtVaCreateManagedWidget("nameTextW", xmLabelGadgetClass, form, XmNalignment, XmALIGNMENT_BEGINNING, + XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, nameLabelW, - XmNrightAttachment, XmATTACH_NONE, + XmNrightAttachment, XmATTACH_FORM, XmNrecomputeSize, True, NULL); diff --git a/version.h b/version.h index 5c1c7b6..0b3d94f 100644 --- a/version.h +++ b/version.h @@ -23,9 +23,9 @@ #define ALH_VERSION 1 #define ALH_REVISION 2 -#define ALH_MODIFICATION 26 +#define ALH_MODIFICATION 35 -#define ALH_VERSION_STRING "ALH Version 1.2.26" +#define ALH_VERSION_STRING "ALH Version 1.2.35" #define ALH_CREDITS_STRING \ "Developed at Argonne National Laboratory\n\n" \ @@ -33,6 +33,8 @@ " Mark Anderson, Marty Kraimer,\n" \ " and Albert Kagarmanov\n\n" \ "(With SNS modifications as of 3/07 by\n" \ - "John Sinclair and Kay Kasemir)\n\n" + "John Sinclair and Kay Kasemir)\n" \ + "(With PSI modifications as of May 2012 by\n" \ + "Andreas Luedeke)\n\n" #endif /* INCversionh */ From f1eb13e25241b20f15cd8803907c4d44708326b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schr=C3=B6der?= Date: Thu, 12 Mar 2020 15:29:12 +0100 Subject: [PATCH 27/28] use source format 3.0 quilt --- ...crash-on-startup-with-test.alhConfig.patch | 21 ++ debian/patches/0002-missing-lpthread.patch | 21 ++ debian/patches/0003-change-TOP.patch | 22 ++ debian/patches/0004-BEEPCMD.patch | 212 ++++++++++++++++++ debian/patches/series | 4 + debian/source/format | 1 + debian/source/local-options | 2 + debian/source/options | 1 + 8 files changed, 284 insertions(+) create mode 100644 debian/patches/0001-workaround-crash-on-startup-with-test.alhConfig.patch create mode 100644 debian/patches/0002-missing-lpthread.patch create mode 100644 debian/patches/0003-change-TOP.patch create mode 100644 debian/patches/0004-BEEPCMD.patch create mode 100644 debian/patches/series create mode 100644 debian/source/format create mode 100644 debian/source/local-options create mode 100644 debian/source/options diff --git a/debian/patches/0001-workaround-crash-on-startup-with-test.alhConfig.patch b/debian/patches/0001-workaround-crash-on-startup-with-test.alhConfig.patch new file mode 100644 index 0000000..dbb06b6 --- /dev/null +++ b/debian/patches/0001-workaround-crash-on-startup-with-test.alhConfig.patch @@ -0,0 +1,21 @@ +From: Michael Davidsaver +Date: Tue, 9 Oct 2012 18:58:15 -0400 +Subject: workaround crash on startup with test.alhConfig + +--- + axRunW.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/axRunW.c b/axRunW.c +index a2b60e5..f3dd0b5 100644 +--- a/axRunW.c ++++ b/axRunW.c +@@ -381,7 +381,7 @@ void silenceCurrentReset(void *area) + { + if (psetup.silenceCurrent) { + psetup.silenceCurrent = FALSE; +- if (((ALINK*)area)->silenceCurrent) { ++ if (area && ((ALINK*)area)->silenceCurrent) { + XmToggleButtonGadgetSetState(((ALINK*)area)->silenceCurrent, + FALSE,FALSE); + } diff --git a/debian/patches/0002-missing-lpthread.patch b/debian/patches/0002-missing-lpthread.patch new file mode 100644 index 0000000..00257dd --- /dev/null +++ b/debian/patches/0002-missing-lpthread.patch @@ -0,0 +1,21 @@ +From: Michael Davidsaver +Date: Thu, 10 Mar 2016 19:54:31 -0500 +Subject: missing -lpthread + +--- + Makefile | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Makefile b/Makefile +index d8848e3..70a2781 100755 +--- a/Makefile ++++ b/Makefile +@@ -185,6 +185,8 @@ X11_DIR = $(X11_LIB) + + RCS_WIN32 += alh.rc + ++PROD_SYS_LIBS += pthread ++ + include $(TOP)/configure/RULES + + alh.res:../alh.ico diff --git a/debian/patches/0003-change-TOP.patch b/debian/patches/0003-change-TOP.patch new file mode 100644 index 0000000..0a7612d --- /dev/null +++ b/debian/patches/0003-change-TOP.patch @@ -0,0 +1,22 @@ +From: =?utf-8?q?Christoph_Schr=C3=B6der?= + +Date: Wed, 11 Mar 2020 14:10:53 +0100 +Subject: change TOP + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 70a2781..6547e49 100755 +--- a/Makefile ++++ b/Makefile +@@ -15,7 +15,7 @@ + # + # Makefile,v 1.22 2013/04/22 16:07:23 jba Exp + # +-TOP=../.. ++TOP=. + include $(TOP)/configure/CONFIG + + #=========================== diff --git a/debian/patches/0004-BEEPCMD.patch b/debian/patches/0004-BEEPCMD.patch new file mode 100644 index 0000000..fc395e4 --- /dev/null +++ b/debian/patches/0004-BEEPCMD.patch @@ -0,0 +1,212 @@ +From: Michael Davidsaver +Date: Tue, 9 Oct 2012 18:57:57 -0400 +Subject: BEEPCMD + +Add option to run arbitrary shell command instead of X bell + +Command does not run from gui thread. Command will not +be run concurrently. +--- + alConfig.c | 33 +++++++++++++++++ + alh.h | 1 + + os/default/alAudio.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++-- + test.alhConfig | 1 + + 4 files changed, 132 insertions(+), 3 deletions(-) + +diff --git a/alConfig.c b/alConfig.c +index 50d0526..0d248be 100644 +--- a/alConfig.c ++++ b/alConfig.c +@@ -444,6 +444,37 @@ int context,int caConnect,struct mainGroup *pmainGroup) + return; + } + ++ if (strncmp(&buf[1],"BEEPCMD",7)==0) { ++ unsigned int start=8, end = strlen(buf) - 1; ++ ++ /* skip leading whitespace to find start of command */ ++ for(; start<=end && (buf[start]=='\t' || buf[start]==' '); start++) {} ++ ++ if(start>end) { ++ print_error(buf, "expected argument after BEEPCMD"); ++ return; ++ } ++ ++ /* back track to trim trailing whitespace */ ++ for(; end>=start && (buf[end]=='\0' || isspace(buf[end])); end--) {} ++ ++ if(end>start) { ++ if(psetup.beepCmd) ++ free(psetup.beepCmd); ++ psetup.beepCmd = malloc(end-start+2); ++ if(!psetup.beepCmd) { ++ print_error(buf, "Not enough memory for BEEPCMD"); ++ } else { ++ memcpy(psetup.beepCmd, &buf[start], end-start+1); ++ psetup.beepCmd[end-start+1] = '\0'; ++ } ++ } else { ++ print_error(buf, "Missing argument for BEEPCMD"); ++ } ++ ++ return; ++ } ++ + if (strncmp(&buf[1],"HEARTBEATPV",11)==0) { /*HEARTBEATPV*/ + + if (pmainGroup->heartbeatPV.name) return; +@@ -777,6 +808,8 @@ void alWriteConfig(char *filename,struct mainGroup *pmainGroup) + if (!fw) return; + if (psetup.beepSevr > 1) + fprintf(fw,"$BEEPSEVERITY %s\n",alhAlarmSeverityString[psetup.beepSevr]); ++ if (psetup.beepCmd) ++ fprintf(fw,"$BEEPCMD %s\n", psetup.beepCmd); + /*alWriteGroupConfig(fw,(SLIST *)&(pmainGroup->p1stgroup));*/ + alWriteGroupConfig(fw,(SLIST *)pmainGroup); + fclose(fw); +diff --git a/alh.h b/alh.h +index 37feac8..f6f8928 100644 +--- a/alh.h ++++ b/alh.h +@@ -181,6 +181,7 @@ struct setup { + char logFile[NAMEDEFAULT_SIZE]; /* alarm log file name */ + char opModFile[NAMEDEFAULT_SIZE]; /* opMod log file name */ + char saveFile[NAMEDEFAULT_SIZE]; /* save config file name */ ++ char *beepCmd; /* Optional command in place of X bell*/ + char soundFile[NAMEDEFAULT_SIZE]; /* sound wav file name */ + char lockFileBase[NAMEDEFAULT_SIZE]; /* lock files basename */ + short silenceForever; /* 1 - beepoff forever is true */ +diff --git a/os/default/alAudio.c b/os/default/alAudio.c +index c6e36ab..85ad91e 100644 +--- a/os/default/alAudio.c ++++ b/os/default/alAudio.c +@@ -18,13 +18,88 @@ + * + */ + ++#include + #include ++#include ++#include ++#include + + #include + #include + + #include "alh.h" + ++static pthread_mutex_t beep_lock = PTHREAD_MUTEX_INITIALIZER; ++static pthread_cond_t beep_wake = PTHREAD_COND_INITIALIZER; ++static pthread_once_t beep_setup = PTHREAD_ONCE_INIT; ++/* states: -2 done, -1 shutdown, 0 idle, 1 playing, 2 request play */ ++static int beeping = 0; ++static pthread_t beeper; ++ ++#define LOCK() assert(pthread_mutex_lock(&beep_lock)==0) ++#define UNLOCK() assert(pthread_mutex_unlock(&beep_lock)==0) ++ ++static void beeper_shutdown(void) ++{ ++ /* request shutdown and spin until beeper thread stops */ ++ LOCK(); ++ beeping = -1; ++ while(beeping!=-2) { ++ UNLOCK(); ++ pthread_cond_broadcast(&beep_wake); ++ usleep(10000); /* 10ms */ ++ LOCK(); ++ } ++ /* thread is stopped now */ ++ free(psetup.beepCmd); ++ psetup.beepCmd = NULL; ++ ++ UNLOCK(); ++} ++ ++static void* beeper_thread(void* junk) ++{ ++ LOCK(); ++ ++ atexit(&beeper_shutdown); ++ ++ while(beeping>=0) { ++ ++ assert(pthread_cond_wait(&beep_wake, &beep_lock)==0); ++ ++ if(beeping==2) { ++ beeping=1; ++ UNLOCK(); ++ ++ system(psetup.beepCmd); ++ ++ LOCK(); ++ /* be careful not to overwrite the shutdown command */ ++ if(beeping==1) ++ beeping=0; ++ } ++ } ++ UNLOCK(); ++ beeping=-2; ++ return NULL; ++} ++ ++static void setup(void) ++{ ++ if(!psetup.beepCmd) ++ return; ++ ++ if(pthread_create(&beeper, NULL, &beeper_thread, NULL)) { ++ printf("Error creating beeper thread!\n"); ++ /* clear beepCmd so that future calls to alBeep() will ++ * call XBell(). ++ */ ++ free(psetup.beepCmd); ++ psetup.beepCmd = NULL; ++ return; ++ } ++} ++ + /* Audio device not implemented */ + + /****************************************************** +@@ -32,9 +107,28 @@ + ******************************************************/ + void alBeep(Display *displayBB) + { +- /* system("play /path/to/beep.wav"); */ +- XkbBell(displayBB,None,0,None); +- return; ++ pthread_once(&beep_setup, &setup); ++ ++ if(!psetup.beepCmd) { ++ /* system("play /path/to/beep.wav"); */ ++ XkbBell(displayBB,None,0,None); ++ return; ++ } else { ++ LOCK(); ++ ++ /* wakeup for new command. ++ * also if still waiting for wakeup ++ * if beeper didn't start fast enough ++ * on the previous call. ++ */ ++ if(beeping==0 || beeping==2) { ++ beeping=2; ++ pthread_cond_broadcast(&beep_wake); ++ } ++ ++ UNLOCK(); ++ return; ++ } + } + + +diff --git a/test.alhConfig b/test.alhConfig +index 2475da1..84c96c8 100644 +--- a/test.alhConfig ++++ b/test.alhConfig +@@ -1,3 +1,4 @@ ++$BEEPCMD sleep 5;date -R >> alhtest + $BEEPSEVERITY MAJOR + GROUP NULL JBA_TEST_MAIN_GROUP + $COMMAND xload diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..daf61bb --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,4 @@ +0001-workaround-crash-on-startup-with-test.alhConfig.patch +0002-missing-lpthread.patch +0003-change-TOP.patch +0004-BEEPCMD.patch diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/source/local-options b/debian/source/local-options new file mode 100644 index 0000000..9cdfca9 --- /dev/null +++ b/debian/source/local-options @@ -0,0 +1,2 @@ +unapply-patches +abort-on-upstream-changes diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 0000000..62d9178 --- /dev/null +++ b/debian/source/options @@ -0,0 +1 @@ +compression-level = 9 From 0e6974b4d60afaf2cdda4d841349f50fc094fa4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schr=C3=B6der?= Date: Thu, 12 Mar 2020 15:34:22 +0100 Subject: [PATCH 28/28] 1.2.35-1 --- debian/changelog | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/debian/changelog b/debian/changelog index b8273ca..f6282a4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,16 @@ +alh (1.2.35-1) unstable; urgency=medium + + * remove libxp-dev dependency + * set compat level to 9 + * epics-debhelper>=8.12 uses LINKER_USE_RPATH instead of USE_RPATH + * update dependencies + * fix i386 build + * DEB_DH_STRIP_ARGS is deprecated + * New upstream version 1.2.35 + * use source format 3.0 quilt + + -- Christoph Schröder Thu, 12 Mar 2020 15:33:33 +0100 + alh (1.2.26-3) unstable; urgency=medium * Build against Base 3.15.3