Initial revision

This commit is contained in:
William Ferrell
1999-12-09 23:15:14 +00:00
commit 2635c3085d
139 changed files with 24298 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
William W. Ferrell (choadster@earthlink.net)
Scott Scriven (scriven@cs.colostate.edu).
Hello,
I am the happy new owner of a matrix-orbital LK-204-25 V.
I also made computer science studies (but currently I only program for fun).
The reason why I wanted this LCD screen was to build a MAME/MPEG3/DVD player.
Currently the IR receaver is missing, but I already started to work on my
project by checking LCDPROC capability and trying to make it work the way I
want.
I don't know yet if my developpement will be a client of LCDPROC or if I will
make a stand-alone program (more likely reussing some of your code).
Currently, feature in LCDPROC don't cover yet my need yet.
So, my best option is to support you or your team in building the perfect
server in order for me to build only a client.
So, I downloaded v0.4-pre5 and started to hack. ;-)
I was a little bit confuse with your documentation, sometime talking about
version 0.3.x or about comming feature, but reading the source code (and
the sgml description that I only founded later) was the best.
I made some "minor" change to a few source file (this is what I remember):
* Cleaning the help screen from LCDd.
* Adding a speed option to MtxOrb driver.
* Updated MtxOrb help screen to indicate those change.
* Added some error checking to parameter sended to MtxOrb driver.
* Added fake support for big number into curses driver.
* Some modification to the debug_driver in order to compile.
* Added bignum widget in order to use that feature from the driver.
* Added big cloc[K] (24H) to lcdproc to test the new widget. (ugly/blinking)
* Added a General Purpose Output function to the MtxOrb driver.
Here is some kind of todo-list one liner only:
* Implement a debug/error to a syslog server rather than printf(stderr,...
* General Purpose Output support.
* Make "LCDproc Server" and "End Screen" (build-in screen) optionnal.
* Make HeartBeat working with General Purpose Output (led blinking).
* KeyPad support.
* Make KeyPad local feedback using General Purpose Output (led blinking).
* Make the server port number (listen) a param/config option.
* Accept incoming 'telnet' (specific port) as a new i/o device (vt100/ansi).
* MtxOrb driver across an outgoing 'telnet' session (access server).
My major todo:
* Well, I would like to (one way or another) interconnect IrMan(?) and
LCDProc. I will use LCDProc for the ouput of the name of the song, ...
and maybe for keyboard input. I will also use IrMan or some infrared
library in order to receave remote controle input. Now, I would be nice
to be able to connect to LCDProc and 'register' a new input and/or output
device.
What I am thinking about is to have LCDd be a server with local device
to manage, but also have remote device that could attach themself to
LCDd. I think, by reading your documentation, that you have somethink like
that already in mind. This will allow dynamic addition of new driver without
having to recompile LCDd...
Change you should make yourself:
* Update the network protocol description with heartbeat function.
* Remove reference/out of date description related to 0.3.x
I made many change to a lot of different file... (sorry)
I don't have the tool/knowledge available to give you a patch with only my
modification. So, I send you a taz.gz with everything after my change.
I won't have much time to spend on LCDPROC for about two week (and the
week-end in between). This give you time to check my change and incorporate
anything you find interesting.
+74
View File
@@ -0,0 +1,74 @@
Hello,
In order to compile LCDd (the lcdproc server) with support for IRman,
you need to put libirman in a neighbor directory.
Currently I use version 0.4.1b and this is hard coded into makefile and
#include string. (could do better).
Now for libirman to "work" you need a .irmanrc file with description of
you infrared "code" and mapping to command in my driver.
A template of such a file is given in the driver directory. This template
will only work with my JVC remote control, but you already have configured
IRman, you should be able to modify it for yours.
David GLAUDE
FINDING THE COMPONENT:
lcdproc: deamon to display information on a lcd screen.
version: 0.4-pre5
need libirman and my driver to support input from IrMan.
libirman: library in use to read input from IrMan on a serial port.
version used: 0.4.1b
currently used untouch and just needed to use my driver for lcdproc.
-----------Here stop the currently usefull information------------
lirc: standardize interface to control IR receaver and emetteur.
version: 0.5.4
currently not used but might be usefull have support for other IR.
cdtools: command line program to control the cdrom and play audio cd.
might need some patch to have a better output of cd song information.
Hello,
This file describe the personnal developpement I have made and wich sources
you need to bring together in order to integrate everything the same way
I did.
Basicaly, we are talking about a yet another CD player 'yaCDplayer' but
because the name might already have been in use, it was decided to call it
'lcdcd'.
This CD player take as input (control) and output (display of the status) the
lcdproc server. It as thus no user interface on it's own.
Lcdproc is a server that allow the control of LCD screen over TCP connection.
Some LCD screen also have support to connect a keypad, it also offer
input user interface for this program.
Because lcdproc is a very flexible input/output server, it also support for
input comming from a joystic, the keyboard (curses output) or even irman.
It also support multiple driver simultaniously and multiple driver like curses
and joystic for those without an LCD screen and an irman.
Now irman is an infrared receaver with a build in chip to hash the input
signal into a unique key that can be readed throught a serial interface.
An other important think about lcdcd it is that in order to communicate with
lcdproc we use a TCP/IP connection. Lcdproc need to run in background on the
server where the input/output device are connected. Lcdcd must run on the
client where the cdrom is located. In between, we need to have a TCP/IP
network. Now, if you have a firewall, you will let traffic from the client to
the server on port 13666 wich is the default for lcdproc, be carefull there
is not security build in lcdproc and anybody can connect to it. If you don't
have an IP network and the client and the server are located on a single
computer (with the CDROM, the LCD screen and the IrMan connected) then you
need to enable IP on this computer. This can be done by putting an IP address
on a loopback interface (like 127.0.0.1 on lo, try 'ifup lo' it might work
also on your distribution of Linux).
Currently, this ... ---to be continued---
+49
View File
@@ -0,0 +1,49 @@
(this text taken from a message by Bill Farrow, more info coming later)
<bfarrow@arrow.bsee.swin.edu.au>
The code in LCDproc for the hd4470 LCD controller chips comes from
"lcdtext" (by Matthias Prinke) or one of the derivatives ("lcdstat4",
"lcdtime").
You might like to get those packages down as well and have a play.
LCDproc-0.4 only supports 4 line displays, but LCDproc-0.3.5 runs 2 line
displays also. A different maintainer is responsible for this version.
The pinouts are like so : (From lcdtext)
1.1 Connecting the LCD to a printer port
-----------------------------------------
LCD printer port
Pin signal Pin signal
1 GND 18..25 GND
2 +5V --- *)
3 Vadj. --- *)
4 RS 6 D4
5 RW 7 D5
6 EN 8 D6
11 D4 2 D0
12 D5 3 D1
13 D6 4 D2
14 D7 5 D3
Getting the supply voltage:
Use a floppy supply connector, get it from the game port, take some
diodes and a capacitor and get it from the port's data lines, get it
from the keyboard connector or whatever you like. Be save to avoid
short circuit. You need only 3mA at 5V! (if you have the same type
lcd)
Connecting the contrast adjusting pin (Vadj.):
(variable resistor)
.------.
Vcc ---| 10k |--- GND
`---^--'
/|\
|
Vadj.
+119
View File
@@ -0,0 +1,119 @@
WARNING!
This man page hasn't been updated since V0.3.4.
SYNOPSIS
lcdproc - displays system status on Matrix-Orbital 20x4 LCD
on a serial port
USAGE
lcdproc [-d device] [-c contrast] [modelist]
DESCRIPTION
lcdproc uses a 20x4 character LCD manufactured by Matrix-Orbital
to display status information about the system.
Currently, only Linux is supported (kernels 2.0 and greater), and
/proc filesystem support is required. In addition, only displays
made by Matrix-Orbital are supported at this time (their displays
have built-in controllers and a very good BIOS).
lcdproc understands these options:
-l driver
The lcd display driver to use. So far, this can only be:
text Text-mode output. (20x4)
MtxOrb Matrix Orbital displays... (20x4)
curses Curses-based terminal output (20x4)
debug Verbose debugging text output (terminal)
-d device
The serial port attached to the display. Usually /dev/cua0
or /dev/cua1. This device is locked by lcdproc.
-c contrast
Sets the display's contrast setting to the value specified,
ranging from 0 to 255. Note that values below around 30
yield invisible characters from most viewing angles, and
values above 200 yield solid cells from most viewing
angles.
modelist
A list specifying what screens to display, and in what order;
in the form:
mode [mode mode mode ...]
where mode is one of...
"C" (CPU usage),
"G" (CPU Graph like Xload),
"M" (Memory Usage),
"X" (X-Load),
"T" (Date, time, Uptime, OS version)
"D" (Disk Stats),
"B" (Battery Stats),
"A" (About),
"O" (old date and time screen), (removed soon?)
"U" (System Uptime), (will be removed soon?)
For example:
lcdproc -d /dev/cua1 -c 180 C M D X -l MtxOrb
selects /dev/cua1 (com2) as the serial port for the
MtxOrb driver, sets the display's contrast to 180,
and specifies the following modes:
- CPU Usage, updated every 1/8th of a second for 4 seconds.
- Memory usage, updated every 1/4th of a second for 4 seconds.
- Uptime, updated every 1/2 second for 4 seconds.
- Date and Time, updated every 1/2 second for 4 seconds.
- X-Load average over time, updated once per mode cycle.
CAVEATS
The command line will change a lot Real Soon Now(tm). Be sure to
check on this when installing new versions.
The "idle" stat on the time screen (D) reflects how much idle time
your system has had since booting. So, if you leave the machine
running at night without doing anything, you'll have at least 50%
idle. :)
KNOWN BUGS
- Only supports 20x4 displays, so far.
- Doesn't lock the com port... yet.
- Doesn't always shut down correctly when killed by init. (?)
(during "shutdown -h now", for example)
CONTACT INFORMATION
LCDproc was written by William Ferrell (choadster@earthlink.net) and
Scott Scriven (scriven@cs.colostate.edu).
Matrix Orbital (http://www.matrix-orbital.com/) designed and
manufactures the LCD displays.
The newest version of LCDproc should be available from here:
http://lcdproc.omnipotent.net/
LEGAL STUFF
LCDproc is released as "WorksForMe-Ware". In other words, it is free,
kinda neat, and we don't guarantee that it will do anything in
particular on any machine except the ones it was developed on.
It is technically released under the GNU GPL license (you should
have received the file, "COPYING", with LCDproc) (also, look on
http://www.fsf.org/ for more information), so you can distribute and
use it for free -- but you must make the source code freely available
to anyone who wants it.
For any sort of real legal information, read the GNU GPL (GNU General
Public License). It's worth reading.
+674
View File
@@ -0,0 +1,674 @@
<!DOCTYPE book PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
<book>
<bookinfo>
<date>1999-02-08</date>
<title>LCDproc User's Guide</title>
<subtitle>Installation and Client Development Guide</subtitle>
</bookinfo>
<toc></toc>
<chapter>
<title>Introduction</title>
<para>LCDproc is a system status monitoring application that drives a
variety of different LCD-based display devices. It provides a powerful
framework for networked statistic gathering, adding new monitors or
LCD-aware applications, and adding new devices.
</para>
<para>The client shipped with LCDproc v0.4 can connect to an LCDproc
server either on the local system or on a remote system as long as it
is reachable. It extracts the same statistics regardless of where it
sends this information. The statistics it gathers include CPU
utilization, memory utilization, disk utilization, network utilization,
system uptime, time, and date, and so on. It displays this information
in assorted ways, and can be tailored to taste.
</para>
<sect1>
<title>Supported Hardware</title>
<para>As shipped, LCDproc v0.4 supports LCD modules from Matrix
Orbital Corporation, HD447800-controlled LCDs, and can emulate an LCD with
the curses library or plain, raw, ugly text.
</para>
<sect2>
<title>Matrix Orbital LCD Modules</title>
<para>
LCDproc was born out of original tinkering by William Ferrell with
one of these LCD modules. Their ease of installation and use (as well
as the amazing amount of patience demonstrated by the folks at
Matrix Orbital whilst William figured things out) meant one less thing
to worry about during the early stages of LCDproc's life.
</para>
<para>
These 20x4 alphanumeric modules are connected via standard DB-9 cabling and
connectors. They draw either 5V or 12V, depending on the module purchased,
and are attached with a standard floppy cable connector (with a slightly
modified wire configuration).
</para>
<para>
Once connected, using them is a breeze. They can operate at any number of
different baud rates and serial configurations, but normally they run at
19,200 baud, 8-N-1, making them quite quick. Sending ASCII to the module
will make it simply display that text at its current cursor position. The
module has a built-in BIOS that recognizes commands (sent by transmitting a
single-byte "marker" signifying that a command is on the way, followed by
the single-byte command character itself along with any parameters, if needed)
allowing the programmer to clear the screen, position the cursor anywhere,
define custom characters (up to 8 at a time), draw bar graphs and large numbers,
change the LCD's contrast, and so on.
</para>
<para>
The BIOS included also implements line-wrapping (i.e. writing past the
twentieth character on the first row will automatically move the cursor
to the first character on the second row), and screen scrolling (i.e.
writing past the twentieth character on the fourth row causes the whole
screen to scroll up one row, clearing the fourth line and positioning the
cursor at the first character on that line).
</para>
<para>
These modules are fast. Using the auto-line-wrap feature and disabling
the auto-scrolling feature, the screen can be updated thirty times per
second if *every* character on the screen is changed. If updating less
than the whole screen, the LCD can update faster than can be seen by
the human eye. This, of course, more than meets LCDproc's needs.
</para>
</sect2>
<sect2>
<title>HD44780 Controller-Based LCDs</title>
<para>
These LCDs are controlled by the Hitachi HD44780 LCD controller, and
connect to a system's parallel port. Not much else is known about these
devices at this time. [Update this section].
</para>
</sect2>
<sect2>
<title>LCD Emulation</title>
<para>
LCDproc can emulate an LCD on a curses terminal (or even on a dumb terminal
by writing raw text out, if you're that desperate). The output is confined to
a 20x4 character area, just like on a real LCD, and can be "swallowed" into
window manager panels such as fvwmbuttons.
</para>
</sect2>
</sect1>
<sect1>
<title>LCDproc Documentation</title>
<para>
This document is intended to be full, complete documentation for
LCDproc. While some information presented in this document is present
in assorted files scattered across the LCDproc distribution tarball,
this document is meant to encompass all aspects of dealing with
LCDproc, from installation, all the way to developing custom clients
using LCDproc's client/server API.
</para>
<para>
README and INSTALL files will always be distributed with LCDproc, along
with the requisite copyright and licensing information, but this document
will eventually replace the content of the README and INSTALL files.
</para>
<para>
This documentation was written in SGML and
<ULINK URL="http://www.oasis-open.org/docbook/">DocBook</ULINK>. SGML is a
generalized markup language (of which HTML is a subset), and DocBook is a set of
layout tools and markups using SGML that lends itself quite nicely to the publishing
of technical manuals and software documentation like this.
</para>
<para>
In Linux, one can produce DVI, PostScript, HTML, Unix Manual Pages and Info
pages from the same SGML/DocBook source using
<ULINK URL="http://www.sgmltools.org/">SGMLtools</ULINK>. Take a look at this set
of tools if you have any large-scale documentation to write. It might have a bit of
a steep learning curve, but it's certainly worth the effort.
</para>
</sect1>
</chapter>
<chapter>
<title>Installation</title>
<para>
This chapter covers the installation process for both LCDproc, and the actual LCD
module intended for use with LCDproc. Since our experience has involved almost
exclusively the Matrix Orbital modules, we will spend little time on installation
instructions for other hardware.
</para>
<para>
If you have successfully installed LCDproc-compatible hardware and would care to
document how you did so, please e-mail the author of this book
(choadster@earthlink.net).
</para>
<para>
We will examine the installation process of LCDproc and the hardware it drives in
small steps, as it is vitally important to pay close attention to detail during
hardware installation to avoid damaging equipment, as well as during LCDproc's
installation, since things have become a little more complicated since LCDproc's
split into a client and server model.
</para>
<para>
First, hardware installation is discussed. If you are not using physical LCD
hardware to run LCDproc, you can safely skip the hardware installation sections and
move on to the software installation sections.
</para>
<sect1>
<title>Hardware Installation</title>
<para>
Regardless of what specific type of hardware you intend to use with LCDproc,
installation is usually straightforward, and requires only a few steps. Regardless,
you must use caution while working inside your computer system or with any hardware
attachments.
</para>
<Warning>
<Title>Warning!</Title>
<para>
Installing new hardware inside a computer system can be dangerous to both
system components and the installer. Use caution whenever adding a component
to the inside of your system, altering a power cable, or physically mounting
a device inside a computer system.
</para>
<para>
When installing hardware inside a computer, make sure it's turned off and that
its power is disconnected. This is especially important when making changes to
power cables (as some LCD modules require).
</para>
</Warning>
<sect2>
<title>Matrix Orbital LCD/VFD Module Installation</title>
<para>
The LCD and VFD modules from Matrix Orbital are relatively straightforward
to install. With a small, regular (flat-head) screwdriver, a spare floppy drive
power cable, and a bit of luck, installation will take less than an hour.
</para>
<para>
These installation instructions assume that you are installing the module into
a PC or PC-style system (one with AT- or ATX-compliant power cabling) and that
you have some idea of where you intend to permanently mount the module. For
mounting ideas and tips, refer to the section "Mounting" below.
</para>
<Tip>
<Title>Before you start</title>
<para>
Your Matrix Orbital LCD or VFD module should be clearly marked with an
indication of the module's power requirements. It should be either a 5 volt
or 12 volt unit. You should have this information available before proceeding.
</para>
</tip>
<sect3>
<title>Power Cable Modification</title>
<para>
The first step in installing the module is making the necessary modifications
to a floppy drive power cable in order to provide power to the module. The
modifications must be made based on the module's power requirements -- either
5V or 12V -- depending on which module you purchased.
</para>
<para>
A standard floppy drive power cable has a smaller connection than a "normal"
PC power connector. However, like a "normal" power connector, it has four
wires: one yellow, one red, and two black. The red wire provides +5V power, and
is "hot" or live when the system is powered up. The yellow wire provides +12V
power, and is also hot when the system is powered up. Both black wires are
ground.
[TODO: INCLUDE A FIGURE HERE SHOWING A "STANDARD" FLOPPY CONNECTOR]
</para>
<para>
One of the hot wires and one of the black wires will not be needed for your
module's power connection; they will be completely removed when the power cable
modification is complete.
</para>
<Warning>
<title>Warning!</title>
<para>
Do NOT make this modification to a power cable attached to a running
system! Electrocution resulting in personal injury and/or damage to the
system can result.
</para>
</Warning>
<para>
Using a regular screwdriver, press down the small metal locking flap of one
of the two black wires on the small end of the cable, and pull the black wire
from the connector. Using a pair of needle-nose pliers, squeeze the other end
of the same black wire, and pull it out of the large end of the cable. This
black wire can be set aside; it will not be used for the module's power
connection. Either wire can be safely removed; you may safely remove either
wire.
[TODO: INCLUDE A FIGURE HERE SHOWING THIS PROCESS]
</para>
<para>
Next, using the same procedure, remove the unneeded hot wire. If your module
is 5V, you do not need the yellow (+12V) wire. Conversely, if your module is
12V, you do not need the red (+5V) wire. The removed wire can be set aside;
it will not be used for the module's power connection.
[TODO: INCLUDE A FIGURE HERE]
</para>
<para>
The floppy power connector should now have only two wires attached to it.
Leave the larger end alone from now on; these connections are correct (the
larger end connects to your system's power mains). Move the two remaining wires
to the outside connectors on the small end of the cable. Orientation does not
particularly matter here; the connector will fit on the module's receptacle
in either orientation.
[TODO: A FIGURE HERE]
</para>
<para>
You should now have a properly modified power connector. When physically
attaching this connector to the module, the black (ground) lead should be
connected to the pin labelled GND, while the colored (+5V/+12V) lead should
be connected to the pin labelled +5V/+12V.
</para>
<para>
Test the power connection before connecting the data line or mounting the
module. Connect the module to the power connector, and the connector to your
system's power mains. Turn the system on.
</para>
<Caution>
<Title>Caution</Title>
<para>
If the module does not immediately display its initial BIOS screen and light
up its backlight (or light up the screen if a VFD module is being used),
<EMPHASIS>immediately</EMPHASIS> power down the system, disconnect the module
and connector, and double-check the modification before trying again. Do NOT
leave the system on if the module does not immediately respond; module or
system damage could result.
</para>
</Caution>
<para>
When the LCD powers up and displays its initial BIOS screen, you've gotten the
power connection wired properly and can now properly mount the module and make
its final connections. Matrix Orbital Corporation sells a PC bay insert mount
for the 20x4 and 20x2 modules (LCDproc, however, only supports the 20x4 at
present). The inserts provide an easy means of mounting the LCD modules inside
a PC using one (for the 20x2) or two (for the 20x4) 5 1/4" bays.
</para>
<Note>
<title>Note</title>
<para>
Describing how to physically mount the module in a PC case is beyond the
scope of this document; LCDproc's website contains more detailed mounting
information and examples.
</para>
</Note>
</sect3>
<sect3>
<title>Serial Connection</title>
<para>
The LCD module uses a standard DB9 serial connector. You can attach the module
to your system using a direct cable to the motherboard, or by removing one of
your system's serial ports from the back of the case, then connecting it to a
standard serial cable to the module.
</para>
<para>
While connecting the serial cable to the module, be sure to configure the
module's serial interface settings. Typically, setting the module to its fastest
setting (19,200 baud, 8-N-1) is recommended. At present, the Matrix Orbital
module driver in LCDproc is hardwired to use these settings; using different
ones will require minor changes to the driver's code.
</para>
</sect3>
</sect2>
<sect2>
<title>Other Display Types</title>
<para>
At present, we do not have any detailed information regarding the installation
of other types of LCDs. If you have any information that would be useful to
include here, please contact William Ferrell
(<ULINK URL="mailto:choadster@earthlink.net">choadster@earthlink.net</ULINK>).
</para>
</sect2>
</sect1>
</chapter>
<chapter>
<title>LCDproc Distribution Layout</title>
<para>The current LCDproc distribution contains both the LCDproc server
and the LCDproc client. It also contains sparse documentation (this
document will hopefully solve this problem), and a sample Perl client.
[THIS WILL CHANGE -- REWRITE THIS PARAGRAPH]</para>
<sect1>
<title>Basic Layout</title>
<para>
LCDproc is distributed in a single archive containing both the client(s)
and the server:
<SimpleList columns=2>
<Member>clients/</Member>
<Member>docs/</Member>
<Member>old/</Member>
<Member>server/</Member>
<Member>server/drivers/</Member>
<Member>shared/</Member>
<Member>tests/</Member>
<Member>BUGS</Member>
<Member>COPYING</Member>
<Member>INSTALL</Member>
<Member>Makefile</Member>
<Member>Makefile.config</Member>
<Member>README</Member>
<Member>TODO</Member>
<Member>WHATSNEW</Member>
<Member>Contains the LCDproc client and the sample Perl client</Member>
<Member>Documentation (sparse at the moment)</Member>
<Member>Contains older source code, unused in compiling v0.4</Member>
<Member>Contains the LCDproc server</Member>
<Member>Contains LCDproc's device drivers</Member>
<Member>Contains shared code</Member>
<Member>Contains test code not used in compiling</Member>
<Member>A list of known bugs in the current version</Member>
<Member>The GNU General Public License</Member>
<Member>Installation Instructions</Member>
<Member>File for the "make" utility, used to compile LCDproc</Member>
<Member>Contains compile-time user-tunable defaults for LCDproc</Member>
<Member>Read this file first! Contains basic information regarding LCDproc,
what it does, how it works, and how to start building it.</Member>
<Member>List of planned changes and improvements.</Member>
<Member>List of revisions that have been made to LCDproc throughout its
development. [This should be changed to ChangeLog]</Member>
</Simplelist>
</para>
</sect1>
<sect1>
<title>A Stroll Through the Code</title>
<para>
This section attempts to document how LCDproc works. Both the server and
the client are explored at the source code level. This section was written
as an exercise for the author to help him better understand LCDproc's
inner workings, allowing him to better document LCDproc for end users and
developers. Feel free to skip past this entire section unless you really
feel like reading how LCDproc renders screens, manages clients, deals with
input, and handles trouble.
</para>
<sect2>
<title>The LCDproc Server, LCDd</title>
<para>
LCDd is the central component of LCDproc. It is responsible for several
different activities:
<SimpleList>
<Member>Initializing the output device</Member>
<Member>Initializing the incoming socket</Member>
<Member>Listening for client connections and accepting them</Member>
<Member>Storing screens provided by clients</Member>
<Member>Storing stats provided by clients</Member>
<Member>Choose the best screen to display on the LCD based on order of
client and screen arrival, and by priority</Member>
<Member>Provide a rich screen-drawing widget set for clients to use</Member>
<Member>Render screens to the LCD</Member>
<Member>Gracefully handle dead sockets and clients</Member>
<Member>Gracefully remove screens and clients when asked to by clients or
the user</Member>
</SimpleList>
</para>
<para>
To accomplish all this, LCDd splits into dozens of source files to handle
different bits of the job. We will examine each of these source files one by
one (and, to make things easier, in alphabetical order). Header files (*.h)
will not be included in this discussion.
</para>
<sect3>
<title>server/client_data.c</title>
<para>
This file appears to contain code that handles the creation and destruction
of linked lists for client data.
</para>
</sect3>
<sect3>
<title>server/client_functions.c</title>
<para>
This file actually describes itself as its first comment! It contains
definitions for all the functions that the clients can run. They are to
be called only from server/parse.c.
</para>
<para>
Here the functions that clients call when connected to LCDd are actually
defined and performed.
</para>
</sect3>
<sect3>
<title>server/clients.c</title>
<para>
This file contains code allowing LCDd to handle client connections and
data structures. It contains functions to initialize the internal list
of clients, terminate client connections, add new clients to the list,
add, remove, and retrieve messages to clients' message queues, and
locating a client's socket.
</para>
</sect3>
<sect3>
<title>server/input.c</title>
<para>
This file contains functions that handle input from keypads, joysticks,
etc.
</para>
</sect3>
<sect3>
<title>server/main.c</title>
<para>
Where the action is.
</para>
<para>
This file contains LCDd's main() function and supporting code. It begins
life by configuring signal handlers, then by immediately initializing the
LCD drivers. (Huh?) It then parses the command line, configuring the
LCD driver appropriately, then initializes its internal lists and the
socket.</para>
<para>
Next, it forks into a daemon process (shedding its controlling terminal)
and enters the main loop. The main loop: listens for connections from
new clients and for input from already connected ones, parses all input
from connected clients, checks for input, then updates the screen list
and updates the LCD.
</para>
<para>
Also present are functions to handle graceful exits when various signals
are received, and a help screen.
</para>
</sect3>
<sect3>
<title>server/menu.c</title>
<para>
This appears to be code to handle server-generated menu screens on the LCD.
[I don't understand this file in the slightest ... study this harder later]
</para>
</sect3>
<sect3>
<title>server/parse.c</title>
<para>
This file contains code that parses input from the clients.
parse_all_client_messages() is called once each time through main()'s loop.
</para>
</sect3>
<sect3>
<title>server/render.c</title>
<para>
This file contains code that actually generates the full screen data to
send to the LCD. draw_screen() takes a screen definition and a counter as its
arguments. It builds the screen according to the definition, and using the
counter as a reference.
</para>
</sect3>
<sect3>
<title>server/screen.c</title>
<para>
This file stores all the screen definition-handling code. Functions here
provide means to create new screens and destroy existing ones. Screens are
identified by client and by the client's own identifiers for screens.
</para>
</sect3>
<sect3>
<title>server/screenlist.c</title>
<para>
This appears to be the screenlist handler that decides which screen to
display based on priorities and screen creation order.
</para>
</sect3>
<sect3>
<title>server/serverscreens.c</title>
<para>
This file contains code to allow the server to generate its own screens.
Currently, only the server status screen is provided, showing total number
of connected clients, and the combined total of screens they provide (this
count does not include the server's screens).
</para>
<para>
It is interesting to note that the server creates a special screen
definition for its screens, but uses the same widget set made available
to clients.
</para>
</sect3>
<sect3>
<title>server/sock.c</title>
<para>
This file contains all the sockets code used by the server. This contains
the code called upon by main() to initialize the listening socket, as well
as code to deal with sending messages to clients, maintaining connections,
accepting new connections, closing dead connections (or connections
associated with dying/exiting clients), etc.
</para>
</sect3>
<sect3>
<title>server/widget.c</title>
<para>
This file houses code that handles the creation and destruction of widget
objects for the server. These functions are called using the arguments
passed by the client, then they store the specified widget into a generic
container that is parsed later by the screen renderer.
</para>
</sect3>
<sect3>
<title>server/drivers/*</title>
<para>
These are the individual driver files. Each driver allows LCDproc to display
its output on a different device. A driver is responsible for accepting
LCD-like handling instructions from LCDd, and for returning input from the
device to LCDd.
</para>
<para>
Currently, drivers provided are MtxOrb, hd44780, curses, and joy. The
joystick (joy) driver doesn't provide output, but only input.
</para>
</sect3>
</sect2>
<sect2>
<title>The LCDproc Client</title>
<para>
The client shipped with LCDproc performs all of the statistic gathering
previously performed by LCDproc v0.3.x. Instead of driving the LCD directly,
in this version it now connects to LCDd and sends its screens and data there.
</para>
<para>
In this implementation of the statistic-gathering portions of LCDproc, the
layout departs substantially from the older v0.3.x code. Each screen is
generated by functions stored in separate files -- one file per screen.
This keeps files smaller, and code much simpler to maintain and update.
</para>
<para>
The client appears to use files from the share/ tree as well.
</para>
<sect3>
<title>clients/lcdproc/batt.c, chrono.c, cpu.c, disk.c, load.c, mem.c</title>
<para>
These files contain the functions implementing all the screens provided by
LCDproc.
</para>
<para>
Each contains several functions, mostly related to actual statistic gathering.
They are also apparently responsible for actually transmitting their screen
definitions to the server and answering the server's requests for statistic
updates. The functions here do *no* checking to determine if they are being
asked for. They *do* check to see if they need to create a new screen
definition or merely update it. It would appear that the client's main() or
other higher-level function is responsible for calling this function when the
server asks for an update.
</para>
</sect3>
<sect3>
<title>clients/lcdproc/main.c</title>
<para>
This file contains the LCDproc client's main() function, as well as a few
supporting functions.
</para>
<para>
It first declares and fills a modelist (used only internally by this client)
that determines which screens will run by default (if the user doesn't
specify a custom modelist on the command line). The first thing main() itself
does is configure the signal handlers.
</para>
<para>
Next, it parses the command line for options, yelling at the user if an
invalid or nonsensical argument has been specified. After it has done this,
it tries to open a socket connection to LCDd. If successful, execution
continues. If unsuccessful, the client exits gracefully.
</para>
<para>
Assuming a valid socket connection is established, it sends the "hello"
command to the server, introducing itself and convincing the server that yes,
it really *should* serve this client. Next, it calls the mode_init() function
which appears to set up data structures for the various modes, and then finally
the main_loop() function which executes indefinitely until the client is
killed or is asked to stop. Then the program exits cleanly.
</para>
<para>
main_loop() is defined in this file as well. The main loop listens for any
input from the server, and reacts on what it receives. It appears capable of
dealing with keypresses, listen/ignore signals, and menu activity. After it
has reacted appropriately to inputs, it runs the screen asked for by the
server.
</para>
<para>
The old main() is commented out, but included here for reference. Eventually,
this will be removed from LCDproc's source. For now, however, it serves as a
useful reference.
</para>
</sect3>
<sect3>
<title>clients/lcdproc/mode.c</title>
<para>
This file contains functions responsible for initializing mode screens and
calling the appropriate mode screen update function when asked to do so.
main_loop() passes the server's parsed messages to this function to enable it
to select which screen is called for.
</para>
<para>
This file also contains reread() and getentry() functions which are used by
many of the mode screens.
</para>
</sect3>
</sect2>
<sect2>
<title>Shared Files</title>
<para>
Both LCDd and the LCDproc client make extensive use of linked lists and sockets
code. Much of that code is shared, and stored in the shared/ tree.
</para>
<sect3>
<title>shared/config.c</title>
<para>
This file contains the beginnings of configuration file code.
</para>
</sect3>
<sect3>
<title>shared/LL.c</title>
<para>
This file contains all of the functions used in implementing LCDproc's
linked lists. Functions exist here to create new lists, destroy lists,
remove an entry from a list, add an entry to a list, move a pointer to
the beginning or end of a list, move a pointer to the next item in a
list, the previous item of a list, or to retrieve individual items from
a list.
</para>
</sect3>
<sect3>
<title>shared/sockets.c</title>
<para>
This file contains all the functions used in implementing LCDproc's socket
handling capabilities. Full bi-directional communication is implemented by
these functions.
</para>
</sect3>
<sect3>
<title>shared/str.c</title>
<para>
This file contains only one function, get_args(). It appears to parse
command lines (or command line-like strings) for arguments, and returns them
in a more useful form.
</para>
</sect3>
</sect2>
</sect1>
</chapter>
</book>
+126
View File
@@ -0,0 +1,126 @@
Allo... (warning: this was written as I thought it up :)
Ideas for implementing menus...
We've got a data structure called "Menu_Item", which has (for starters):
Title -- Text to display
Child -- Sub-Menu to recurse into, if item is picked
Exec Function -- Function to call if the item is picked
An item must not have both a child and an exec function.
The DoMenu(main_menu) handles all input and either calls ExecFunction,
if the picked item has one; or recurses into the Child menu. The
ExecFunction returns a value to specify whether the menus should go
away, back up one level, or stay as-is. Also, a menu title (label)
can be specified by giving neither a Child nor a Function.
The up/down arrows, blinking, scrolling, etc, are handled by DoMenu().
This gives us the functionality of a standard pull-down menu.
However, we need more functionality than that. We need checkboxes,
sliders, and a way to move items up/down.
So...
The ExecFunction should take a parameter, telling whether the item was
simply picked, or if it had a +/- pressed on it. This lets us change
a value from the menu.
We should also add another function to the MenuItem struct:
Data Function -- returns true, false, or 0-255.
This lets us find out if a checkbox should be checked, or where a
slider should be. DoMenu() will figure out what widget it's dealing
with (if any), and adjust its display accordingly.
But we still can't move menu items up/down.
...
Perhaps... This might work better:
Title -- Text
Type -- menu, function, checkbox, slider, mover
Data -- Child, ExecFunc, CheckFunc, SlidFunc, ???
When an item is picked, DoMenu() decides what to do based on type.
--"Menus" will recurse into the "data", assuming it's a child menu.
--"Function"-type items will have their function called.
--CheckBox-type items will have their function called with a "read"
parameter to get an on/off signal, and called with a "set" signal when
picked.
--Sliders will have the same "read" thing, and the "set" function will
take a plus or minus parameter.
--The Movers will act like a label until picked, and then the +/- keys
will both rearrange the menu, and send the item a signal of some sort
to indicate what happened. It'll act like a label again after the
user presses Enter again.
The "Data" field will really be a "void *", which is C's "generic"
data type...
Anyway, this sort of thing would be declared this way:
========================================================================
Menu MainMenu = {
"MENU", NULL, NULL, // Title
"Options", MENU_TYPE, (void *)OptionsMenu,
"Kill LCDproc", FUNC_TYPE, (void *)Shutdown_func,
NULL, NULL, NULL,
};
Menu OptionsMenu = {
"OPTIONS", NULL, NULL, // Title
"24-hour Time", CHEK_TYPE, (void *)Time24_func,
"Contrast...", SLID_TYPE, (void *)Contrast_func,
NULL, NULL, NULL,
};
///////////////// Elsewhere, we declare these...
void Shutdown_func()
{
// Do something here...
return MENU_KILL; // or MENU_CLOSE, or MENU_OK, or MENU_ERROR
}
int Time24_func(int input)
{
if(input == READ) return status;
if(input == SELECT) toggle_status(); // does something.
return (status | MENU_OK);
// The status is "or"-ed with the MENU value to let DoMenu()
// know what to do after selecting the item. (two return
// values in one. :)
// Also, "MENU_OK" happens to be zero, so it doesn't matter
// unless you want something else (like MENU_CLOSE)
}
int Contrast_func(int input)
{
if(input == READ) return status;
if(input == PLUS) increment_status(); // does something.
if(input == MINUS) decrement_status();// does something.
return (status | MENU_OK);
}
========================================================================
The main reason I like this is that it completely separates the menu
definitions from the code which actually handles it. We have *one*
function which does everything menu-related.
Also, we'd include a table of some sort to match names to functions,
so that the user can create their own menus with the functionality
already provided. (including user-defined "functions", which will be
rather limited but still useful)
+298
View File
@@ -0,0 +1,298 @@
LCDproc client/server protocol
---------------------------------------------
QUICKSTART
----------
- Open a socket to the LCDproc port (usually 13666).
- say "hello"
- the server will notify you of a good connection, and some info
on the type of display available.
- Identify yourself. "client_set name some_sort_of_name"
- Add a new screen. "screen_add my_screen"
- Put a widget on the screen.
"widget_add my_screen my_widget string"
- Now, update the widget whenever your status info changes...
"widget_set my_screen my_widget 1 1 Booger!"
- When you're done, just close the socket.
- You probably want to read on for more information, once you've
gotten the LCDproc server to display something. :)
DETAILS
-------
There are two parts to the spec:
A language for client/server to interact with.
A protocol guiding interactions.
=================== The protocol ==================================
The protocol is context-free. So, no commands require responses; and
responses are simply commands.
The client may send updated info at any time, and the server decides
whether to display it. An ideal communication may flow like this:
client->server server->client
------------------ -------------------
(idle) (nothing)
(idle) "I'm listening"
new stats... (nothing; displays updated stats)
new stats... (nothing...)
new stats... (nothing...)
new stats... "Okay, be quiet"
(idle) (nothing; displays new screen)
... ...
(idle) "Your slider moved up"
Set slider value: 43 (nothing; displays updated slider)
(idle) (nothing)
... ...
But the client could safely continue to send new stats, knowing that
the server isn't listening and won't display it. Also, the client could
ignore the slider change, and the slider onscreen simply wouldn't move.
=================== The syntax ==================================
The language is ascii-based, so a human can telnet to a port and talk
to the server. This helps with development and debugging.
With that in mind, a commandline-like syntax seems good:
function arg1 arg2 arg3 ...
The syntax dictates that the first word is a function name, and the
rest of the line is passed to that function as an argument.
String-type arguments should always come last. So, for example:
set_label 23 3 2 Hey, booger. What's up?
The first argument is a label id number, the 2nd and 3rd are x,y
coordinates onscreen, and the rest of the line is a string.
=================== The command set ==================================
The naming convention dictates that function names are lower-case,
with underscores ("_"'s) between words.
The naming convention also requires that function-name words go in
descending order. So, "screen_set_priority" would be okay, but
"set_screen_priority" would not.
Id's are strings. (the "#id" things)
In general, we're trying to keep the command set small. Especially the
server->client functions, so that clients won't have to handle a lot of
different types of input.
Now, the function list:
client->server functions
-------------------------
hello
Client init. You must send this before the server will pay
any attention to you. You'll get some info about the server
in return... (a "connect" string)
client_set [name #id]
Set client's name and other info
client_add_key #id
Tells the server the client can handle keypresses of type #id.
#id is probably just "A", "B", and so on...
All keypresses are disabled by default, so you'll have to tell
the server which ones you want to accept...
client_del_key #id
Tells the server to never send that keypress.
All keypresses are disabled by default.
screen_add #id
Add a new screen
screen_del #id
Remove a screen
screen_set #id [priority integer] [name "my_name"] [duration integer]
[wid width] [hgt height]
Initialize a screen, or reset its data.
Priority values are as follows:
0 You feel like getting kicked off the server, don't you?
1 The world is about to explode
16 Emergency priority
32 Very high priority (important)
64 High priority (normal)
128 Normal (recommended)
192 Low priority (normal)
224 Very low priority (very unimportant)
240 Boring as hell
255 This screen won't show up very much even if there are
no other screens queued...
An example of using priorities is as follows.
Imagine you're making an mp3 player for LCDproc. When the
song changes, it's nice to display the new name immediately.
So, you could set your screen's priority to 64, wait for
the server to display (or ignore) your screen, then set the
screen back to 128. This would cause the mp3 screen to
show up as soon as the one onscreen was finished, then
return to normal priority afterward.
Or, let's say your client monitors the health of hospital
patients. If one of the patients has a heart attack, you
could set the screen priority to 16 (emergency), and it
would be displayed immediately. It wouldn't even wait for
the previous screen to finish. ... And it would stay there
most of the time until the user did something about it.
A priority of 1 would stay onscreen permanently, with
flashing lights and other visual cues if possible.
... Please *don't* use this priority. :)
The duration can be either a positive number, or -1. A
positive number indicates how many display frames the screen
should last for. A 0 or -1 means that the server should use
"auto" duration, which is probably a good idea. This will be
whatever the user wants. It defaults to 4 seconds (32
frames), or will be calculated for things such as scrollers.
widget_add #screen #id type [-in #id]
Add something onscreen
Widget types can be any of the following: "string", "hbar",
"vbar", "title", "icon", "scroller", "frame", ... more later?
Widgets are drawn in the order you create them.
You can put a widget inside a frame by adding "-in #id", where
#id is the name of a frame.
widget_del #screen #id
Kill something onscreen
widget_set #screen #id data
Set (reset) widget's data
Note that the "string" type should be used for frame buffers.
Strings should not be bigger than the screen.
The widgets take these arguments for data:
string x y text
hbar x y length_in_pixels
vbar x y length_in_pixels
icon x y binary_data
title text
scroller left top right bottom direction speed text
A scroller is a string which scrolls.
This is useful for things such as the disk
usage screen, which may be very tall.
The speed is how many display frames to delay
between scrolling. Each display frame is
1/8th of a second, by default.
Direction must be "h" or "v".
Positive speeds indicate frames per movement.
Negative speeds indicate movements per frame.
frame left top right bottom wid hgt dir speed
Frames occupy the area (left, top)-(right,bottom)
onscreen, and the inside area is wid x hgt.
The inside may be bigger than the actual size,
so that the frame will scroll.
server->client functions
-------------------------
connect args
Verifies connection; gives info about the LCD, etc...
bye
Notifies the client of a server shutdown.
huh? [info]
Notifies the client of a request error.
listen [#screen [#widget [#widgets...]]]
Notifies client that "server is listening for data".
ignore [#screen [#widget [#widgets...]]]
Tells the client "shut up".
key #id
Sends a keypress to the client.
--- Not implemented yet ---
The functions below are planned but not completed.
client->server functions
-------------------------
menu_add #id
Add a new menu.
menu_del #id
Get rid of a menu.
menu_set [top] [name my_menu_name]
if (top) Gets added to "Client Menus".
else Client must insert it into its own menu heirarchy.
menu_item_add #menu #id
Add a new, blank menu item.
menu_item_del #menu #id
Delete a menu item.
menu_item_set #menu #id type [value] text
(re)Set the menu item's data.
If type is "checkbox" or "slider" or "menu", [value] should
contain appropriate info. (like true, 43, or #menuid)
backlight [on] [off] [blink] [flash] [toggle]
Requests that the backlight be toggled... The backlight
command will likely be ignored, but users can enable it if
desired.
The LCDproc server has [will have] several backlight modes:
On Stays on all the time
Off Stays off all the time
Load? Turns off when the load average is low
Shell? Controlled by a user-supplied shell script
Open Can be controlled by all clients
Vis Controlled by the currently visible client
driver_add #id? type args
Start up a new output driver.
Nice if you want to check on your machine remotely with the
curses driver.
driver_del #id? (or type)
Stop a running output driver.
Good for reclaiming your joystick when you want to play games...
server->client functions
-------------------------
menu #menu #item #action
Tells the client that a menu item was selected/used/etc...
The action can be "click", "up", or "down". The client should
handle this according to what type of menu item has been
activated, and should probably send the server a new item
definition if the item was a checkbox or slider.