Files
lcdproc/clients/examples/lcdident.pl
T

299 lines
8.1 KiB
Perl
Executable File

#!/usr/bin/perl -w
# $Id$
#
# Copyright (c) 2008, Ethan Dicks <ethan.dicks@gmail.com>
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this file; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
# Following is the POD documentation, type perldoc lcdident.pl to read it.
=head1 NAME
lcdident - identify LCDproc displays
=head1 SYNOPSIS
B<lcdident.pl>
[B<-s> I<server>]
[B<-p> I<port>]
[B<-t> I<seconds>]
[B<-v> I<verbosity>]
[B<-h>]
[B<-V>]
=head1 DESCRIPTION
B<lcdident> is a simple LCDproc client program that writes a port
number and display geometry to a particular instance of B<LCDd>. For
systems with multiple display modules and multiple B<LCDd> processes,
it can be quite handy to know which TCP port is associated with
which physical module.
B<lcdident> is also an example of how to code for different display
geometries. In particular, it differentiates between 2-line and
more-than-2-line (typically 4-line) displays.
=head1 OPTIONS
-s <server>
connect to <server>.
-p <port>
connect to port <port>
-t <seconds>
how long to keep this client running (default is 5 seconds).
-v <verbosity>
set logging verbosity level to <verbosity>.
-V
display the present version number of lcdident.
-h
print out a list of the available program options and exit.
=head1 DIAGNOSTICS
=over 4
=item Cannot connect to LCDproc port
By default, lcdident tries to connect to localhost port 13666, but by using
the B<-s> and B<-p> options, you can point B<lcdident> at other servers and
other ports. If you get this error, that means that there was a problem
opening up the requested port on the requested machine. Typically this
means that B<LCDd> is not listening on that particular port. The two most
common causes of this are because B<LCDd> was configured to listen on a
different port, or because B<LCDd> is not running at all.
=back
=head1 REQUIRES
Perl 5.004;
=head1 DISCLAMER
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
=head1 SEE ALSO
L<LCDd>
=head1 BUGS
Yes, there might be some. Please report any you find to LCDproc's mailing list.
See the website for more information.
=head1 AUTHORS
B<lcdident> was written by Ethan Dicks <ethan.dicks@gmail.com>
=head1 WEBSITE
Visit B<http://www.lcdproc.org/> for more info and the lastest version.
=cut
use 5.004;
use strict;
use IO::Socket;
use Getopt::Std;
use Fcntl;
############################################################
# Configurable part. Set it according your setup
# or use input args.
############################################################
# Verbose
# 0 : None (only fatal errors)
# 1 : Warnings
# 5 : Explain every step.
my $verbose = 0;
# Host which runs lcdproc daemon (LCDd)
my $server = "localhost";
# Port on which LCDd listens to requests
my $port = "13666";
# wait-time (in seconds) when we are all done
my $waittime = 5;
############################################################
# End of user configurable parts
############################################################
$SIG{INT} = \&grace;
$SIG{TERM} = \&grace;
my $progname = $0;
$progname =~ s#.*/(.*?)$#$1#;
# declare functions
sub grace();
sub usage($);
# Process input arguments
my %opt = ();
# get options #
if (getopts('s:p:v:t:hV', \%opt) == 0) {
usage(1);
}
# check options
usage(0) if ($opt{h});
if ($opt{V}) {
print STDERR $progname ." version 1.05\n";
exit(0);
}
# check number of arguments
usage(1) if ($#ARGV >= 0);
# set variables
$server = defined($opt{s}) ? $opt{s} : $server;
$port = defined($opt{p}) ? $opt{p} : $port;
$verbose = defined($opt{v}) ? $opt{v} : $verbose;
$waittime= defined($opt{t}) ? $opt{t} : $waittime;
# Connect to the server...
print "Connecting to LCDproc at $server\n" if ($verbose >= 5);
my $remote = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => $server,
PeerPort => $port,
) or die "Cannot connect to LCDproc port ($server:$port)\n";
# Make sure our messages get there right away
$remote->autoflush(1);
sleep 1; # Give server plenty of time to notice us...
print $remote "hello\n";
my $lcdconnect = <$remote>;
print $lcdconnect if ($verbose >= 5);
# connect LCDproc 0.5.2 protocol 0.3 lcd wid 20 hgt 4 cellwid 5 cellhgt 8
($lcdconnect =~ /lcd.+wid\s+(\d+)\s+hgt\s+(\d+)/);
my $lcdwidth = $1; my $lcdheight= $2;
print "Detected LCD size of $lcdwidth x $lcdheight\n" if ($verbose >= 5);
# Turn off blocking mode...
fcntl($remote, F_SETFL, O_NONBLOCK);
# Set up some screen widgets...
print $remote "client_set name {lcdident}\n";
print $remote "screen_add lcdident\n";
print $remote "screen_set lcdident name {lcdident}\n";
print $remote "widget_add lcdident title title\n";
print $remote "widget_set lcdident title {lcdident}\n";
print $remote "widget_add lcdident ident1 string\n";
print $remote "widget_add lcdident ident2 string\n";
# Compose the ident message(s) and calculate where to render it/them
my $ident1;
my $ident2;
my $ident2_y = $lcdheight; # put the second bit on the bottom line
my $ident1_y = $ident2_y - 1; # put the first bit one line up from the second
# check for 2-line displays to see if we have to put all the info on one line
if ($lcdheight > 2) {
$ident1 = "Port ${port}";
$ident2 = "Geom ${lcdwidth}x${lcdheight}";
} else {
$ident1 = "Port $port ${lcdwidth}x${lcdheight}";
$ident2 = "";
$ident1_y = $lcdheight; # use the bottom line
}
# Display the ident message(s)
if ($ident1) {
my $cmd = sprintf("widget_set lcdident ident1 1 %d {%s}", $ident1_y, $ident1);
print "Cmd is '$cmd'\n" if ($verbose >= 5);
print $remote $cmd, "\n";
}
if ($ident2) {
my $cmd = sprintf("widget_set lcdident ident2 1 %d {%s}", $ident2_y, $ident2);
print "Cmd is '$cmd'\n" if ($verbose >= 5);
print $remote $cmd, "\n";
}
# hold the client screen up for as long as we were asked (default 5 seconds);
print "Keeping screen up for $waittime seconds\n" if ($verbose >= 5);
sleep($waittime);
# eat all input from LCDd
while(defined(my $input = <$remote>)) { }
# all done
grace();
# send a SIGINT or SIGTERM to exit nicely.
# To be called on exit and on SIGINT or SIGTERM.
sub grace() {
print "Exiting...\n" if ($verbose >= 5);
close($remote);
exit;
}
## print out usage message and exit ##
# Synopsis: usage($status)
sub usage($)
{
my $status = shift;
print STDERR "Usage: $progname [<options>]\n";
if (!$status) {
print STDERR " where <options> are\n" .
" -s <server> connect to <server> (default: $server)\n" .
" -p <port> connect to <port> on <server> (default: $port)\n" .
" -t <seconds> how long to hold the client screen up (default: $waittime seconds).\n" .
" -v <verbosity> verbosity level (default: $verbose, max verbosity: 5)\n" .
" -h show this help page\n" .
" -V display version number\n";
}
else {
print STDERR "For help, type: $progname -h\n";
}
exit($status);
}
__END__