summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author(no author)2006-09-28 15:13:27 +0000
committer(no author)2006-09-28 15:13:27 +0000
commit40f683f8e11e217c3c27bf6e8606aa7bcb88f908 (patch)
tree10a29c505f3668d27091d678232a9d6ac8c2a4d8
parent1360fa0dcdc84c0d53a31d590482a895376cfdd8 (diff)
downloadivycontrolpanel-debian_sarge_branch.zip
ivycontrolpanel-debian_sarge_branch.tar.gz
ivycontrolpanel-debian_sarge_branch.tar.bz2
ivycontrolpanel-debian_sarge_branch.tar.xz
This commit was manufactured by cvs2svn to create branchdebian_sarge_branch
'debian_sarge_branch'.
-rw-r--r--debian/changelog29
-rw-r--r--debian/control10
-rwxr-xr-xdebian/rules41
-rwxr-xr-xicp.prj9
-rw-r--r--src/Agent.pm589
-rw-r--r--src/IvyIO.pm70
-rwxr-xr-xsrc/ivycontrolpanel200
7 files changed, 569 insertions, 379 deletions
diff --git a/debian/changelog b/debian/changelog
index b3a89c5..ff0744a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,32 @@
+ivycontrolpanel (2.3) unstable; urgency=low
+
+ * Ajout d'un mécanisme de polling pour détecter les problèmes de
+ performance. Cette fonctionnalité nécessite Ivy v4.18.
+ (contribution de JP Imbert)
+
+ -- Daniel Etienne <etienne@cena.fr> Thu, 28 Sep 2006 15:49:19 +0200
+
+ivycontrolpanel (2.2) unstable; urgency=low
+
+ * Optimisation des regexps ivy (correction d'un bug introduit en v2.0)
+
+ -- Daniel Etienne <etienne@cena.fr> Wed, 19 Apr 2006 11:23:03 +0200
+
+ivycontrolpanel (2.1) unstable; urgency=low
+
+ * Ajout de l'option -smallsize: affichage en 640x480.
+ * Ajout de l'option -position.
+
+ -- Cedirc Mariot <mariot@cena.fr> Wed, 26 Nov 2003 14:17:18 +0200
+
+ivycontrolpanel (2.0) unstable; urgency=low
+
+ * Reconception IHM : le widget Zinc est abandonné au profit de widgets
+ plus adaptés.
+ * Reconception graphique
+
+ -- Daniel Etienne <etienne@cena.fr> Wed, 7 May 2003 17:47:18 +0200
+
ivycontrolpanel (1.9) unstable; urgency=low
* passage à zinc-perl 3.2.6a1 ou >= 3.2.6h
diff --git a/debian/control b/debian/control
index c7fbfb9..68f5696 100644
--- a/debian/control
+++ b/debian/control
@@ -1,16 +1,16 @@
Source: ivycontrolpanel
Section: devel
Priority: extra
-Maintainer: Christophe Mertz <mertz@cena.fr>
-Standards-Version: 2.3.0.0
+Maintainer: Daniel Etienne <etienne@cena.fr>
+Standards-Version: 3.2.1
Package: ivycontrolpanel
Architecture: all
-Depends: perl5, ivy-perl (>= 4.11b), perl-tk, zinc-perl (= 3.2.6a1) | zinc-perl (>= 3.2.6h)
+Depends: perl5, ivy-perl (>= 4.11b), perl-tk, ivylaunch
Description: Monitoring of ivy based applications
Monitoring of ivy agent (ie ivy based applications).
It monitors applications launched on a given ivy port number.
- (Specific use for Toccata demos).
It allows restarting agents described in a configuration file.
- It also offers some simulation start, stop and pause.
+ It also offers some simulation start, stop and pause (specific
+ use for Toccata trafic generator)
diff --git a/debian/rules b/debian/rules
index 0204846..74aba0a 100755
--- a/debian/rules
+++ b/debian/rules
@@ -6,57 +6,48 @@ package=ivycontrolpanel
build:
$(checkdir)
- pod2man src/$(package) > doc/$(package).1
touch build
clean:
$(checkdir)
-rm -f build
+ -$(MAKE) clean
-rm -f `find . -name "*~"`
-rm -rf debian/tmp debian/files* core debian/substvars
-binary-indep: checkroot build
+binary-indep: checkroot build
+ $(checkdir)
+# There are no architecture-independent files to be uploaded
+# generated by this package. If there were any they would be
+# made here.
+
+binary-arch: checkroot build
$(checkdir)
-rm -rf debian/tmp
+ install -d debian/tmp
install -d debian/tmp/usr/bin
- install -d debian/tmp/usr/
install -d debian/tmp/usr/lib/$(package)
install -d debian/tmp/usr/share/$(package)
- install -d debian/tmp/usr/share/man/man1
-
- pod2man src/$(package) > debian/tmp/usr/share/man/man1/$(package).1
- install -m755 src/ivycontrolpanel debian/tmp/usr/bin/$(package)
- for f in src/*.pm; do \
- install -m644 $$f debian/tmp/usr/lib/$(package); \
- done
- for f in images/*; do \
- install -m644 $$f debian/tmp/usr/share/$(package); \
- done
+ install -m755 src/$(package) debian/tmp/usr/bin/$(package)
+ install -m644 src/*.pm debian/tmp/usr/lib/$(package)
+ install -m644 images/*.bmp debian/tmp/usr/share/$(package)
# Must have debmake installed for this to work. Otherwise please copy
# /usr/bin/debstd into the debian directory and change debstd to debian/debstd
- debstd debian/copyright debian/changelog doc/*.1 doc/ivycontrolpanel.gif
- dpkg-gencontrol -isp
+ pod2man src/$(package) > $(package).1
+ debstd
+ dpkg-gencontrol
chown -R root.root debian/tmp
chmod -R go=rX debian/tmp
dpkg --build debian/tmp ..
-binary-arch: checkroot build
- $(checkdir)
-# There are no architecture-independent files to be uploaded
-# generated by this package. If there were any they would be
-# made here.
-
define checkdir
test -f debian/rules
endef
-# Below here is fairly generic really
-
-binary: binary-indep binary-arch
+binary: binary-indep binary-arch
checkroot:
$(checkdir)
test root = "`whoami`"
.PHONY: binary binary-arch binary-indep clean checkroot
-
diff --git a/icp.prj b/icp.prj
new file mode 100755
index 0000000..fbc6fe1
--- /dev/null
+++ b/icp.prj
@@ -0,0 +1,9 @@
+[Project ID]
+Signature=UE Proj: v.1
+[Files]
+0=E:\Travail\ivycontrolpanel\debian\changelog
+1=E:\Travail\ivycontrolpanel\src\Agent.pm
+2=E:\Travail\ivycontrolpanel\src\ivycontrolpanel
+3=E:\Travail\ivycontrolpanel\src\IvyIO.pm
+[Group]
+0=
diff --git a/src/Agent.pm b/src/Agent.pm
index 75cf616..d1a6fc1 100644
--- a/src/Agent.pm
+++ b/src/Agent.pm
@@ -13,122 +13,138 @@ use strict;
#
#----------------------------------------------------------------------
my ($x0, $y0, $wmax, $dx, $dy, $cmin, $rmax, @matrix, @hosts, $tempo_id,
- $mw, $bg, $fg, $selcolor, $hlbg, $darkbg, $fontspec, @fontspec,
- $on_img, $off_img, %instances, @instances, $bus,
- $hosts_tl, $selected_host, $preselected_host);
+ $mw, $bg, $fg, $selcolor, $pbcolor, $hlbg, $darkbg, $fontspec, @fontspec,
+ $on_img, $off_img, $pb_img, %instances, @instances, $bus, $coef,
+ $hosts_tl, $selected_host, $preselected_host, $pingThreshold);
# configure the class : graphic parameters, geometry and ivy bus
sub configure {
- shift;
- ($mw, $bg, $fg, $selcolor, $hlbg, $darkbg,
- $fontspec, $x0, $y0, $wmax, $dy, $cmin, $rmax, $bus) = @_;
- @fontspec = @$fontspec if $fontspec;
- $off_img = $mw->Bitmap('off', -file => Tk::findINC('led.bmp'),
- -foreground => $bg);
- $on_img = $mw->Bitmap('on', -file => Tk::findINC('led.bmp'),
- -foreground => $selcolor);
- &_resetmatrix;
-
+ shift;
+ ($mw, $bg, $fg, $selcolor, $pbcolor, $hlbg, $darkbg,
+ $fontspec, $x0, $y0, $wmax, $dy, $cmin, $rmax, $bus, $coef, $pingThreshold) = @_;
+ @fontspec = @$fontspec if $fontspec;
+ $off_img = $mw->Bitmap('off', -file => Tk::findINC('led.bmp'),
+ -foreground => $bg);
+ $pb_img = $mw->Bitmap('pb', -file => Tk::findINC('led.bmp'),
+ -foreground => $pbcolor);
+ $on_img = $mw->Bitmap('on', -file => Tk::findINC('led.bmp'),
+ -foreground => $selcolor);
+ &_resetmatrix;
+
} # end configure
# kill an named agent
sub kill {
- my ($class, $appname) = @_;
- IvyIO::kill($appname);
+ my ($class, $appname) = @_;
+ IvyIO::kill($appname);
} # end kill;
# kill all agents
sub killall {
- my ($class) = @_;
- my $nb = 0;
- for(@instances) {
- if ($_->{status} > 0) {
- IvyIO::kill($_->{appname});
- $nb++;
- }
- }
- return $nb;
+ my ($class) = @_;
+ my $nb = 0;
+ for(@instances) {
+ if ($_->{status} > 0) {
+ IvyIO::kill($_->{appname});
+ $nb++;
+ }
+ }
+ return $nb;
} # end killall;
# set usable hosts list for executing agents
sub hosts {
- shift;
- @hosts = @_;
+ shift;
+ @hosts = @_;
} # end hosts
# callback called when an agent connects
sub connect {
- my ($class, $appname, $host) = @_;
- if ($instances{$appname}) {
- if ($instances{$appname}->{status} == 1) {
- $instances{$appname}->addtwin;
- } else {
- $instances{$appname}->on;
- }
- } else {
- $class->new($appname, $host, undef, undef, 1);
- }
+ my ($class, $appname, $host) = @_;
+ if ($instances{$appname}) {
+ if ($instances{$appname}->{status} == 1) {
+ $instances{$appname}->addtwin;
+ } else {
+ $instances{$appname}->on;
+ }
+ } else {
+ $class->new($appname, $host, undef, undef, 1);
+ }
} # end connect
# callback called when an agent disconnects
sub disconnect {
- my ($class, $appname, $host) = @_;
- if ($instances{$appname}) {
- if ($instances{$appname}->{number} > 1) {
- $instances{$appname}->removetwin;
- } else {
- $instances{$appname}->off;
- }
- } else {
- $class->new($appname, $host, undef, undef, 0);
- }
+ my ($class, $appname, $host) = @_;
+ if ($instances{$appname}) {
+ if ($instances{$appname}->{number} > 1) {
+ $instances{$appname}->removetwin;
+ } else {
+ $instances{$appname}->off;
+ }
+ } else {
+ $class->new($appname, $host, undef, undef, 0);
+ }
} # end disconnect
+# callback called when a ping/pong is received
+sub pingcb {
+ my ($class, $appname, $host, $pingtime) = @_;
+ #print "pingtime=$pingtime\n";
+ if ($instances{$appname}) {
+ # if pingtime > $pingThreshold status is changed
+ if ($pingtime > $pingThreshold) {
+ $instances{$appname}->pb;
+ } elsif ($instances{$appname}->{status} == 2) {
+ $instances{$appname}->nopb;
+ }
+ }
+} # end pingcb
+
# class constructor
sub new {
- my ($class, $appname, $host, $command, $params, $status) = @_;
- if ($instances{$appname}) {
- $instances{$appname}->addtwin;
- return;
- }
- my $self = {};
- bless $self;
-
- # set object attributes
- $self->{appname} = $appname;
- $self->{status} = $status;
- $self->{host} = $host;
- $self->{command} = $command;
- $self->{params} = $params;
- $self->{number} = 1;
- $self->{led} = undef;
- $self->{label} = undef;
-
- # reset positions before adding new instance
- if (@instances >= ($rmax*$cmin)) {
- $cmin++;
- $class->_updatepositions;
- }
- # set class variables
- $instances{$appname} = $self;
- push(@instances, $self);
-
- # graphical updates
- $self->createlabel;
- $self->on if $status;
-
- $class->_alphabeticsort();
-
- return $self;
+ my ($class, $appname, $host, $command, $params, $status) = @_;
+ if ($instances{$appname}) {
+ $instances{$appname}->addtwin;
+ return;
+ }
+ my $self = {};
+ bless $self;
+
+ # set object attributes
+ $self->{appname} = $appname;
+ $self->{status} = $status;
+ $self->{host} = $host;
+ $self->{command} = $command;
+ $self->{params} = $params;
+ $self->{number} = 1;
+ $self->{led} = undef;
+ $self->{label} = undef;
+
+ # reset positions before adding new instance
+ if (@instances >= ($rmax*$cmin)) {
+ $cmin++;
+ $class->_updatepositions;
+ }
+ # set class variables
+ $instances{$appname} = $self;
+ push(@instances, $self);
+
+ # graphical updates
+ $self->createlabel;
+ $self->on if $status;
+
+ $class->_alphabeticsort();
+
+ return $self;
} # end new
@@ -142,139 +158,166 @@ sub new {
# called when several agent instances are detected
sub addtwin {
- my $self = shift;
- $self->{number}++;
- $self->{label}->configure(-text => $self->formatlabel);
+ my $self = shift;
+ $self->{number}++;
+ $self->{label}->configure(-text => $self->formatlabel);
} # end addtwin
# called when an instance of a not single agent dies
sub removetwin {
- my $self = shift;
- return if $self->{number} == 1;
- $self->{number}--;
- $self->{label}->configure(-text => $self->formatlabel);
+ my $self = shift;
+ return if $self->{number} == 1;
+ $self->{number}--;
+ $self->{label}->configure(-text => $self->formatlabel);
} # end addtwin
# graphical effect when a known agent connects
sub on {
- my $self = shift;
- $self->{status} = 1;
- $self->{led}->configure(-image => $on_img);
- $self->{label}->raise;
- $self->{label}->configure(-highlightthicknes => 2);
- $tempo_id = $mw->after(3000, sub {
- $self->{label}->configure(highlightthicknes => 0);
- });
+ my $self = shift;
+ $self->nopb;
+ $self->{label}->raise;
+ $self->{label}->configure(-highlightthicknes => 2);
+ $tempo_id = $mw->after(2000, sub {
+ $self->{label}->configure(-highlightthicknes => 0);
+ });
} # end on
# graphical effect when a known agent disconnects
sub off {
- my $self = shift;
- $self->{status} = 0;
- $self->{led}->configure(-image => $off_img);
+ my $self = shift;
+ $self->{status} = 0;
+ $self->{led}->configure(-image => $off_img);
} # end off
+# graphical effect when a know agent has a ping problem (latency)
+
+sub pb {
+ my $self = shift;
+ $self->{status} = 2;
+ $self->{led}->configure(-image => $pb_img);
+ my $i = 0;
+ my $id;
+ $id = $mw->repeat(100, sub {
+ if ($i == 4) {
+ $mw->afterCancel($id);
+ } elsif ($i % 2 == 0) {
+ $self->{led}->configure(-image => $on_img);
+ } else {
+ $self->{led}->configure(-image => $pb_img);
+ }
+ $i++;
+ });
+
+} # end pb
+
+sub nopb {
+ my $self = shift;
+ $self->{status} = 1;
+ $self->{led}->configure(-image => $on_img);
+
+} # end pb
+
# label placement
sub setposition {
- my $self = shift;
- my ($r, $c);
- for (my $i=0; $i<@matrix; $i++) {
- for (my $j=0; $j<=$#{$matrix[$i]}; $j++) {
- unless ($matrix[$i][$j]->[0]) {
- ($r, $c) = ($i, $j);
- last;
- }
- }
- last if defined $r;
- }
- $matrix[$r][$c]->[0] = $self;
- my ($x, $y) = ($matrix[$r][$c]->[1], $matrix[$r][$c]->[2]);
- my $y2 = $y - 5;
- $y2 -= 12 if ($self->{label}->cget(-text) =~ /\n/);
-
- if ($self->{command}) {
- $self->{led}->configure(-highlightthickness => 6);
- $self->{led}->place(-x => $x+3, -y => $y+3);
- } else {
- $self->{led}->configure(-highlightthickness => 2);
- $self->{led}->place(-x => $x+6, -y => $y+6);
- }
- $self->{label}->place(-x => $x + 38, -y => $y2);
+ my $self = shift;
+ my ($r, $c);
+ for (my $i=0; $i<@matrix; $i++) {
+ for (my $j=0; $j<=$#{$matrix[$i]}; $j++) {
+ unless ($matrix[$i][$j]->[0]) {
+ ($r, $c) = ($i, $j);
+ last;
+ }
+ }
+ last if defined $r;
+ }
+ $matrix[$r][$c]->[0] = $self;
+ my ($x, $y) = ($matrix[$r][$c]->[1], $matrix[$r][$c]->[2]);
+ my $y2 = $y - 5*$coef;
+ $y2 -= 12*$coef if ($self->{label}->cget(-text) =~ /\n/);
+
+ if ($self->{command}) {
+ $self->{led}->configure(-highlightthickness => 6*$coef);
+ $self->{led}->place(-x => $x+3*$coef, -y => $y+3*$coef);
+ } else {
+ $self->{led}->configure(-highlightthickness => 2*$coef);
+ $self->{led}->place(-x => $x+6*$coef, -y => $y+6*$coef);
+ }
+ $self->{label}->place(-x => $x + 38, -y => $y2);
} # end setposition
# label creation
sub createlabel {
- my ($self) = @_;
- $self->{led} =
- $mw->Label(-image => $off_img,
- -highlightbackground => $hlbg,
- -borderwidth => 0,
- );
- $self->{label} =
- $mw->Label(-text => $self->formatlabel,
- -pady => 10,
- -justify => 'left',
- -relief => 'flat',
- -highlightthickness => 0,
- -background => $darkbg,
- -foreground => $fg,
- @fontspec,
- );
- $self->{led}->bind('<1>', [\&_cbOnPress, $self]);
- $self->{label}->bind('<1>', [\&_cbOnPress, $self]);
+ my ($self) = @_;
+ $self->{led} =
+ $mw->Label(-image => $off_img,
+ -highlightbackground => $hlbg,
+ -borderwidth => 0,
+ );
+ $self->{label} =
+ $mw->Label(-text => $self->formatlabel,
+ -pady => 10*$coef,
+ -justify => 'left',
+ -relief => 'flat',
+ -highlightthickness => 0,
+ -background => $darkbg,
+ -foreground => $fg,
+ @fontspec,
+ );
+ $self->{led}->bind('<1>', [\&_cbOnPress, $self]);
+ $self->{label}->bind('<1>', [\&_cbOnPress, $self]);
} # end createlabel
# label format : affects too long labels and not single agents
sub formatlabel {
- my ($self) = @_;
- my $im_width = 38;
- my $dx = $dx - $im_width;
- my $appname = $self->{appname};
- # for not single agents
- $appname = '['.$self->{number}.'] '.$appname if $self->{number} > 1;
- my $width = $mw->fontMeasure($fontspec[1], $appname);
- my $appnametext;
- # for too long names
- while ($width > 2*$dx) {
- $appname = substr($appname, 0, -1);
- $width = $mw->fontMeasure($fontspec[1], $appname);
- }
- if ($width > $dx) {
- my $hlen = int(length($appname)/2);
- my @fields = split(/:/, $appname);
- if (@fields > 1) {
- my $len = 0;
- my $imax = -1;
- for (my $i=0; $i<@fields; $i++) {
- $len += length($fields[$i]);
- if ($len > $hlen) {
- $imax = $i - 1;
- last;
- }
- }
- if ($imax >= 0) {
- $appnametext = join(':', (@fields)[0..$imax])."\n".
- join(':', (@fields)[$imax+1..$#fields]);
- }
- }
- $appnametext = substr($appname, 0, $hlen)."\n".substr($appname, $hlen)
- unless $appnametext;
- } else {
- my @fields = split(/:/, $appname);
- if (@fields > 1) {
- $appnametext = $fields[0].":\n ".join(':', (@fields)[1..$#fields]);
- }
- }
- $appnametext = $appname unless $appnametext;
- return $appnametext;
+ my ($self) = @_;
+ my $im_width = 38;
+ my $dx = $dx - $im_width;
+ my $appname = $self->{appname};
+ # for not single agents
+ $appname = '['.$self->{number}.'] '.$appname if $self->{number} > 1;
+ my $width = $mw->fontMeasure($fontspec[1], $appname);
+ my $appnametext;
+ # for too long names
+ while ($width > 2*$dx) {
+ $appname = substr($appname, 0, -1);
+ $width = $mw->fontMeasure($fontspec[1], $appname);
+ }
+ if ($width > $dx) {
+ my $hlen = int(length($appname)/2);
+ my @fields = split(/:/, $appname);
+ if (@fields > 1) {
+ my $len = 0;
+ my $imax = -1;
+ for (my $i=0; $i<@fields; $i++) {
+ $len += length($fields[$i]);
+ if ($len > $hlen) {
+ $imax = $i - 1;
+ last;
+ }
+ }
+ if ($imax >= 0) {
+ $appnametext = join(':', (@fields)[0..$imax])."\n".
+ join(':', (@fields)[$imax+1..$#fields]);
+ }
+ }
+ $appnametext = substr($appname, 0, $hlen)."\n".substr($appname, $hlen)
+ unless $appnametext;
+ } else {
+ my @fields = split(/:/, $appname);
+ if (@fields > 1) {
+ $appnametext = $fields[0].":\n ".join(':', (@fields)[1..$#fields]);
+ }
+ }
+ $appnametext = $appname unless $appnametext;
+ return $appnametext;
} # end formatlabel
@@ -285,120 +328,120 @@ sub formatlabel {
#
#----------------------------------------------------------------------
sub _resetmatrix {
- $dx = $wmax/$cmin;
- for(my $r=0; $r<$rmax; $r++) {
- for(my $c=0; $c<$cmin; $c++) {
- $matrix[$r][$c] = [undef, $x0 + $c*$dx, $y0 + $r*$dy];
- }
- }
+ $dx = $wmax/$cmin;
+ for(my $r=0; $r<$rmax; $r++) {
+ for(my $c=0; $c<$cmin; $c++) {
+ $matrix[$r][$c] = [undef, $x0 + $c*$dx, $y0 + $r*$dy];
+ }
+ }
} # end _resetmatrix
sub _updatepositions {
- &_resetmatrix;
- for (@instances) {
- $_->setposition();
- $_->{label}->configure(-text => $_->formatlabel);
- }
+ &_resetmatrix;
+ for (@instances) {
+ $_->setposition();
+ $_->{label}->configure(-text => $_->formatlabel);
+ }
} # end _updatepositions
sub _alphabeticsort {
- &_resetmatrix;
- for (sort {uc($a->{appname}) cmp uc($b->{appname})} @instances) {
- $_->setposition();
- }
+ &_resetmatrix;
+ for (sort {uc($a->{appname}) cmp uc($b->{appname})} @instances) {
+ $_->setposition();
+ }
} # end _alphabeticsort
# callback invoked when user press on label
sub _cbOnPress {
- shift;
- my $self = shift;
- $self->{label}->configure(-foreground => $hlbg);
- if ($self->{status} == 1) {
- IvyIO::kill($self->{appname});
- $mw->after(400, sub {$self->{label}->configure(-foreground => $fg);});
- } elsif ($self->{command}) {
- my ($x, $y) = ($self->{label}->rootx, $self->{label}->rooty);
- my $host = &_hostsmenu($x, $y, $self->{host});
- $self->{label}->configure(-foreground => $fg);
- return unless $host;
- FugueConfig::launchAgent($self->{appname}, $host,
- $self->{command}, $self->{params}, $bus);
- print "$self->{appname} launched\n";
- } else {
- $mw->bell;
- $mw->after(400, sub {$self->{label}->configure(-foreground => $fg);});
- }
+ shift;
+ my $self = shift;
+ $self->{label}->configure(-foreground => $hlbg);
+ if ($self->{status} > 0) {
+ IvyIO::kill($self->{appname});
+ $mw->after(400, sub {$self->{label}->configure(-foreground => $fg);});
+ } elsif ($self->{command}) {
+ my ($x, $y) = ($self->{label}->rootx, $self->{label}->rooty);
+ my $host = &_hostsmenu($x, $y, $self->{host});
+ $self->{label}->configure(-foreground => $fg);
+ return unless $host;
+ FugueConfig::launchAgent($self->{appname}, $host,
+ $self->{command}, $self->{params}, $bus);
+ print "$self->{appname} launched\n";
+ } else {
+ $mw->bell;
+ $mw->after(400, sub {$self->{label}->configure(-foreground => $fg);});
+ }
} # end _cbOnPress
# create and show hosts menu
sub _hostsmenu {
- my $x = shift;
- my $y = shift;
- $x += 50;
-
- my $preselected_host = shift;
- return $preselected_host if @hosts <= 1;
- $hosts_tl->destroy if Tk::Exists($hosts_tl);
- $hosts_tl = $mw->Toplevel(-background => $darkbg);
- $hosts_tl->resizable(0,0);
- $hosts_tl->title('ivycontrolpanel');
- my $hosts_fm = $hosts_tl->Frame(-background => $darkbg,
- -highlightthickness => 3,
- -highlightbackground => $hlbg,
- )->pack(-side => 'top', -padx => 0, -pady => 0);
- my @lattr = (-padx => 10,
- -pady => 10,
- -relief => 'flat',
- -highlightthickness => 0,
- -background => $darkbg,
- -foreground => $fg,
- -borderwidth => 0,
- @fontspec);
- my @battr = (@lattr,
- -width => 4, -height => 1,
- -highlightthickness => 3,
- -highlightbackground => $hlbg,
- -activebackground => $darkbg,
- -activeforeground => $fg,
- );
- my @rattr = (@lattr,
- -activebackground => $darkbg,
- -activeforeground => $fg,
- -selectcolor => $selcolor);
-
- $hosts_fm->Label(@lattr, -text => "restart on :"
- )->pack(-side => 'top', -padx => 20, -pady => 20);
- for(@hosts) {
- $hosts_fm->Radiobutton(@rattr,
- -variable => \$preselected_host,
- -value => $_,
- -text => $_,
- )->pack(-side => 'top');
- }
- my $fm = $hosts_fm->Frame(-background => $darkbg)->pack(-side => 'bottom');
- $fm->Button(@battr,
- -command => sub {$hosts_tl->destroy},
- -text => 'ok')->pack(-side => 'left', -padx => 10, -pady => 20);
- $fm->Button(@battr,
- -command => sub {$preselected_host = undef; $hosts_tl->destroy},
- -text => 'cancel')->pack(-side => 'left', -padx => 10, -pady => 20);
- $hosts_tl->update;
- my ($X, $Y) = ($mw->rootx, $mw->rooty);
- my ($w, $h) = ($hosts_tl->width, $hosts_tl->height);
- my ($W, $H) = ($mw->width, $mw->height);
- $x = $X + $W - $w if ($x + $w) > $X + $W;
- $y = $Y + $H - $h if ($y + $h) > $Y + $H;
- $hosts_tl->geometry('+'.$x.'+'.$y);
- $hosts_tl->waitWindow();
- return $preselected_host;
+ my $x = shift;
+ my $y = shift;
+ $x += 50;
+
+ my $preselected_host = shift;
+ return $preselected_host if @hosts <= 1;
+ $hosts_tl->destroy if Tk::Exists($hosts_tl);
+ $hosts_tl = $mw->Toplevel(-background => $darkbg);
+ $hosts_tl->resizable(0,0);
+ $hosts_tl->title('ivycontrolpanel');
+ my $hosts_fm = $hosts_tl->Frame(-background => $darkbg,
+ -highlightthickness => 3,
+ -highlightbackground => $hlbg,
+ )->pack(-side => 'top', -padx => 0, -pady => 0);
+ my @lattr = (-padx => 10,
+ -pady => 10,
+ -relief => 'flat',
+ -highlightthickness => 0,
+ -background => $darkbg,
+ -foreground => $fg,
+ -borderwidth => 0,
+ @fontspec);
+ my @battr = (@lattr,
+ -width => 4, -height => 1,
+ -highlightthickness => 3,
+ -highlightbackground => $hlbg,
+ -activebackground => $darkbg,
+ -activeforeground => $fg,
+ );
+ my @rattr = (@lattr,
+ -activebackground => $darkbg,
+ -activeforeground => $fg,
+ -selectcolor => $selcolor);
+
+ $hosts_fm->Label(@lattr, -text => "restart on :"
+ )->pack(-side => 'top', -padx => 20, -pady => 20);
+ for(@hosts) {
+ $hosts_fm->Radiobutton(@rattr,
+ -variable => \$preselected_host,
+ -value => $_,
+ -text => $_,
+ )->pack(-side => 'top');
+ }
+ my $fm = $hosts_fm->Frame(-background => $darkbg)->pack(-side => 'bottom');
+ $fm->Button(@battr,
+ -command => sub {$hosts_tl->destroy},
+ -text => 'ok')->pack(-side => 'left', -padx => 10, -pady => 20);
+ $fm->Button(@battr,
+ -command => sub {$preselected_host = undef; $hosts_tl->destroy},
+ -text => 'cancel')->pack(-side => 'left', -padx => 10, -pady => 20);
+ $hosts_tl->update;
+ my ($X, $Y) = ($mw->rootx, $mw->rooty);
+ my ($w, $h) = ($hosts_tl->width, $hosts_tl->height);
+ my ($W, $H) = ($mw->width, $mw->height);
+ $x = $X + $W - $w if ($x + $w) > $X + $W;
+ $y = $Y + $H - $h if ($y + $h) > $Y + $H;
+ $hosts_tl->geometry('+'.$x.'+'.$y);
+ $hosts_tl->waitWindow();
+ return $preselected_host;
} # end hostsmenu
diff --git a/src/IvyIO.pm b/src/IvyIO.pm
index 8283a02..76dc968 100644
--- a/src/IvyIO.pm
+++ b/src/IvyIO.pm
@@ -2,19 +2,28 @@ package IvyIO;
use strict;
use Ivy;
+use Carp;
+use Tk;
my $ivy;
+my %appNameByhostAndPort = ();
+my %diedApp = ();
+my $pingcallback;
# init an ivy bus
sub init {
- my ($appname, $bus, $conncb, $disconncb) = @_;
+ my ($appname, $bus, $conncb, $disconncb, $pingcb, $mw) = @_;
Ivy->init(-loopMode => 'TK',
-appName => $appname,
-ivyBus => $bus,
);
+
+ $pingcallback = $pingcb;
+
$ivy = Ivy->new(-statusFunc => sub {&_status($conncb, $disconncb, @_);});
$ivy->start;
+ $mw->repeat (3000 ,[\&sendPings]) if defined $pingcb;
} # end init
@@ -27,13 +36,17 @@ sub kill {
sub _status {
- my ($conncb, $disconncb, $ref_array_present, $ref_array_absent,
- $ref_hash_present, $agent, $status, $host) = @_;
- if ($status eq "new") {
- &$conncb($agent, $host);
- } elsif ($status eq "died") {
- &$disconncb($agent, $host);
- }
+ my ($conncb, $disconncb, $ref_array_present, $ref_array_absent,
+ $ref_hash_present, $agent, $status, $host) = @_;
+ #print "Status : @_\n";
+ if ($status eq "new") {
+ &$conncb($agent, $host);
+ $appNameByhostAndPort{$host} = $agent;
+ delete $diedApp{$host};
+ } elsif ($status eq "died") {
+ &$disconncb($agent, $host);
+ $diedApp{$host} = 1;
+ }
} # end _status
@@ -83,7 +96,7 @@ sub bind_for_play_event {
my $cb = shift;
return unless $cb;
return unless $ivy;
- $ivy->bindRegexp("ClockStart", [sub { shift; &$cb(); }]);
+ $ivy->bindRegexp("^ClockStart", [sub { shift; &$cb(); }]);
} # end bind_for_play_event
@@ -92,7 +105,7 @@ sub bind_for_pause_event {
my $cb = shift;
return unless $cb;
return unless $ivy;
- $ivy->bindRegexp("ClockStop", [sub { shift; &$cb(); }]);
+ $ivy->bindRegexp("^ClockStop", [sub { shift; &$cb(); }]);
} # end bind_for_pause_event
@@ -103,12 +116,45 @@ sub bind_for_clock_and_rate_event {
my $cb = shift;
return unless $cb;
return unless $ivy;
- $ivy->bindRegexp('ClockEvent Time=(\d\d):(\d\d):(\d\d) Rate=(.*) Bs=.*',
+ $ivy->bindRegexp('^ClockEvent Time=(\d\d):(\d\d):(\d\d) Rate=(.*) Bs=.*',
[sub { shift; &$cb(@_); }]);
- $ivy->bindRegexp('ClockDatas Time=(\d\d):(\d\d):(\d\d) Rate=(.*) Bs=.*',
+ $ivy->bindRegexp('^ClockDatas Time=(\d\d):(\d\d):(\d\d) Rate=(.*) Bs=.*',
[sub { shift; &$cb(@_); }]);
} # end bind_for_clock_event
+# execute the callback kill all
+sub bind_for_kill_all {
+ my $cb = shift;
+ return unless $cb;
+ return unless $ivy;
+ $ivy->bindRegexp('^IvyControlPanel KillAll',
+ [sub { shift; &$cb(); }]);
+
+} # end bind_for_clock_event
+
+
+# send a ping to agent(s)
+sub sendPings ()
+{
+ my $appf;
+ foreach $appf (keys (%appNameByhostAndPort)) {
+ next if exists $diedApp{$appf};
+ $ivy->ping ($appf, \&receivePongCb);
+ }
+} # end sendPings
+
+
+# received pong, Agent is notified with the ping/pong time value
+sub receivePongCb($$)
+{
+ my ($time, $appf) = @_; # time = ping/pong duration in ms
+
+ #printf ("DBG> :$received: $appf [$time]".$appNameByhostAndPort{$appf}."\n");
+ &$pingcallback($appNameByhostAndPort{$appf}, $appf, $time);
+
+} # end receivePongCb
+
+
1;
diff --git a/src/ivycontrolpanel b/src/ivycontrolpanel
index e0214bd..0bbc4d4 100755
--- a/src/ivycontrolpanel
+++ b/src/ivycontrolpanel
@@ -9,10 +9,12 @@
use strict;
use Carp;
+
# where you may find bitmap files
use lib "/usr/share/ivycontrolpanel";
# where you may find the IvyIO and Agent modules
use lib "/usr/lib/ivycontrolpanel";
+#use lib ".";
# where you may find the FugueConfig module
use lib "/usr/lib/ivylaunch";
@@ -42,6 +44,8 @@ use vars qw(%opt);
# window size
my $width = 1024;
my $height = 768;
+my $smallsized = 0;
+my $coef = 1;
# fonts spec
my @fontspec34 = (-font =>
@@ -59,6 +63,8 @@ my $bg = '#5C5655';
my $hlbg = '#7CC452';
my $fg = '#FCFAFC';
my $selcolor = 'yellow';
+my $pbcolor = '#c9b900000000';
+my $pingThreshold = 20;
# traffic rate spec
my @rate = (-20..-1, -0.5, 0, 0.5, 1..20);
@@ -77,6 +83,17 @@ my $settingtime;
my $selectedtimelabel;
my $ivylaunch_agent;
+# ivy version
+my $ivy_version = $Ivy::VERSION;
+my $ivy_versionstring = "v$ivy_version";
+my $ivy_cvsrevision = 0;
+if ($ivy_version =~ s/Revision: (.*)//) {
+ $ivy_version = $1;
+ $ivy_cvsrevision = 1;
+ $ivy_versionstring = "v$ivy_version (cvs revision)";
+}
+my $newapi4_18 = 1 if (($ivy_cvsrevision == 1 and $ivy_version ge 1.40) or
+ ($ivy_cvsrevision == 0 and $ivy_version ge 4.18));
#---------------------------------------------------------------------------------
#
@@ -84,26 +101,53 @@ my $ivylaunch_agent;
#
#---------------------------------------------------------------------------------
-&usage unless Getopt::Long::GetOptions(\%opt, 'b=s', 'nocursor', 'help');
-&usage if $opt{help};
+Getopt::Long::Configure('pass_through');
+&usage unless Getopt::Long::GetOptions(\%opt, 'b=s', 'nocursor', 'help', 'smallsize',
+ 'position=s','pingthreshold=s');
+&usage(1) if $opt{help};
my ($fuguefile) = @ARGV;
+
#---------------------------------------------------------------------------------
#
-# init ivy
+# build the mainwindow
#
#---------------------------------------------------------------------------------
+if ($opt{smallsize})
+{
+ $width = 640;
+ $height = 480;
+ $smallsized = 1;
+ $coef = 0.620;
+
+ @fontspec34 = (-font =>
+ '-b&h-lucida-bold-r-normal-sans-20-140-100-100-p-127-iso8859-1');
+ @fontspec20 = (-font =>
+ '-b&h-lucida-bold-r-normal-sans-12-120-75-75-p-79-iso8859-1');
+ @fontspec24 = (-font =>
+ '-b&h-lucida-bold-i-normal-sans-15-150-100-100-p-216-iso8859-1');
+ @fontspec17 = (-font =>
+ '-adobe-helvetica-medium-r-normal--11-80-100-100-p-60-iso10646-1');
+}
+
+if ($opt{pingthreshold}) {
+ $pingThreshold = $opt{pingthreshold};
+}
-IvyIO::init("ivycontrolpanel", $opt{b}, \&connected, \&disconnected);
+my $mw = MainWindow->new (-bg => 'black');
#---------------------------------------------------------------------------------
#
-# build the mainwindow
+# init ivy
#
#---------------------------------------------------------------------------------
-my $mw = MainWindow->new (-bg => 'black');
+if ($newapi4_18) {
+ IvyIO::init("ivycontrolpanel", $opt{b}, \&connected, \&disconnected, \&pingcb, $mw);
+} else {
+ IvyIO::init("ivycontrolpanel", $opt{b}, \&connected, \&disconnected, undef, $mw);
+}
if ($opt{nocursor}) {
open(CURSOR, ">/tmp/cursor-ivybanner");
@@ -120,27 +164,27 @@ if ($opt{nocursor}) {
} else {
$mw->configure(-cursor => 'circle');
}
-$mw->geometry ($width."x".$height."--0+0");
-$mw->title ('ivycontrolpanel');
+$mw->geometry ($width."x".$height.$opt{position});
+$mw->title ('ivycontrolpanel - Ivy '.$ivy_versionstring);
$mw->client ('ivycontrolpanel');
$mw->resizable(0,0);
# geometry variables
-my $dxleft = 20;
-my $dxright = 20;
-my $dybot = 90;
-my $dytop = 20;
-my $ddy = 10;
+my $dxleft = 20*$coef;
+my $dxright = 20*$coef;
+my $dybot = 90*$coef;
+my $dytop = 20*$coef;
+my $ddy = 10*$coef;
my $y;
my $x;
my $btn_h = $dybot - 3*$ddy;
my $btn_w = $btn_h;
-my $fm_w = $btn_w + 10;
-my $fm_h = $btn_h + 10;
+my $fm_w = $btn_w + 10*$coef;
+my $fm_h = $btn_h + 10*$coef;
# widgets attributes
my @frameattr = (-relief => 'flat',
- -highlightthickness => 3,
+ -highlightthickness => 3*$coef,
-highlightbackground => $hlbg,
-highlightcolor => $hlbg,
-height => $height - $dytop - $dybot,
@@ -155,7 +199,7 @@ my @labelattr = (-width => 2, -height => 1,
my @buttonattr = (@labelattr,
-borderwidth => 1,
-highlightbackground => $hlbg,
- -highlightthickness => 3,
+ -highlightthickness => 3*$coef,
-width => $btn_w, -height => $btn_h,
-activebackground => $bg,
-activeforeground => $fg);
@@ -189,7 +233,7 @@ $fm1->Label(-borderwidth => 0,
-text => ' [ Bus ] '.(($opt{b}) ? $opt{b} : 'default').' '.
'[ File ] '.(($fuguefile) ? $fuguefile : 'none').' ',
@fontspec17,
- -foreground => $hlbg)->place(-x => $dxleft+20, -y => $dytop-10);
+ -foreground => $hlbg)->place(-x => $dxleft+20*$coef, -y => $dytop-10);
# build traffic rate frame
#---------------------------------------------------------------------------------
@@ -204,19 +248,19 @@ my $btn_prev = $fm1->Button(@buttonattr,
-image => $prevbmp,
)->place(-x => $x, -y => $y );
-$x += $btn_w + 15;
+$x += $btn_w + 15*$coef;
my $fm_lab = $fm1->Frame(@frameattr,
-width => $fm_w,
-height => $fm_h)->place(-x => $x, -y => $y);
my $lab_rate = $fm_lab->Label(@labelattr,
-anchor => 'center',
- -text => 1)->place(-x => 7, -y => 10);
+ -text => 1)->place(-x => 7*$coef, -y => 10*$coef);
-$x += $fm_w + 5;
+$x += $fm_w + 5*$coef;
my $btn_next = $fm1->Button(@buttonattr,
-image => $nextbmp,
)->place(-x => $x, -y => $y);
-$x += $btn_w + 15;
+$x += $btn_w + 15*$coef;
&setloopcommand($btn_prev, \&decrease_rate);
&setloopcommand($btn_next, \&increase_rate);
@@ -231,19 +275,19 @@ $lab_rate->bind('<ButtonPress>', [sub {
# build hour frame
#---------------------------------------------------------------------------------
-$x += 90;
+$x += 90*$coef;
my $xi;
# next/prev buttons
my $btn_tprev = $fm1->Button(@buttonattr,
-image => $prevbmp,
- )->place(-x => $x-$fm_w-5, -y => $y + 80);
+ )->place(-x => $x-$fm_w-5, -y => $y + 80*$coef);
my $fm_lab = $fm1->Frame(@frameattr,
-width => 3*$fm_w,
-height => $fm_h)->place(-x => $x, -y => $y);
# separators
-$xi = -13 ;
+$xi = -13*$coef ;
for (my $i=0; $i<2; $i++) {
$xi += $fm_w;
$fm_lab->Label(@labelattr,
@@ -252,28 +296,28 @@ for (my $i=0; $i<2; $i++) {
-text => ':')->place(-x => $xi, -y => $ddy);
}
# hour, minutes, seconds
-$xi = 5;
+$xi = 5*$coef;
my $lab_hour = $fm_lab->Label(@labelattr,
-anchor => 'center',
-text => '00')->place(-x => $xi, -y => $ddy);
$xi += $fm_w;
my $lab_min = $fm_lab->Label(@labelattr,
-anchor => 'center',
- -text => '00')->place(-x => $xi, -y => 10);
+ -text => '00')->place(-x => $xi, -y => 10*$coef);
$xi += $fm_w;
my $lab_sec = $fm_lab->Label(@labelattr,
-anchor => 'center',
- -text => '00')->place(-x => $xi, -y => 10);
+ -text => '00')->place(-x => $xi, -y => 10*$coef);
$lab_hour->bind('<1>', [\&settime, 0]);
$lab_min->bind('<1>', [\&settime, 1]);
$lab_sec->bind('<1>', [\&settime, 2]);
-$x += 3*$fm_w + 10;
+$x += 3*$fm_w + 10*$coef;
my $btn_tnext = $fm1->Button(@buttonattr,
-image => $nextbmp,
- )->place(-x => $x-5, -y => $y + 80);
+ )->place(-x => $x-5, -y => $y + 80*$coef);
@@ -289,7 +333,7 @@ IvyIO::bind_for_clock_and_rate_event(sub {
# build traffic control frame
#---------------------------------------------------------------------------------
-$x += 90;
+$x += 90*$coef;
my $playbmp = $mw->Bitmap('play', -file => Tk::findINC('play.bmp'),
-background => $bg,
-foreground => $hlbg);
@@ -306,11 +350,11 @@ my $playbtn = $fm1->Button(@buttonattr,
-image => $playbmp,
)->place(-x => $x, -y => $y);
-$x += $btn_w + 20;
+$x += $btn_w + 20*$coef;
my $pausebtn = $fm1->Button(@buttonattr,
-image => $pausebmp,
)->place(-x => $x, -y => $y );
-$x += $btn_w + 20;
+$x += $btn_w + 20*$coef;
$playbtn->configure(-command => \&play);
@@ -332,8 +376,9 @@ $fm1->Button(@buttonattr,
-image => $quitbmp,
-command => \&quitdialogbox,
)->place(-x => $x, -y => $y);
-$x -= $fm_w + 10;
+$x -= $fm_w + 10*$coef;
+IvyIO::bind_for_kill_all(\&killandquit);
#---------------------------------------------------------------------------------
#
@@ -347,16 +392,16 @@ if ($fuguefile) {
die "Cant' parse fugue config file $fuguefile\n" unless $code;
}
-my $x0 = $dxleft + 20;
-my $y0 = $dytop + 25;
-my $rmax = 10;
+my $x0 = $dxleft + 20*$coef;
+my $y0 = $dytop + 25*$coef;
+my $rmax = 10*$coef;
my $cmin = 2;
my $wmax = ($width-2*$x0);
-my $dy = 64;
+my $dy = 64*$coef;
my %hosts;
-Agent->configure($mw, $bg, $fg, $selcolor, $hlbg, $darkbg, \@fontspec20,
- $x0, $y0, $wmax, $dy, $cmin, $rmax, $opt{b});
+Agent->configure($mw, $bg, $fg, $selcolor, $pbcolor, $hlbg, $darkbg, \@fontspec20,
+ $x0, $y0, $wmax, $dy, $cmin, $rmax, $opt{b}, $coef, $pingThreshold);
for (@fugueconfigdata) {
next unless $_->[0] eq 'global' or $_->[0] eq 'local';
@@ -381,13 +426,19 @@ MainLoop;
#=================================================================================
sub usage {
- print "Usage : ivycontrolpanel [-help] [-b ivybus] [-nocursor] [fugueconfigfile]\n";
+ my $exitflag = shift;
+ print "Usage : ivycontrolpanel [-help] [-b ivybus] [-nocursor] [-smallsize]\n";
+ print " [-pingthreshold threshold] [fugueconfigfile]\n";
print "\n";
print "Options :\n";
print " -b ivybus bus ivy\n";
- print " -nocursor hide mouse cursor\n";
+ print " -nocursor hide mouse cursor\n";
+ print " -smallsize display the app in 640x480 mode\n";
+ print " -pingthreshold ms [def=20] set the ping threshold in ms for detecting\n";
+ print " performance problems (requires Ivy >= 4.18)\n";
+ print " -position position set the window position\n";
print "\n";
- exit 0;
+ exit 0 if $exitflag ;
} # end usage
@@ -395,8 +446,8 @@ sub usage {
sub killandquit {
Agent->killall;
$mw->after(1500, sub {
- Agent->kill('ivylaunch') if $ivylaunch_agent > 0;
- &quit;});
+ Agent->kill('ivylaunch') if $ivylaunch_agent > 0;
+ &quit;});
} # end killandquit
@@ -439,7 +490,7 @@ sub quitdialogbox {
$tl->title('ivycontrolpanel');
$tl->resizable(0, 0);
my $fm = $tl->Frame(-background => $darkbg,
- -highlightthickness => 3,
+ -highlightthickness => 3*$coef,
-highlightbackground => $hlbg,
)->pack(-side => 'top', -padx => 0, -pady => 0);
my $fm1 = $fm->Frame(-background => $darkbg)->pack(-side => 'bottom');
@@ -455,24 +506,24 @@ sub quitdialogbox {
-foreground => $fg,
-borderwidth => 1,
-highlightbackground => $hlbg,
- -highlightthickness => 3,
+ -highlightthickness => 3*$coef,
-height => 2,
-activebackground => $bg,
-activeforeground => $fg,
@fontspec24);
my $l = $fm->Label(@labelattr, -text => "kill all agents ?",
- )->pack(-side => 'top', -padx => 20, -pady => 20,
+ )->pack(-side => 'top', -padx => 20*$coef, -pady => 20*$coef,
-expand => 1, -fill => 'both');
$fm1->Button(@buttonattr, -text => 'yes',
-command => sub {
$l->configure(-text => $l->cget(-text)."...\nwait...");
&killandquit;
},
- )->pack(-side => 'left', -padx => 20, -pady => 20,
+ )->pack(-side => 'left', -padx => 20*$coef, -pady => 20*$coef,
-expand => 1, -fill => 'both');
$fm1->Button(@buttonattr, -text => 'cancel',
-command => sub { $tl->destroy },
- )->pack(-side => 'left', -padx => 20, -pady => 20,
+ )->pack(-side => 'left', -padx => 20*$coef, -pady => 20*$coef,
-expand => 1, -fill => 'both');
# placement at window center
$tl->update;
@@ -512,6 +563,16 @@ sub disconnected {
} # end disconnected
+# called when an ivy ping/pong
+sub pingcb {
+ my ($agent, $host, $pingvalue) = @_;
+ if ($agent eq 'ivylaunch') {
+ $ivylaunch_agent++;
+ } elsif ($agent ne 'ivycontrolpanel') {
+ Agent->pingcb($agent, $host, $pingvalue);
+ }
+}
+
#---------------------------------------------------------------------------------
#
# Functions dedicated to play/pause buttons
@@ -655,10 +716,10 @@ sub display_rate {
$rate =~ s/\.0+$//;
if (length($rate) > 2) {
$lab_rate->configure(-width => 3, @fontspec24);
- $lab_rate->place(-x => 5, -y => 15);
+ $lab_rate->place(-x => 5*$coef, -y => 15*$coef);
} else {
$lab_rate->configure(-width => 2, @fontspec34);
- $lab_rate->place(-x => 7, -y => 10);
+ $lab_rate->place(-x => 7*$coef, -y => 10*$coef);
}
$lab_rate->configure(-text => $rate);
if ($rate == 0 and $isplaying) {
@@ -690,8 +751,8 @@ sub settime {
if ($selectedtimelabel eq $lab) {
$selectedtimelabel = undef;
$lab->configure(-background => $bg, -foreground => $fg);
- $btn_tprev->place(-y => $y + 80);
- $btn_tnext->place(-y => $y + 80);
+ $btn_tprev->place(-y => $y + 80*$coef);
+ $btn_tnext->place(-y => $y + 80*$coef);
&unsetloopcommand($btn_tprev);
&unsetloopcommand($btn_tnext);
my $time = $lab_hour->cget(-text).':'.$lab_min->cget(-text).':'.
@@ -709,8 +770,8 @@ sub settime {
}
$lab->configure(-background => $fg, -foreground => $bg);
unless (defined $selectedtimelabel) {
- $btn_tprev->place(-y => $y - 80);
- $btn_tnext->place(-y => $y - 80);
+ $btn_tprev->place(-y => $y - 80*$coef);
+ $btn_tnext->place(-y => $y - 80*$coef);
}
$selectedtimelabel = $lab;
&setloopcommand($btn_tprev, sub {&decrease_time($lab, $field)});
@@ -758,24 +819,23 @@ sub display_time {
} # end display_time
-
-
=head1 NAME
ivycontrolpanel - an interface for controlling ivy agents
=head1 SYNOPSIS
-ivycontrolpanel [-help] [-b bus] [-nocursor] [fugueconfigfile]
+ivycontrolpanel [-help] [-b bus] [-nocursor] [-smallsize] [-position pos] [-pingthreshold ms] [fugueconfigfile]
=head1 DESCRIPTION
-ivycontrolpanel blabla.
-
-description des interactions de controle (vitesse, réglage de l'heure,
-play/pause, sortie)
+ivycontrolpanel displays agents detected on a given ivy bus. For each agent, a led indicates its status. By clicking on an active agent (or its led), you kill it (an ivy die message is sent to it). When ivycontrolpanel is associated with a Fugue configuration file, the agents referenced in this file can be restarted by the same way. These agents are recognizable by their larger led's border.
-description du panneau agents.
+At bottom of window, two areas are dedicated to a specific agent, the air traffic simulator Rejeu. At bottom left, you can adjust the traffic speed. At bottom center, you have a clock; when you click on one of time fields, two scrolling arrows appears which let you adjust time; validation is done by clicking on the last selected field. Near, play/pause buttons let you start or stop the traffic simulator. Then, at bottom right, the cross button will be used to kill all agents and quit.
+
+=head1 LISTENED MESSAGE
+
+listen to the message 'IvyControlPanel KillAll', to kill all the agent (like quit button).
=head1 OPTIONS
@@ -789,6 +849,18 @@ Specify the ivy bus.
Hide mouse cursor (for touchscreen usage).
+=item B<-smallsize>
+
+Set the window size to 640x480 pixels.
+
+=item B<-position> XOFF+YOFF
+
+Specify the window position.
+
+=item B<-pingthreshold> duration in ms
+
+Set the ping threshold for detecting performance problems. ivycontrolpanel periodically pings agents and compares the ping/pong duration with the given threshold. If duration exceeds it, the agent's led becomes blinking red. Default is 20 ms. Requires Ivy v4.18 or higher.
+
=back
=head1 FILE FORMAT