[Lcdproc] picolcd patch against current CVS (20070312)
Gatewood Green
woody@nitrosecurity.com
Mon Mar 12 20:23:01 2007
This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--------------enigFA62A4346E097BC97891B5A1
Content-Type: multipart/mixed;
boundary="------------060705070503080508070909"
This is a multi-part message in MIME format.
--------------060705070503080508070909
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Attached is an updated patch for current CVS to support to the
Mini-Box.com USB LCD (picoLCD) as shipped in the M300.
http://www.mini-box.com/picoLCD-20x2-OEM
http://www.mini-box.com/Mini-Box-M300-LCD
This pass also incorporates cleanup suggestions from Peter.
Comments and feedback welcome.
Thanks,
Woody
--=20
-----------------------------------------------------------------
Gatewood Green Software Engineer/System Admin
Email: woody@nitrosecurity.com
http://www.nitrosecurity.com/ NitroSecurity
-----------------------------------------------------------------
Imagine, if you will, a world in which there are no hypothetical
situations...
--------------060705070503080508070909
Content-Type: text/plain;
name="cvs200703121330MDT-lcdproc.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline;
filename="cvs200703121330MDT-lcdproc.patch"
diff -uNrp lcdproc-orig/acinclude.m4 lcdproc/acinclude.m4
--- lcdproc-orig/acinclude.m4 2007-02-04 14:14:55.000000000 -0700
+++ lcdproc/acinclude.m4 2007-03-12 13:38:05.000000000 -0600
@@ -8,14 +8,14 @@ AC_ARG_ENABLE(drivers,
[ bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,=
EyeboxOne,]
[ g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,ir=
man,]
[ joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,mtc_s1=
6209x,]
- [ MtxOrb,NoritakeVFD,pyramid,sed1330,sed1520,serialP=
OS,]
+ [ MtxOrb,NoritakeVFD,picolcd,pyramid,sed1330,sed1520=
,serialPOS,]
[ serialVFD,sli,stv5730,svga,t6963,text,tyan,ula200,=
xosd]
[ 'all' compiles all drivers;]
[ 'all,!xxx,!yyy' de-selects previously selected drive=
rs],
drivers=3D"$enableval",
drivers=3D[bayrad,CFontz,CFontz633,curses,CwLnx,glk,lb216,lcdm001,MtxOr=
b,pyramid,text])
=20
-allDrivers=3D[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,EyeboxOn=
e,g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,joy,lb216,lcdm001=
,lcterm,lirc,MD8800,ms6931,mtc_s16209x,MtxOrb,NoritakeVFD,pyramid,sed1330=
,sed1520,serialPOS,serialVFD,sli,stv5730,svga,t6963,text,tyan,ula200,xosd=
]
+allDrivers=3D[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,EyeboxOn=
e,g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,joy,lb216,lcdm001=
,lcterm,lirc,MD8800,ms6931,mtc_s16209x,MtxOrb,NoritakeVFD,picolcd,pyramid=
,sed1330,sed1520,serialPOS,serialVFD,sli,stv5730,svga,t6963,text,tyan,ula=
200,xosd]
=20
drivers=3D`echo $drivers | sed -e 's/,/ /g'`
=20
@@ -271,6 +271,23 @@ dnl else
DRIVERS=3D"$DRIVERS NoritakeVFD${SO}"
actdrivers=3D["$actdrivers NoritakeVFD"]
;;
+ picolcd)
+ AC_CHECK_HEADERS([usblcd.h],[
+ AC_CHECK_LIB(usblcd, main,[
+ LIBUSBLCD=3D"-lusblcd"
+ DRIVERS=3D"$DRIVERS picolcd${SO}"
+ actdrivers=3D["$actdrivers picolcd"]
+ ],[
+dnl else
+ AC_MSG_WARN([The picolcd driver needs the usblcd library])
+ ],
+ [-lusblcd]
+ )
+ ],[
+dnl else =20
+ AC_MSG_WARN([The picolcd driver needs widgets.h, usblcd.h and usblcd=
_util.h from the usblcd package])
+ ]) =20
+ ;; =20
pyramid)
DRIVERS=3D"$DRIVERS pyramid${SO}"
actdrivers=3D["$actdrivers pyramid"]
@@ -395,6 +412,7 @@ AC_SUBST(LIBG15)
AC_SUBST(LIBGLCD)
AC_SUBST(LIBFTDI)
AC_SUBST(LIBXOSD)
+AC_SUBST(LIBUSBLCD)
])
=20
=20
diff -uNrp lcdproc-orig/docs/LCDd.8.in lcdproc/docs/LCDd.8.in
--- lcdproc-orig/docs/LCDd.8.in 2006-10-01 10:23:39.000000000 -0600
+++ lcdproc/docs/LCDd.8.in 2007-03-12 13:39:06.000000000 -0600
@@ -192,6 +192,9 @@ Matrix Orbital displays (except Matrix O
.B NoritakeVFD
Noritake VFD Device CU20045SCPB-T28A
.TP
+.B picolcd
+Mini-box.com USB LCD (picoLCD 20x2)
+.TP
.B pyramid
LCD displays from Pyramid (http://www.pyramid.de)=20
.TP
diff -uNrp lcdproc-orig/docs/lcdproc-user/drivers/picolcd.docbook lcdproc=
/docs/lcdproc-user/drivers/picolcd.docbook
--- lcdproc-orig/docs/lcdproc-user/drivers/picolcd.docbook 1969-12-31 17:=
00:00.000000000 -0700
+++ lcdproc/docs/lcdproc-user/drivers/picolcd.docbook 2007-03-12 13:45:00=
=2E000000000 -0600
@@ -0,0 +1,139 @@
+<sect1 id=3D"picolcd">
+ <title>The Mini-Box USB LCD (picoLCD 20x2) Driver (picolcd)</title>
+
+ <para>
+ This section covers the installation and use of the Mini-Box USB LCD (=
picoLCD=20
+ 20x2) display.
+ </para>
+ <para>
+ The picoLCD page indicates that the device can be connected via I2C or=
USART. =20
+ This lcdproc driver, however, is limited to the USB connected model.=20
+ </para>
+ <sect2 id=3D"picolcd-setup">
+ <title>Setting up the picoLCD</title>
+
+ <para>
+ The picoLCD device as used by this driver is USB connected and may be=
purchased=20
+ with an internal USB header connector (5-pin to 5-pin) or an external=
cable=20
+ (Type-A to 5-pin). See: http://www.mini-box.com/picoLCD-20x2-OEM. I=
t may also
+ come pre-installed on systems like the Mini-Box M300:=20
+ http://www.mini-box.com/Mini-Box-M300-LCD.
+ </para>
+ <para>
+ Using the USB LCD with this driver requires the usblcd library from M=
ini-box.com
+ (avaiable at http://www.mini-box.com/picoLCD-20x2-OEM). The usblcd l=
ibrary=20
+ requires libusb and libhcd. Your distribution may or may not already=
provide=20
+ these libraries. The only kernel driver required is the USB host con=
troller=20
+ driver (uhci_hcd on the M300) required to fire up the usb bus to whic=
h the LCD is=20
+ attached.
+ </para>
+ <para>
+ Lastly, the usbfs file system must be mounted on /proc/bus/usb.
+ <code>mount -t usbfs usbfs /proc/bus/usb</code>
+ </para>
+ <para>
+ Once connected and with libusblcd, libusb and libhid installed, testi=
ng the USB LCD=20
+ can be done with the "usblcd" program that comes with the usblcd libr=
ary. You can=20
+ also change the USB LCD's initial display (what it shows when you ini=
tialize the=20
+ device) by using the usblcd binary's "splash" command.
+ </para>
+ <para>
+ To use the picolcd with lcdproc, add picolcd to the lcdproc configure=
drivers option=20
+ (or use all) and then start LCDd with the "-d picolcd" option. The d=
river has=20
+ sane default options and the options that are user configurable are l=
imited to mostly=20
+ simple items, like contrast and which keys to lights up.
+ </para>
+ </sect2>
+ <sect2 id=3D"picolcd-options">
+ <para>
+ Contrast: 0-1000. 0 is visible, and 1000 is not on my M300. Default=
is 0. =09
+ </para>
+ <para>
+ Keylights: 0/1. 0 turns off the key LEDs and 1 turns them on. Defau=
lt is 1. =09
+ </para>
+ </sect2>
+ <sect2>
+ <para>
+ Key0Light: if Keylights is set to 1, you can disable the directional =
pad LED by=20
+ setting this value to 0. Default is 1.
+ </para>
+ </sect2>
+ <sect2>
+ <para>
+ Key1Light: if Keylights is set to 1, you can disable the F1 LED by se=
tting this value=20
+ to 0. Default is 1.
+ </para>
+ </sect2>
+ <sect2>
+ <para>
+ Key2Light: if Keylights is set to 1, you can disable the F2 LED by se=
tting this value=20
+ to 0. Default is 1.
+ </para>
+ </sect2>
+ <sect2>
+ <para>
+ Key3Light: if Keylights is set to 1, you can disable the F3 LED by se=
tting this value=20
+ to 0. Default is 1.
+ </para>
+ </sect2>
+ <sect2>
+ <para>
+ Key4Light: if Keylights is set to 1, you can disable the F4 LED by se=
tting this value=20
+ to 0. Default is 1.
+ </para>
+ </sect2>
+ <sect2>
+ <para>
+ Key5Light: if Keylights is set to 1, you can disable the F5 LED by se=
tting this value=20
+ to 0. Default is 1.
+ </para>
+ </sect2>
+ <sect2>
+ <para>
+ KeyTimeout: (Advanced) This value controls how long LCDd waits for a =
key press when=20
+ get_key is called. The value represents microseconds and the default=
is 500 or .5=20
+ seconds. Lowering this value will make LCDd more responsive but also=
causes LCDd to use=20
+ more CPU time and, as the timeout grows shorter, key presses become h=
arder to detect. =20
+ Larger values make key presses more reliable if somewhat slow to take=
effect.
+ </para>
+ </sect2>
+ <sect2 id=3D"picolcd-status">
+ <title>picolcd driver status</title>
+
+ <para>
+ The lcdproc picolcd driver relies upon Mini-Box's usblcd library to s=
etup the USB/HID=20
+ interface. Unfortunately the usblcd library is very thin and tends t=
o put function=20
+ results on stdout/stderr instead of in return values. They (Mini-Box=
) really had=20
+ scripting interfaces in mind.
+ </para>
+ <para>
+ The primary example of this is that I had to write a replacement (get=
_key_events) for=20
+ usblcd's read_events so that I could get the key presses back to the =
calling function=20
+ instead of on stdout. usblcd also has a large number of function she=
lls for which no=20
+ code exists yet. I am not an expert on HID and USB coding, but if an=
d as time permits=20
+ and hardware is available I will try and improve this drivers access =
to the hardware in=20
+ order to get back data (get_contrast for example) and to potentially =
drive multiple=20
+ pcioLCDs at once (or pick the one we want out of many).
+ </para>
+ <para>
+ To sum up, this driver right now stabs and hopes since response data =
is lacking.
+ </para>
+ <para>
+ The hardware also reports key-up events. Normally this would be of n=
o issue (they are=20
+ usually a 0 or 'no key') except that when keys are used in combonatio=
n, the key-up=20
+ event may actually come back as multiple events depending on how the =
user released the=20
+ keys. If the key-up event for a multiple key press comes back as two=
events, the first=20
+ up event will actually look like a new key press. The algorithm in g=
et_key tries to=20
+ deal with this in a sane way and toss out all key-up events for now. =
The hardware is=20
+ touchy and both combo key-down and key-up actions may be reported as =
mutiple events if=20
+ the user is more than a tenth of a second (maybe less?) off in motion=
s.
+ </para>
+ </sect2>
+ <sect2 id=3D"picolcd-copy">
+ <title>Copyright</title>
+ <para>
+ The lcdproc picolcd driver was written by Gatewood Green (woody@nitro=
security.com)=20
+ or (woody@linif.org) and paid for by NitroSecurity, Inc (nitrosecurit=
y.com).
+ </para>
+ </sect2>
+</sect1>
diff -uNrp lcdproc-orig/docs/lcdproc-user/drivers.docbook lcdproc/docs/lc=
dproc-user/drivers.docbook
--- lcdproc-orig/docs/lcdproc-user/drivers.docbook 2007-02-04 14:14:55.00=
0000000 -0700
+++ lcdproc/docs/lcdproc-user/drivers.docbook 2007-03-12 13:40:24.0000000=
00 -0600
@@ -32,6 +32,7 @@ well as the configuration of LCDd.
&mtc_s16209x;
&MtxOrb;
&NoritakeVFD;
+&picolcd;
&pylcd;
&sed1330;
&sed1520;
diff -uNrp lcdproc-orig/LCDd.conf lcdproc/LCDd.conf
--- lcdproc-orig/LCDd.conf 2007-02-04 14:14:55.000000000 -0700
+++ lcdproc/LCDd.conf 2007-03-12 13:31:48.000000000 -0600
@@ -39,7 +39,7 @@
# bayrad, CFontz, CFontz633, CFontzPacket, curses, CwLnx, EyeboxOne,
# g15, glcdlib, glk, hd44780, icp_a106, imon, IOWarrior, irman,
# joy, lb216,lcdm001, lcterm, lirc,MD8800, ms6931, mtc_s16209x,
-# MtxOrb, NoritakeVFD, pyramid, sed1330, sed1520, serialPOS,
+# MtxOrb, NoritakeVFD, picolcd, pyramid, sed1330, sed1520, serialPOS,
# serialVFD, sli, stv5730, svga, t6963, text, tyan, ula200, xosd
Driver=3Dcurses
=20
@@ -694,6 +694,38 @@ Speed=3D9600
=20
=20
=20
+## Mini-box.com picoLCD (usblcd) driver ##
+[picolcd]
+# This is for the Mini-Box.com usblcd device that ships with the M300. =
It can=20
+# also be purchased separately but this driver has only been tested on t=
he M300=20
+# setup.
+
+# KeyTimeout is the time that LCDd spends waiting for a key press before=
cycling=20
+# through other duties. Higher values make LCDd use less CPU time and m=
ake=20
+# key presses more detectable. Lower values make LCDd more responsive b=
ut a=20
+# little prone to missing key presses. 500 (.5 second) is the default a=
nd a
+# balanced value.
+KeyTimeout=3D500
+
+# Contrast: 0 - 1000. 1000 is the default.
+Contrast=3D1000
+
+# Light the keys? 1 (on) / 0 (off). Default is 1 (on).
+Keylights=3D1
+
+# If Keylights =3D 1, the you can unlight specific keys below: 1 (on) / =
0 (off)
+# Key0 is the directional pad. Key1 - Key5 correspond to the F1 - F5 ke=
ys. =20
+# There is no LED for the +/- keys. This is a handy way to indicate to =
users=20
+# which keys are disabled. Defaults are 1 (on).
+Key0Light=3D1
+Key1Light=3D1
+Key2Light=3D1
+Key3Light=3D1
+Key4Light=3D1
+Key5Light=3D1
+
+
+
## Pyramid LCD driver ##
[pyramid]
=20
diff -uNrp lcdproc-orig/server/drivers/Makefile.am lcdproc/server/drivers=
/Makefile.am
--- lcdproc-orig/server/drivers/Makefile.am 2007-02-04 14:14:55.000000000=
-0700
+++ lcdproc/server/drivers/Makefile.am 2007-03-12 13:49:11.000000000 -060=
0
@@ -19,7 +19,7 @@ AM_LDFLAGS =3D @LDSHARED@
#LIBS =3D
=20
pkglib_PROGRAMS =3D @DRIVERS@
-EXTRA_PROGRAMS =3D bayrad CFontz CFontz633 CFontzPacket curses CwLnx Eye=
boxOne g15 glcdlib glk hd44780 icp_a106 imon IOWarrior irman joy lb216 lc=
dm001 lcterm lirc MD8800 ms6931 mtc_s16209x MtxOrb NoritakeVFD pyramid se=
d1330 sed1520 serialPOS serialVFD stv5730 svga t6963 text tyan sli ula200=
xosd
+EXTRA_PROGRAMS =3D bayrad CFontz CFontz633 CFontzPacket curses CwLnx Eye=
boxOne g15 glcdlib glk hd44780 icp_a106 imon IOWarrior irman joy lb216 lc=
dm001 lcterm lirc MD8800 ms6931 mtc_s16209x MtxOrb NoritakeVFD picolcd py=
ramid sed1330 sed1520 serialPOS serialVFD stv5730 svga t6963 text tyan sl=
i ula200 xosd
noinst_LIBRARIES =3D libLCD.a libbignum.a
=20
IOWarrior_CFLAGS =3D @libusb_cflags@ $(AM_CFLAGS)
@@ -45,6 +45,7 @@ MD8800_LDADD =3D libLCD.a
mtc_s16209x_LDADD =3D libLCD.a
MtxOrb_LDADD =3D libLCD.a libbignum.a
NoritakeVFD_LDADD =3D libLCD.a
+picolcd_LDADD =3D libLCD.a @LIBUSBLCD@
pyramid_LDADD =3D libLCD.a
serialPOS_LDADD =3D libLCD.a libbignum.a
serialVFD_LDADD =3D libLCD.a libbignum.a
@@ -85,6 +86,7 @@ ms6931_SOURCES =3D lcd.h lcd_lib.h ms6
mtc_s16209x_SOURCES =3D lcd.h lcd_lib.h mtc_s16209x.c mtc_s16209x.h rep=
ort.h
MtxOrb_SOURCES =3D lcd.h lcd_lib.h MtxOrb.c MtxOrb.h report.h adv_bi=
gnum.h
NoritakeVFD_SOURCES =3D lcd.h lcd_lib.h NoritakeVFD.c NoritakeVFD.h repo=
rt.h
+picolcd_SOURCES =3D lcd.h picolcd.h picolcd.c report.h
pyramid_SOURCES =3D lcd.h pylcd.c pylcd.h
sed1330_SOURCES =3D lcd.h sed1330.h sed1330.c port.h lpt-port.h timin=
g.h report.h
sed1520_SOURCES =3D lcd.h sed1520.c sed1520.h sed1520fm.c sed1520fm.h=
port.h report.h
diff -uNrp lcdproc-orig/server/drivers/picolcd.c lcdproc/server/drivers/p=
icolcd.c
--- lcdproc-orig/server/drivers/picolcd.c 1969-12-31 17:00:00.000000000 -=
0700
+++ lcdproc/server/drivers/picolcd.c 2007-03-12 13:45:00.000000000 -0600
@@ -0,0 +1,520 @@
+/*
+ * picoLCD driver for lcdPROC
+ *
+ * (c) 2007 NitroSecurity, Inc.
+ * Written by Gatewood Green <woody@nitrosecurity.com> or <woody@linif.o=
rg>
+ *
+ * License: GPL (same as usblcd and lcdPROC)
+ *
+ * picoLCD: http://www.mini-box.com/picoLCD-20x2-OEM =20
+ * Can be purchased separately or preinstalled in units such as the=20
+ * M300 http://www.mini-box.com/Mini-Box-M300-LCD
+ *
+ * This driver (key lables and arrangement) is based on the M300 impleme=
ntation=20
+ * of the picoLCD
+ *
+ * The picoLCD is usb connected and is driven (currently) via userspace =
+ * libraries using the Mini-box.com usblcd library (not to be confused w=
ith the=20
+ * Linux usblcd module which does NOT support this device). The usblcd =
library=20
+ * rides atop libusb and libhid (both of which are required for this dri=
ver to=20
+ * operate).
+ *
+ * libusb: http://libusb.sf.net
+ * libhid: http://libhid.alioth.debian.org
+ * usblcd: http://www.mini-box.com/picoLCD-20x2-OEM
+ *=20
+ * The usblcd library is very haphazardly written and directly writes to=
=20
+ * stdout and stderr instead of returning the result for most functions =
+ * (including read_events). Eventually it would be a good idea to elimi=
nate=20
+ * the need for usblcd and drive the hardware via libusb and libhid dire=
ctly. =20
+ * Such a conversion has the opportunity to provide meaningful return va=
lues=20
+ * for all fucntions (instead of stab and hope) and allow for use of mul=
tiple=20
+ * picoLCD devices.
+ *
+ * Due to the way libusblcd's read_events prints keys to stderr instead =
of=20
+ * returning a struct or some such, you will find my own get_key_events =
below.
+ *
+ * ### WARNING ###: libusblcd.so sets a handler for SIGTERM. Because mo=
st=20
+ * applications would set up their signal handling early on (before call=
ing=20
+ * new_usblcd_operations()), this can result in a condition that will pr=
event
+ * a handler your application installed from executing. If your handler=
was=20
+ * responsible for cleaning up logs, syncing, etc, it can result in lost=
data.=20
+ *=20
+ */
+
+/* lcdPROC includes */
+#include "lcd.h"
+#include "picolcd.h"
+#include "report.h"
+
+/* These three includes are the Mini-box.com libusblcd (usblcd) and comp=
any. */
+#include <usblcd.h>
+#include <widgets.h>
+#include <usblcd_util.h>
+
+/* Various odds and ends */
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+/* This is a hack */
+#define API_VERSION "0.5"
+
+/* 12 keys plus a 0 placeholder */
+#define KEYPAD_MAX 13
+#define KEYPAD_LIGHTS 6
+
+#define DEFAULT_CONTRAST 1000 /* Full */
+#define DEFAULT_BACKLIGHT 1 /* On */
+#define DEFAULT_KEYLIGHTS 1 /* On */
+#define DEFAULT_TIMEOUT 500 /* Half second */
+
+/* Set this to 1 and get lots of cruft on stderr when using "LCDd -f 1 -=
d picolcd" */
+#define DEBUG_PICO 0
+
+/* PrivateData struct */
+typedef struct pd {
+ usblcd_operations *lcd; // Reference to the LCD instance
+ int width;
+ int height;
+ int key_timeout;
+ int contrast;
+ int backlight;
+ int keylights;
+ int key_light[KEYPAD_LIGHTS];
+ char *key_matrix[KEYPAD_MAX];
+ char *info;
+ unsigned char *framebuf;
+ unsigned char *lstframe;
+} PrivateData;
+
+static char * keymap[KEYPAD_MAX] =3D {
+ NULL,
+ "Plus",
+ "Minus",
+ "F1",
+ "F2",
+ "F3",
+ "F4",
+ "F5",
+ "Left",
+ "Right",
+ "Up",
+ "Down",
+ "Enter"
+};
+
+/* Private function definitions */
+void get_key_event ( usblcd_operations *self, lcd_packet *packet, int t=
imeout );
+void set_key_lights ( usblcd_operations *self, int keys[], int state );
+
+/* lcd_logical_driver Variables */
+MODULE_EXPORT char *api_version =3D API_VERSION;
+MODULE_EXPORT int stay_in_foreground =3D 0;
+MODULE_EXPORT int supports_multiple =3D 1;
+MODULE_EXPORT char *symbol_prefix =3D "picoLCD_";
+
+/* lcd_logical_driver Manditory functions */
+MODULE_EXPORT int picoLCD_init( Driver *drvthis ) {
+ PrivateData *pd;
+ int x;
+
+ pd =3D ( PrivateData * ) malloc( sizeof( PrivateData ) );
+
+ if ( ! pd )
+ return -1;
+
+ if ( drvthis->store_private_ptr( drvthis, pd ) )
+ return -1;
+
+ pd->lcd =3D new_usblcd_operations();
+ pd->lcd->init( pd->lcd );
+ pd->width =3D 20; /* hard coded (mfg spec) */
+ pd->height =3D 2; /* hard coded (mfg spec) */
+ pd->info =3D "picoLCD: Supports the LCD as installed on the M300 (http:=
//www.mini-box.com/Mini-Box-M300-LCD) ";
+
+ for ( x =3D 0; x < KEYPAD_LIGHTS; x++ )
+ pd->key_light[x] =3D 1; /* individual lights on */
+
+ pd->contrast =3D drvthis->config_get_int( drvthis->name, "Contrast=
", 0, DEFAULT_CONTRAST );
+ pd->backlight =3D drvthis->config_get_bool( drvthis->name, "BackLigh=
t", 0, DEFAULT_BACKLIGHT );
+ pd->keylights =3D drvthis->config_get_bool( drvthis->name, "KeyLight=
s", 0, DEFAULT_KEYLIGHTS ); /* key lights with LCD Backlight? */
+ pd->key_timeout =3D drvthis->config_get_int( drvthis->name, "KeyTimeo=
ut", 0, DEFAULT_TIMEOUT );
+
+ /* These allow individual lights to be disabled */
+ pd->key_light[0] =3D drvthis->config_get_bool( drvthis->name, "Key0Ligh=
t", 0, 1 ); /* Directional PAD */
+ pd->key_light[1] =3D drvthis->config_get_bool( drvthis->name, "Key1Ligh=
t", 0, 1 ); /* F1 */
+ pd->key_light[2] =3D drvthis->config_get_bool( drvthis->name, "Key2Ligh=
t", 0, 1 ); /* F2 */
+ pd->key_light[3] =3D drvthis->config_get_bool( drvthis->name, "Key3Ligh=
t", 0, 1 ); /* F3 */
+ pd->key_light[4] =3D drvthis->config_get_bool( drvthis->name, "Key4Ligh=
t", 0, 1 ); /* F4 */
+ pd->key_light[5] =3D drvthis->config_get_bool( drvthis->name, "Key5Ligh=
t", 0, 1 ); /* F5 */
+
+ for ( x =3D 0; x < KEYPAD_MAX; x++ )
+ pd->key_matrix[x] =3D keymap[x];
+
+ pd->framebuf =3D ( unsigned char * ) malloc( pd->width * pd->height + 1=
);
+ if ( pd->framebuf =3D=3D NULL ) {
+ report( RPT_ERR, "%s: unable to create framebuf.\n", __FUNCTION__ );
+ return -1;
+ }
+ memset( pd->framebuf, ' ', pd->width * pd->height );
+ pd->framebuf[pd->width * pd->height] =3D 0;
+
+ pd->lstframe =3D ( unsigned char * ) malloc( pd->width * pd->height + 1=
);
+ if ( pd->lstframe =3D=3D NULL ) {
+ report( RPT_ERR, "%s: unable to create lstframe.\n", __FUNCTION__ );
+ return -1;
+ }
+ memset( pd->lstframe, ' ', pd->width * pd->height );
+ pd->lstframe[pd->width * pd->height] =3D 0;
+
+ if ( pd->backlight )
+ picoLCD_backlight( drvthis, 1 );
+ if ( ! pd->keylights )
+ set_key_lights( pd->lcd, pd->key_light, 0 );
+ else
+ picoLCD_backlight( drvthis, 0 );
+
+ picoLCD_set_contrast( drvthis, pd->contrast );
+
+ report( RPT_INFO, "picolcd: init complete\n", __FUNCTION__ );
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: init complete\n" );
+
+ return 0;
+}
+
+MODULE_EXPORT void picoLCD_close( Driver *drvthis ) {
+ PrivateData *pd =3D drvthis->private_data;
+
+ pd->lcd->close( pd->lcd ); /* This actually does not do anything in usb=
lcd (yet?) */
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: close complete\n" );
+}
+
+/* lcd_logical_driver Essential output functions */
+MODULE_EXPORT int picoLCD_width( Driver *drvthis ) {
+ PrivateData *pd =3D drvthis->private_data;
+
+ return pd->width;
+}
+
+MODULE_EXPORT int picoLCD_height( Driver *drvthis ) {
+ PrivateData *pd =3D drvthis->private_data;
+
+ return pd->height;
+}
+
+MODULE_EXPORT void picoLCD_clear( Driver *drvthis ) {
+ PrivateData *pd =3D drvthis->private_data;
+
+ memset( pd->framebuf, ' ', pd->width * pd->height );
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: clear complete\n" );
+}
+
+MODULE_EXPORT void picoLCD_flush( Driver *drvthis ) {
+ PrivateData *pd =3D drvthis->private_data;
+ unsigned char *fb =3D pd->framebuf;
+ unsigned char *lf =3D pd->lstframe;
+ static char text[48];
+ int i, line, offset;
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: flush started\n" );
+
+ for ( line =3D 0; line < pd->height; line++ ) {=20
+ memset( text, 0, 48 );=20
+ offset =3D line * pd->width;
+ fb =3D pd->framebuf + offset;
+ lf =3D pd->lstframe + offset;
+
+ for ( i =3D 0; i < pd->width; i++ ) {
+ if ( *fb++ !=3D *lf++ ) {
+ strncpy( text, pd->framebuf + offset, pd->width );
+ pd->lcd->settext( pd->lcd, line, 0, text );
+ memcpy( pd->lstframe + offset, pd->framebuf + offset, pd->width );
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: flush wrote line %d (%s)\n", line + 1, t=
ext );
+
+ break;
+ }
+ }
+ }
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: flush complete\n\t(%s)\n\t(%s)\n", pd->fram=
ebuf, pd->lstframe );
+}
+
+MODULE_EXPORT void picoLCD_string( Driver *drvthis, int x, int y, char *=
str ) {
+ PrivateData *pd =3D drvthis->private_data;
+ char *dest;
+ int len;
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: string start (%s)\n", str );
+
+ if ( y < 1 || y > pd->height )
+ return;
+ if ( x < 1 || x > pd->width )
+ return;
+
+ len =3D strlen( str );
+ if ( len + x > pd->width ) {
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: string overlength (>%d). Start: %d Length:=
%d (%s)\n", pd->width, x, len ,str );
+
+ len =3D pd->width - x; /* Copy what we can */
+ }
+
+ x--; y--; /* Convert 1-based to 0-based */
+ dest =3D pd->framebuf + ( y * pd->width + x );
+ memcpy( dest, str, len * sizeof(char) );
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: string complete (%s)\n", str );
+}
+
+MODULE_EXPORT void picoLCD_chr( Driver *drvthis, int x, int y, char chr =
) {
+ PrivateData *pd =3D drvthis->private_data;
+ char *dest;
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: chr start (%c)\n", chr );
+
+ if ( y < 1 || y > pd->height )
+ return;
+ if ( x < 1 || x > pd->width )
+ return;
+
+ x--; y--; /* Convert 1-based to 0-based */
+ dest =3D pd->framebuf + ( y * pd->width + x );
+ memcpy( dest, &chr, sizeof(char) );
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: chr complete (%c)\n", chr );
+}
+
+/* lcd_logical_driver Essential input functions */
+
+MODULE_EXPORT char *picoLCD_get_key( Driver *drvthis ) {
+ PrivateData *pd =3D drvthis->private_data;
+ lcd_packet *keydata;
+ char *keystr;
+ int keys_read =3D 0;
+ int key_pass =3D 0;
+ int two_keys =3D 0;
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: get_key start (timeout %d)\n", pd->key_time=
out );
+
+ keydata =3D malloc( sizeof( lcd_packet ) );
+
+ while ( ! keys_read ) {
+ get_key_event( pd->lcd, keydata, pd->key_timeout );
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: get_key got an event\n" );
+
+ if ( keydata->type =3D=3D IN_REPORT_KEY_STATE ) {
+ if ( ! keydata->data[1] && key_pass ) {
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: get_key got all clear\n" );
+ /* Got a <0, 0> key-up event after reading a valid key press event *=
/
+ keys_read++; /* All clear */
+ } else if ( ! keydata->data[2] && ! two_keys ) {
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: get_key got one key\n" );
+ /* We got one key (but not after a two key event and before and all =
clear) */
+ keystr =3D pd->key_matrix[keydata->data[1]];
+ } else {
+ /* We got two keys */
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: get_key got two keys\n" );
+ two_keys++;
+ sprintf( keystr, "%s+%s", pd->key_matrix[keydata->data[1]], pd->key_=
matrix[keydata->data[2]] );
+ }
+
+ key_pass++; /* This hack allows us to deal with receiving left over <=
0,0> first */
+ } else {
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: get_key got non-key data or timeout\n" );=
+ /* We got IR or otherwise bad data */
+ return NULL;
+ }
+
+ }
+
+ free( keydata );
+
+ if ( DEBUG_PICO )
+ fprintf( stderr, "picolcd: get_key complete (%s)\n", keystr );
+
+ if ( ! strlen( keystr ) )
+ return NULL;
+
+ return keystr;
+
+/*=20
+ * Due to how key events are reported, we need to keep reading key press=
es=20
+ * until we get the all clear (all keys up) event.
+ *=20
+ * Key events come back in such a way to report up to two simultanious k=
eys=20
+ * pressed. The highest numbered key always comes back as the first key=
and=20
+ * the lower numbered key follows. If only one key was pressed, the sec=
ond=20
+ * key is 0. I will refer to a key event as: <high key, low key>.
+ *
+ * Key ID numbers:
+ * 0 =3D (no key)
+ * 1 =3D + (plus)
+ * 2 =3D - (minus)
+ * 3 =3D F1
+ * 4 =3D F2
+ * 5 =3D F3
+ * 6 =3D F4
+ * 7 =3D F5
+ * 8 =3D Left
+ * 9 =3D Right
+ * 10 =3D Up
+ * 11 =3D Down
+ * 12 =3D Enter
+ *=20
+ * The picoLCD also sends key-up events.
+ *
+ * On a single key press, the return is <keynum, 0>. The key-up event i=
s a=20
+ * read that returns <0, 0> (all clear). On a dual key press, if one ke=
y is=20
+ * released later than the other key, the first key-up event is=20
+ * <remainingkey, 0>. This will be followed by a final "all clear" key-=
up=20
+ * <0, 0>. If both keys are release simultaniously, then after <hk, lk>=
,=20
+ * you will receive <0, 0>. If the keys are pressed down in a staggard =
+ * fashion, you will receive <first key, 0> followed by <hk, lk> followe=
d by=20
+ * key-up events as already detailed.
+ *
+ * What this means is that we need to keep reading key presses until we =
get=20
+ * the <0, 0> all clear.
+ */
+=09
+}
+
+/* lcd_logical_driver Extended output functions */
+
+/* lcd_logical_driver User-defined character functions */
+
+/* lcd_logical_driver Hardware functions */
+/*MODULE_EXPORT int picoLCD_get_contrast( Driver *drvthis ) {
+ PrivateData *pd =3D drvthis->private_data;
+
+}*/
+
+MODULE_EXPORT int picoLCD_set_contrast( Driver *drvthis, int promille )=
{
+ PrivateData *pd =3D drvthis->private_data;
+ int inv; /* The hardware seems to go dark on higher values, so we turn =
it around */
+
+ if ( promille <=3D 1000 && promille > 0 ) {
+ inv =3D 1000 - promille;
+ pd->lcd->contrast( pd->lcd, ( int ) ( inv / 1000 * 40 ) );
+ return 0;
+ } else if ( promille > 1000 ) {
+ pd->lcd->contrast( pd->lcd, 0 );
+ return 0;
+ } else if ( promille <=3D 0 ) {
+ pd->lcd->contrast( pd->lcd, 40 );
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+/*MODULE_EXPORT int picoLCD_get_brightness( Driver *drvthis, int state )=
{
+ PrivateData *pd =3D drvthis->private_data;
+
+}*/
+
+/*MODULE_EXPORT int picoLCD_set_brightness( Driver *drvthis, int state,=
int promille ) {
+ PrivateData *pd =3D drvthis->private_data;
+
+}*/
+
+MODULE_EXPORT void picoLCD_backlight( Driver *drvthis, int state ) {
+ PrivateData *pd =3D drvthis->private_data;
+
+ if ( state =3D=3D 0 ) {
+ pd->lcd->backlight( pd->lcd, state );
+ set_key_lights( pd->lcd, pd->key_light, state );
+ return;
+ }
+
+ if ( state =3D=3D 1 ) {
+ pd->lcd->backlight( pd->lcd, state );
+ if ( pd->keylights )
+ set_key_lights( pd->lcd, pd->key_light, state );
+ return;
+ }
+
+ return;
+}
+
+/*MODULE_EXPORT int picoLCD_output( Driver *drvthis, int state ) {
+ PrivateData *pd =3D drvthis->private_data;
+
+}*/
+
+/* lcd_logical_driver Informational functions */
+MODULE_EXPORT char *picoLCD_get_info( Driver *drvthis ) {
+ PrivateData *pd =3D drvthis->private_data;
+
+ return pd->info;
+}
+
+/* Private functions */
+void get_key_event ( usblcd_operations *self, lcd_packet *packet, int ti=
meout ) {
+ int ret;
+
+ memset( packet->data, 0, 255 );
+ packet->type =3D 0;
+ ret =3D usb_interrupt_read( self->hid->hiddev->handle, USB_ENDPOINT_IN =
+ 1, packet->data, _USBLCD_MAX_DATA_LEN, timeout );
+ if ( ret > 0 ) {
+ switch ( packet->data[0] ) {
+ case IN_REPORT_KEY_STATE: {
+ packet->type =3D IN_REPORT_KEY_STATE;
+ } break;
+ case IN_REPORT_IR_DATA: {
+ packet->type =3D IN_REPORT_IR_DATA;
+ } break;
+ default: {
+ packet->type =3D 0;
+ }
+ }
+ }
+}
+
+void set_key_lights ( usblcd_operations *self, int keys[], int state ) {=
+ if ( state ) {
+ /* Only LEDs we want on */
+ if ( keys[0] )
+ self->setled( self, 0, 1 );
+ if ( keys[1] )
+ self->setled( self, 1, 1 );
+ if ( keys[2] )
+ self->setled( self, 2, 1 );
+ if ( keys[3] )
+ self->setled( self, 3, 1 );
+ if ( keys[4] )
+ self->setled( self, 4, 1 );
+ if ( keys[5] )
+ self->setled( self, 5, 1 );
+ } else {
+ /* All LEDs off */
+ self->setled( self, 0, 0 );
+ self->setled( self, 1, 0 );
+ self->setled( self, 2, 0 );
+ self->setled( self, 3, 0 );
+ self->setled( self, 4, 0 );
+ self->setled( self, 5, 0 );
+ }
+}
diff -uNrp lcdproc-orig/server/drivers/picolcd.h lcdproc/server/drivers/p=
icolcd.h
--- lcdproc-orig/server/drivers/picolcd.h 1969-12-31 17:00:00.000000000 -=
0700
+++ lcdproc/server/drivers/picolcd.h 2007-03-12 13:45:00.000000000 -0600
@@ -0,0 +1,56 @@
+/*
+ * Driver for picoLCD graphical displays
+ * Header file
+ *
+ * (c) 2007 NitroSecurity, Inc.
+ * Written by Gatewood Green <woody@nitrosecurity.com> or <woody@linif.o=
rg>
+ *
+ * License: GPL (same as usblcd and lcdPROC)
+ *
+ * picoLCD: http://www.mini-box.com/picoLCD-20x2-OEM =20
+ * Can be purchased separately or preinstalled in units such as the=20
+ * M300 http://www.mini-box.com/Mini-Box-M300-LCD
+ *
+ * See picolcd.c for full details
+ *
+ */
+
+#ifndef PICOLCD_H
+#define PCIOLCD_H
+
+#include "lcd.h"
+
+typedef struct _lcd_packet lcd_packet;
+struct _lcd_packet {
+ unsigned char data[255];
+ unsigned int type;
+};
+
+MODULE_EXPORT int picoLCD_init ( Driver *drvthis );
+MODULE_EXPORT void picoLCD_close ( Driver *drvthis );
+MODULE_EXPORT int picoLCD_width ( Driver *drvthis );
+MODULE_EXPORT int picoLCD_height ( Driver *drvthis );
+MODULE_EXPORT void picoLCD_clear ( Driver *drvthis );
+MODULE_EXPORT void picoLCD_flush ( Driver *drvthis );
+MODULE_EXPORT void picoLCD_string ( Driver *drvthis, int x, int y, ch=
ar *str );
+MODULE_EXPORT void picoLCD_chr ( Driver *drvthis, int x, int y, ch=
ar c );
+
+MODULE_EXPORT char *picoLCD_get_key ( Driver *drvthis );
+
+//MODULE_EXPORT void picoLCD_vbar ( Driver *drvthis, int x, int y, =
int len, int promille, int options );
+//MODULE_EXPORT void picoLCD_hbar ( Driver *drvthis, int x, int y, =
int len, int promille, int options );
+//MODULE_EXPORT void picoLCD_num ( Driver *drvthis, int x, int y, =
int num );
+//MODULE_EXPORT void picoLCD_heartbeat ( Driver *drvthis, int state );
+//MODULE_EXPORT void picoLCD_icon ( Driver *drvthis, int x, int y, =
int icon );
+//MODULE_EXPORT void picoLCD_cursor ( Driver *drvthis, int x, int y, =
int type );
+
+//MODULE_EXPORT int picoLCD_get_contrast ( Driver *drvthis );
+MODULE_EXPORT int picoLCD_set_contrast ( Driver *drvthis, int promill=
e );
+//MODULE_EXPORT int picoLCD_get_brightness ( Driver *drvthis, int state=
);
+//MODULE_EXPORT int picoLCD_set_brightness ( Driver *drvthis, int state=
, int promille );
+MODULE_EXPORT void picoLCD_backlight ( Driver *drvthis, int promill=
e );
+//MODULE_EXPORT void picoLCD_output ( Driver *drvthis, int state=
);
+
+MODULE_EXPORT char *picoLCD_get_info ( Driver *drvthis );
+
+#endif
--------------060705070503080508070909--
--------------enigFA62A4346E097BC97891B5A1
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFF9baVHnsUla8nzK0RA7v9AJ9+6KuC/MSe3EjvSiYcPznM9w/VOQCeNeB4
vvo3hUzLGHK2EGJYjMuJfpc=
=xDKK
-----END PGP SIGNATURE-----
--------------enigFA62A4346E097BC97891B5A1--