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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 |