Index: LCDd.conf
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/LCDd.conf,v
retrieving revision 1.63.2.12
diff -u -r1.63.2.12 LCDd.conf
--- LCDd.conf 25 Apr 2007 20:11:15 -0000 1.63.2.12
+++ LCDd.conf 18 Mar 2009 16:54:23 -0000
@@ -28,6 +28,14 @@
## Server section with all kinds of settings for the LCDd server ##
[server]
+# Where can we find the driver modules ?
+# IMPORTANT: Make sure to change this setting to reflect your
+# specific setup! Otherwise LCDd won't be able to find
+# the driver modules and will thus not be able to
+# function properly.
+# NOTE: Always place a slash as last character !
+DriverPath=server/drivers/
+
# Tells the server to load the given drivers. Multiple lines can be given.
# The name of the driver is case sensitive and determines the section
# where to look for further configuration options of the specific driver
@@ -37,11 +45,12 @@
#
# The following drivers are supported:
# bayrad, CFontz, CFontz633, CFontzPacket, curses, CwLnx, ea65,
-# EyeboxOne, 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, ula200, xosd
-Driver=curses
+# EyeboxOne, g15, glcdlib, glk, hd44780, icp_a106, imon, imonlcd, IOWarrior,
+# irman, joy, lb216, lcdm001, lcterm, lirc, lis, MD8800, ms6931, mtc_s16209x,
+# MtxOrb, mx5000, NoritakeVFD, picolcd, pyramid, sed1330, sed1520, serialPOS,
+# serialVFD, shuttleVFD, sli, stv5730, svga, t6963, text, tyan, ula200,
+# xosd
+Driver=imonlcd
# Tells the driver to bind to the given interface
Bind=127.0.0.1
@@ -52,35 +61,40 @@
# Sets the reporting level; defaults to 2 (warnings and errors only).
#ReportLevel=3
-# Should we report to syslog instead of stderr ? Default: no
+# Should we report to syslog instead of stderr ? [default: no; legal: yes, no]
#ReportToSyslog=yes
+# User to run as. LCDd will drop its root priviledges, if any,
+# and run as this user instead.
+User=nobody
+
+# The server will stay in the foreground if set to true.
+#Foreground=no
+
+# Hello message: each entry represents a display line; default: builtin
+#Hello=" Welcome to"
+#Hello=" LCDproc!"
+
+# GoodBye message: each entry represents a display line; default: builtin
+#GoodBye="Thanks for using"
+#GoodBye=" LCDproc!"
+
# Sets the default time in seconds to displays a screen.
WaitTime=5
-# User to run as. LCDd will drop its root priviledges,
-# if any, and run as this user instead.
-User=nobody
-
# If yes, the the serverscreen will be rotated as a usual info screen. If no,
# it will be a background screen, only visible when no other screens are
# active.
#ServerScreen=no
-# The server will stay in the foreground if set to true.
-#Foreground=no
+# set master backlight setting [default: open; legal: off, open, on]
+#Backlight=open
-# Where can we find the driver modules ?
-# IMPORTANT: Make sure to change this setting to reflect your
-# specific setup! Otherwise LCDd won't be able to find
-# the driver modules and will thus not be able to
-# function properly.
-# NOTE: Always place a slash as last character !
-DriverPath=server/drivers/
+# set master heartbeat setting [default: open; legal: off, open, on]
+#Heartbeat=open
-# GoodBye message: each entry represents a display line; default: builtin
-#GoodBye="Thanks for using"
-#GoodBye=" LCDproc!"
+# set title scrolling speed [default: 10; legal: 0-10]
+#TitleSpeed=10
# The "...Key=" lines define what the server does with keypresses that
# don't go to any client.
@@ -238,18 +252,21 @@
# use ASC symbols for icons & bars [default: no; legal, yes, no]
UseACS=no
+# draw Border [default: yes; legal: yes, no]
+DrawBorder=yes
+
## Cwlinux driver ##
[CwLnx]
-# Select the LCD model [default: 12232; legal: 12232, 1602]
+# Select the LCD model [default: 12232; legal: 12232, 12832, 1602]
Model=12232
# Select the output device to use [default: /dev/lcd]
Device=/dev/ttyUSB0
-# Select the LCD size [default: depending on model: 12232: 20x4, 1602: 16x2]
+# Select the LCD size [default: depending on model: 12232: 20x4, 12832: 21x4, 1602: 16x2]
Size=20x4
# Set the communication speed [default: 19200; legal: 9600, 19200]
@@ -342,6 +359,8 @@
# Display size (currently unused)
size=20x5
+
+
## glcdlib meta driver for graphical LCDs ##
[glcdlib]
@@ -409,10 +428,10 @@
# Select what type of connection. See documentation for types.
ConnectionType=4bit
-# Port where the LPT is. Usual values are 0x278, 0x378 and 0x3BC
+# Port where the LPT is [ususal: 0x278, 0x378 and 0x3BC]
Port=0x378
-# Device of the serial interface (default is /dev/lcd)
+# Device of the serial interface [default: /dev/lcd]
Device=/dev/ttyS0
# Bitrate of the serial port (0 for interface default)
@@ -422,9 +441,13 @@
# You may also need to configure the keypad layout further on in this file.
Keypad=no
-# set the initial contrast (for bwctusb only) [default: 0; legal: 0 - 1000]
+# Set the initial contrast (bwctusb and lcd2usb) [default: 500; legal: 0 - 1000]
Contrast=0
+# Set brightness of the backlight (lcd2usb only) [default: 0; legal 0 - 1000]
+#Brightness=1000
+#OffBrightness=0
+
# If you have a switchable backlight.
Backlight=no
@@ -446,12 +469,16 @@
# If you have an HD66712, a KS0073 or an other 'almost HD44780-compatible',
# set this flag to get into extended mode (4-line linear).
-# This flag is NOT the old obsolete Extended option.
#ExtendedMode=yes
+# In extended mode, on some controllers like the ST7036 (in 3 line mode)
+# the next line in DDRAM won't start 0x20 higher. [default: 0x20]
+#LineAddress=0x10
+
# Character map to to map ISO-8859-1 to the LCD's character set
-# [default: hd44780_default; legal: hd44780_default, ea_ks0073, sed1278f_0b ]
-Charmap=hd44780_default
+# [default: hd44780_default; legal: hd44780_default, hd44780_euro,
+# ea_ks0073, sed1278f_0b ]
+CharMap=hd44780_default
# If your display is slow and cannot keep up with the flow of data from
# LCDd, garbage can appear on the LCDd. Set this delay factor to 2 or 4
@@ -502,6 +529,10 @@
# (if not given, the 1st IOWarrior found gets used)
#SerialNumber=00000674
+# If you have an HD66712, a KS0073 or an other 'almost HD44780-compatible',
+# set this flag to get into extended mode (4-line linear).
+#ExtendedMode=yes
+
# Specifies if the last line is pixel addressable or it controls an
# underline effect. [default: true (= pixel addressable); legal: yes, no]
#Lastline=true
@@ -521,7 +552,7 @@
## IrMan driver ##
[IrMan]
-#if in trouble with IrMan, try Lirc emulator for IrMan
+# in case of trouble with IrMan, try the Lirc emulator for IrMan
# Select the input device to use
#Device=/dev/irman
@@ -531,6 +562,20 @@
+## IRtrans driver ##
+[irtrans]
+
+# Does the device have a backlight? [default: no; legal: yes, no]
+#Backlight=no
+
+# IRTrans device to connect to [default: localhost]
+#Hostname=localhost
+
+# display dimensions
+Size=16x2
+
+
+
## Joystick driver ##
[joy]
@@ -607,6 +652,26 @@
+## LIS MCE 2005 driver ##
+[lis]
+
+# Set the initial brightness [default: 1000; legal: 0 - 1000]
+# 0-250 = 25%, 251-500 = 50%, 501-750 = 75%, 751-1000 = 100%
+#Brightness=1000
+
+# Columns by lines [default: 20x2]
+#Size=20x2
+
+# USB Vendor ID [default: 0x0403]
+# Change only if testing a compatible device.
+#VendorID=0x0403
+
+# USB Product ID [default: 0x6001]
+# Change only if testing a compatible device.
+#ProductID=0x6001
+
+
+
##The driver for the VFD of the Medion MD8800 PC ##
[MD8800]
# device to use [default: /dev/ttyS1]
@@ -695,30 +760,39 @@
+## mx5000 driver for LCD display on the Logitech MX5000 keyboard ##
+[mx5000]
+
+# Select the output device to use [default: /dev/hiddev0]
+Device = /dev/hiddev0
+# Time to wait in ms after the refresh screen has been sent [default: 1000]
+WaitAfterRefresh = 1000
+
+
+
## Noritake VFD driver ##
[NoritakeVFD]
# device where the VFD is. Usual values are /dev/ttyS0 and /dev/ttyS1 [default: /dev/lcd]
Device=/dev/ttyS0
-
# Specifies the size of the LCD.
Size=20x4
-
-# set the brightness
-Brightness=255
-
+# Set the initial brightness [default: 1000; legal: 0 - 1000]
+Brightness=1000
+# Set the initial off-brightness [default: 0; legal: 0 - 1000]
+# This value is used when the display is normally
+# switched off in case LCDd is inactive
+OffBrightness=50
# set the serial port speed [default: 9600, legal: 1200, 2400, 9600, 19200, 115200]
Speed=9600
-
-# re-initialize VFD ?
-#Reboot=yes
+# Set serial data parity [default: 0 (None), legal: 0(=none), 1(=odd), 2(=even)]
+Parity=0
+# re-initialize the VFD [default: no; legal: yes, no]
+Reboot=no
## Mini-box.com picoLCD (usblcd) driver ##
[picolcd]
-# This is for the Mini-Box.com usblcd device that ships with the M300. It can
-# also be purchased separately but this driver has only been tested on the M300
-# setup.
# KeyTimeout is the time that LCDd spends waiting for a key press before cycling
# through other duties. Higher values make LCDd use less CPU time and make
@@ -727,7 +801,10 @@
# balanced value.
KeyTimeout=500
-# Contrast: [default: 1000; legal: 0 - 1000]
+# Set the initial brightness [default: 1000; legal: 0 - 1000]
+Brightness=1000
+
+# Set the initial contrast [default: 1000; legal: 0 - 1000]
Contrast=1000
# Light the keys? i[default: on; legal: on, off]
@@ -744,6 +821,21 @@
Key4Light=on
Key5Light=on
+# Host name or IP address of the LIRC instance that is to receive IR codes
+# If not set, or set to an empty value, IR support is disabled.
+#LircHost=127.0.0.1
+
+# UDP port on which LIRC is listening [default: 8765; legal: 1 - 65535]
+LircPort=8765
+
+# Duration in jiffies of the synthesized sync pulse [default: 64; 0 to suppress]
+LircSync=64
+
+# Duration in jiffies of the synthesized gap; 0 to suppress, default 2048.
+# This is really the fixed duration of an entire IR command; individual pulse/space
+# durations are deducted from this to determine the duration of the trailing gap.
+LircLength=2048
+
## Pyramid LCD driver ##
@@ -771,6 +863,7 @@
ConnectionType=classic
+
## Seiko Epson 1520 driver ##
[sed1520]
@@ -806,6 +899,11 @@
# 1 KD Rev 2.1.
# 2 Noritake VFDs (*).
# 3 Futaba VFDs
+# 4 IEE S03601-95B
+# 5 IEE S03601-96-080 (*)
+# 6 Futaba NA202SD08FA (allmost IEE compatible)
+# 7 Samsung 20S207DA4 and 20S207DA6
+# 8 Nixdorf BA6x / VT100
# (* most should work, not testet yet.)
Type=0
@@ -818,6 +916,9 @@
# Portaddress where the LPT is. Used in parallelmode only. Usual values are 0x278, 0x378 and 0x3BC
Port=0x378
+# Set parallel port timingdelay (us). Used in parallelmode only. [default: 2; legal: 0 - 255]
+#PortWait=2
+
# Device to use in serial mode. Usual values are /dev/ttyS0 and /dev/ttyS1
Device=/dev/ttyS1
@@ -841,6 +942,12 @@
+## shuttleVFD driver ##
+[shuttleVFD]
+# No options
+
+
+
## stv5730 driver ##
[stv5730]
@@ -950,7 +1057,27 @@
# set display size [default: 20x4]
Size=20x4
-# font to use, in XLFD format, as given by "xfontsel"
+# Offset in pixels from the top-left corner of the monitor [default: 0x0]
+Offset=200x200
+
+# X font to use, in XLFD format, as given by "xfontsel"
Font=-*-terminus-*-r-*-*-*-320-*-*-*-*-*
+## SoundMon iMon LCD
+[imonlcd]
+# Specify which iMon protocol should be used [default: 0=15c2:ffdc device; legal: 1=15c2:0038 device]
+Protocol=0
+# Set the exit behavior [default: 1=show the big clock; legal: 0=leave shutdown message, 2=blank device]
+OnExit=2
+# Select the output device to use [default: /dev/lcd0]
+Device=/dev/lcd0
+# Select the displays contrast [default: 200; legal: 0-1000]
+Contrast=200
+# Specify the size of the display in pixels [default:96x16]
+#Size=96x16
+# Set the backlight state [default: 1=on; legal: 0=off]
+#Backlight=1
+# Set the disc mode [default: 0=spin the "slim" disc - two disc segments; legal: 1=their complement spinning]
+#DiscMode=0
+
# EOF
Index: acinclude.m4
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/acinclude.m4,v
retrieving revision 1.68.2.9
diff -u -r1.68.2.9 acinclude.m4
--- acinclude.m4 14 Apr 2007 18:07:41 -0000 1.68.2.9
+++ acinclude.m4 18 Mar 2009 16:54:23 -0000
@@ -6,7 +6,7 @@
[ which is a comma-separated list of drivers.]
[ Possible drivers are:]
[ bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,ea65,]
- [ EyeboxOne,g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,]
+ [ EyeboxOne,g15,glcdlib,glk,hd44780,icp_a106,imon,imonlcd,IOWarrior,]
[ irman,joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,]
[ mtc_s16209x,MtxOrb,NoritakeVFD,picolcd,pyramid,sed1330]
[ sed1520,serialPOS,serialVFD,sli,stv5730,svga,t6963,text,]
@@ -16,7 +16,7 @@
drivers="$enableval",
drivers=[bayrad,CFontz,CFontz633,curses,CwLnx,glk,lb216,lcdm001,MtxOrb,pyramid,text])
-allDrivers=[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,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,ula200,xosd]
+allDrivers=[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,g15,glcdlib,glk,hd44780,icp_a106,imon,imonlcd,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,ula200,xosd]
drivers=`echo $drivers | sed -e 's/,/ /g'`
@@ -207,6 +207,10 @@
DRIVERS="$DRIVERS imon${SO}"
actdrivers=["$actdrivers imon"]
;;
+ imonlcd)
+ DRIVERS="$DRIVERS imonlcd${SO}"
+ actdrivers=["$actdrivers imonlcd"]
+ ;;
IOWarrior)
if test "$enable_libusb" = yes ; then
DRIVERS="$DRIVERS IOWarrior${SO}"
Index: docs/LCDd.8.in
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/docs/LCDd.8.in,v
retrieving revision 1.7.2.3
diff -u -r1.7.2.3 LCDd.8.in
--- docs/LCDd.8.in 14 Apr 2007 18:07:42 -0000 1.7.2.3
+++ docs/LCDd.8.in 18 Mar 2009 16:54:24 -0000
@@ -168,6 +168,9 @@
.B imon
iMON IR/VFD modules in cases by Soundgraph/Ahanix/Silverstone/Uneed/Accent
.TP
+.B imonlcd
+iMON IR/LCD modules in cases by Soundgraph/Ahanix/Silverstone/Uneed/Accent/Antec
+.TP
.B IOWarrior
Code Mercenaries IOWarrior
.TP
Index: docs/lcdproc-user/drivers.docbook
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/docs/lcdproc-user/drivers.docbook,v
retrieving revision 1.3.2.3
diff -u -r1.3.2.3 drivers.docbook
--- docs/lcdproc-user/drivers.docbook 14 Apr 2007 18:07:43 -0000 1.3.2.3
+++ docs/lcdproc-user/drivers.docbook 18 Mar 2009 16:54:24 -0000
@@ -21,6 +21,7 @@
&hd44780;
&icp_a106;
&imon;
+&imonlcd;
&IOWarrior;
&irman;
&joy;
Index: docs/lcdproc-user/lcdproc-user.docbook
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/docs/lcdproc-user/lcdproc-user.docbook,v
retrieving revision 1.4.2.4
diff -u -r1.4.2.4 lcdproc-user.docbook
--- docs/lcdproc-user/lcdproc-user.docbook 14 Apr 2007 18:07:43 -0000 1.4.2.4
+++ docs/lcdproc-user/lcdproc-user.docbook 18 Mar 2009 16:54:24 -0000
@@ -27,6 +27,7 @@
+
Index: docs/lcdproc-user/drivers/imonlcd.docbook
===================================================================
RCS file: docs/lcdproc-user/drivers/imonlcd.docbook
diff -N docs/lcdproc-user/drivers/imonlcd.docbook
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ docs/lcdproc-user/drivers/imonlcd.docbook 18 Mar 2009 16:54:24 -0000
@@ -0,0 +1,135 @@
+
+The imonlcd Driver
+
+
+General
+
+
+The imonlcd driver controls
+Soundgraph iMON LCD
+devices, that are either preinstalled or available as optional accessories
+for a variety of Home Theater PC (HTPC) cases from Ahanix, Silverstone, Cooler Master, Antec
+and others. They can also be bought separately and then fit into a 5.25" disk drive bay
+of any regular PC.
+
+
+
+The iMON LCD can display various system and media information using a 96x16 pixel field and total of 177 icons. The LCD module connects to the computer using USB. Some devices include support for an IR remote control, and some versions have a volume knob. LCDproc's driver currently only supports the display part of the device. The remote control receiver and volume knob may be configured separately using LIRC.
+
+
+
+In order to be able to use it, you have to get and install one of
+the iMON module included with LIRC ver. 0.8.4a or newer
+
+
+
+
+
+
+Configuration in LCDd.conf
+
+
+[imonlcd]
+
+
+
+
+ Protocol=
+
+ PROTOCOL
+
+
+
+ Specify which SoundGraph protocol your device uses. This is matched to the output of lsusb | grep -si imon. Use 0 for 15c2:ffdc devices. Use 1 for 15cd:0038 devices.
+
+
+
+
+
+ Size=
+
+ WIDTH
+ x
+ HEIGHT
+
+
+
+ Set the display size in pixels. The default 96x16 should be safe
+ for most if not all users, since the device seeems to be made only with
+ this one size.
+
+
+
+
+
+ Device=
+ DEVICE
+
+
+ Select the output device to use. Change this from the default
+ /dev/lcd0 to the device file that gets created
+ when the kernel module (see above) is loaded.
+
+
+
+
+
+
+ OnExit=
+ EXIT_ACTION
+
+
+ Select what should happen when the driver is stopped.
+ The default, 1 shows a big, ugly clock.
+ Setting this to 0 will leave a shutdown message on the screen.
+ Setting this to 2 will blank the device and turn off the backlight.
+ At this time, in many cases, the backlight will turn itself back on
+ if the system is shutdown. Consider this a "feature" for now.
+
+
+
+
+
+ Contrast=
+ CONTRAST
+
+
+ Set the initial contrast.
+ Legal values for CONTRAST are 0 - 1000.
+ If not given, the default value is 200.
+
+
+
+
+
+
+ Backlight=
+ BACKLIGHT
+
+
+ Turn the backlight on or off.
+ Use 0 to turn the backlight is off.
+ Use 1 to turn the backlight on, which is the default.
+
+
+
+
+
+
+ DiscMode=
+ DISC_MODE
+
+
+ Set the type of spinning disc on the display.
+ Use 0 to spin the "slim" disc, which has two disc segments - this is the default.
+ Use 1 to spin the complement.
+
+
+
+
+
+
+
+
+
+
Index: server/drivers/Makefile.am
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/server/drivers/Makefile.am,v
retrieving revision 1.48.2.7
diff -u -r1.48.2.7 Makefile.am
--- server/drivers/Makefile.am 14 Apr 2007 18:07:47 -0000 1.48.2.7
+++ server/drivers/Makefile.am 18 Mar 2009 16:54:25 -0000
@@ -19,7 +19,7 @@
#LIBS =
pkglib_PROGRAMS = @DRIVERS@
-EXTRA_PROGRAMS = bayrad CFontz CFontz633 CFontzPacket curses CwLnx ea65 EyeboxOne 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 stv5730 svga t6963 text tyan sli ula200 xosd
+EXTRA_PROGRAMS = bayrad CFontz CFontz633 CFontzPacket curses CwLnx ea65 EyeboxOne g15 glcdlib glk hd44780 icp_a106 imon imonlcd IOWarrior irman joy lb216 lcdm001 lcterm lirc MD8800 ms6931 mtc_s16209x MtxOrb NoritakeVFD picolcd pyramid sed1330 sed1520 serialPOS serialVFD stv5730 svga t6963 text tyan sli ula200 xosd
noinst_LIBRARIES = libLCD.a libbignum.a
IOWarrior_CFLAGS = @libusb_cflags@ $(AM_CFLAGS)
@@ -37,6 +37,7 @@
hd44780_DEPENDENCIES = @HD44780_DRIVERS@
icp_a106_LDADD = libLCD.a
imon_LDADD = libLCD.a
+imonlcd_LDADD = libLCD.a
IOWarrior_LDADD = @libusb_libs@ libLCD.a libbignum.a
irman_LDADD = @LIBIRMAN@
lcterm_LDADD = libLCD.a
@@ -75,6 +76,7 @@
icp_a106_SOURCES = lcd.h lcd_lib.h icp_a106.c icp_a106.h report.h
imon_SOURCES = lcd.h lcd_lib.h imon.h imon.c report.h
+imonlcd_SOURCES = lcd.h lcd_lib.h imonlcd.h imonlcd.c report.h
IOWarrior_SOURCES = lcd.h lcd_lib.h hd44780-charmap.h IOWarrior.c IOWarrior.h report.h adv_bignum.h
irman_SOURCES = lcd.h irmanin.c irmanin.h report.h
joy_SOURCES = lcd.h joy.c joy.h port.h report.h
Index: server/drivers/imonlcd.c
===================================================================
RCS file: server/drivers/imonlcd.c
diff -N server/drivers/imonlcd.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ server/drivers/imonlcd.c 18 Mar 2009 16:54:26 -0000
@@ -0,0 +1,1330 @@
+/** \file server/drivers/imonlcd.c
+ * Driver for SoundGraph iMON OEM LCD Modules
+ *
+ * Requires the lirc_imon module included with lirc >= 0.8.4a
+ */
+
+/* Modified March 2009 by Jonathan Kyler for inclusion in lcdproc
+ *
+ * Added 0038 support
+ * Added Protocol configuration parameter
+ *
+ * Modified March 2009 by Eric Pooch - lots of cleanup and streamlining
+ * Removed fixed "96" width listed everywhere
+ * Streamlined config file parsing
+ * Sped up font access
+ * Implemented backing store to avoid unnecessary refreshes
+ * Adjusted p->width and p->height to use character width and height properly
+ * Fixed long long defines
+ * Replaced send_data() and send_byte_data() with send_packet()
+ * Improved send_command_data()
+ * Reduced functions for basic character drawing - removed draw_char() and draw_string()
+ *
+ * Copyright (c) 2009, Jonathan Kyler
+ * 2004, Venky Raju
+ * 2007, Christian Leuschen
+ * 2007, Dean Harding
+ * 2009, Eric Pooch < epooch (at) cox (dot) net>
+ *
+ *
+ * This source code is being released under the GPL.
+ * Please see the file COPYING in this package for details.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "lcd.h"
+#include "lcd_lib.h"
+#include "shared/debug.h"
+//#define DEBUG
+#include "report.h"
+
+/* Defines a 6x8 font that is in a format we can use!. */
+#include "t6963_font.h"
+
+#include "imonlcd.h"
+
+#define IMONLCD_PACKET_DATA_SIZE 7
+
+#define DEFAULT_DEVICE "/dev/lcd0"
+#define DEFAULT_SIZE "96x16" // This is the size in "pixels" (colxrow)...
+#define DEFAULT_CONTRAST 200
+#define DEFAULT_BACKLIGHT 1 // default: turn backlight on
+#define DEFAULT_DISCMODE 0 // default: spin the "slim" disc
+
+#define LCD_DEFAULT_CELL_WIDTH 6
+#define LCD_DEFAULT_CELL_HEIGHT 8
+
+#define ON_EXIT_SHOWMSG 0 // Do nothing -- just leave the "shutdown" message there
+#define ON_EXIT_SHOWCLOCK 1 // Show the big clock
+#define ON_EXIT_BLANKSCREEN 2 // Blank the device completely
+
+#define DEFAULT_ON_EXIT 1
+
+#define DEFAULT_PROTOCOL 0 // 0 = protocol for 15c2:ffdc device, 1 = protocol for 15c2:0038 device
+
+#define PROTOCOL_FFDC 0 // protocol ID for 15c2:ffdc device
+#define PROTOCOL_0038 1 // protocol ID for 15c2:0038 device
+
+// Vars for the server core
+MODULE_EXPORT char *api_version = API_VERSION;
+MODULE_EXPORT int stay_in_foreground = 0;
+MODULE_EXPORT int supports_multiple = 0;
+MODULE_EXPORT char *symbol_prefix = "imonlcd_";
+
+// Our private data
+typedef struct imonlcd_private_data {
+ char info[255];
+ int imon_fd;
+
+ /* send buffer for one command or display data */
+ unsigned char tx_buf[8];
+
+ /* framebuffer and backingstore for current contents */
+ unsigned char *framebuf;
+ unsigned char *backingstore;
+
+ int bytesperline;
+
+ int width, height;
+ int cellwidth, cellheight;
+
+ int on_exit;
+ int contrast; // 0 = lowest contrast, 1000 = highest
+ int backlightOn; // stores the backlight state
+ int discMode; // 0 = two disc-segments spinning as default,
+ // 1 = their complement spinning
+
+ /* store commands appropriate for the version of the iMON LCD */
+ int protocol; // 0 = protocol for 15c2:ffdc device, 1 = protocol for 15c2:0038 device
+ uint64_t command_display;
+ uint64_t command_shutdown;
+ uint64_t command_display_on;
+ uint64_t command_clear_alarm;
+
+ /*
+ * Here we record the last "state" of the CD icon so that we can "animate" it.
+ */
+ int last_cd_state;
+ time_t last_cd_state_change;
+ uint64_t last_icon_state;
+ int lastPrivateIconState; // remind the last state for setting the icons
+} PrivateData;
+
+/**
+ * Just for convenience and to have the commands at one place.
+ */
+#define COMMANDS_SET_ICONS (uint64_t) 0x0100000000000000LL
+#define COMMANDS_SET_CONTRAST (uint64_t) 0x0300000000000000LL
+#define COMMANDS_DISPLAY (uint64_t) 0x0000000000000000LL // must be or'd with the applicable COMMANDS_DISPLAY_BYTE
+#define COMMANDS_SHUTDOWN (uint64_t) 0x0000000000000008LL // must be or'd with the applicable COMMANDS_DISPLAY_BYTE
+#define COMMANDS_DISPLAY_ON (uint64_t) 0x0000000000000040LL // must be or'd with the applicable COMMANDS_DISPLAY_BYTE
+#define COMMANDS_CLEAR_ALARM (uint64_t) 0x0000000000000000LL // must be or'd with the applicable COMMANDS_ALARM_BYTE
+#define COMMANDS_SET_LINES0 (uint64_t) 0x1000000000000000LL
+#define COMMANDS_SET_LINES1 (uint64_t) 0x1100000000000000LL
+#define COMMANDS_SET_LINES2 (uint64_t) 0x1200000000000000LL
+#define COMMANDS_INIT (uint64_t) 0x0200000000000000LL //not exactly sure what this does, but it's needed
+#define COMMANDS_LOW_CONTRAST (uint64_t) (COMMANDS_SET_CONTRAST + (uint64_t) 0x00FFFFFF00580A00LL)
+#define COMMAND_MASK (uint64_t) 0xFF00000000000000LL
+
+/* Allow for variations in Soundgraphs numerous protocols */
+/* 15c2:0038 SoundGraph iMON */
+#define COMMANDS_DISPLAY_BYTE_0038 (uint64_t) 0x8800000000000000LL
+#define COMMANDS_ALARM_BYTE_0038 (uint64_t) 0x8a00000000000000LL
+
+/* 15c2:ffdc SoundGraph iMON */
+#define COMMANDS_DISPLAY_BYTE_FFDC (uint64_t) 0x5000000000000000LL
+#define COMMANDS_ALARM_BYTE_FFDC (uint64_t) 0x5100000000000000LL
+
+
+
+
+/*
+ * These are used with the imon_output function to determine which icons to turn on/off. Because we
+ * only get a 32-bit integer to play, some of the icons are grouped into "sets" from which you can
+ * only select to turn one on at a time.
+ */
+#define IMON_OUTPUT_CD_MASK 0x00000001
+#define IMON_OUTPUT_TOPROW_MASK 0x0000000E
+#define IMON_OUTPUT_SPEAKER_MASK 0x00000030
+#define IMON_OUTPUT_SPDIF_MASK 0x00000040
+#define IMON_OUTPUT_SRC_MASK 0x00000080
+#define IMON_OUTPUT_FIT_MASK 0x00000100
+#define IMON_OUTPUT_TV_MASK 0x00000200
+#define IMON_OUTPUT_HDTV_MASK 0x00000400
+#define IMON_OUTPUT_SCR1_MASK 0x00000800
+#define IMON_OUTPUT_SCR2_MASK 0x00001000
+#define IMON_OUTPUT_BRICONS_MASK 0x0000E000
+#define IMON_OUTPUT_BMICONS_MASK 0x00070000
+#define IMON_OUTPUT_BLICONS_MASK 0x00380000
+#define IMON_OUTPUT_VOL_MASK 0x00400000
+#define IMON_OUTPUT_TIME_MASK 0x00800000
+#define IMON_OUTPUT_ALARM_MASK 0x01000000
+#define IMON_OUTPUT_REC_MASK 0x02000000
+#define IMON_OUTPUT_REP_MASK 0x04000000
+#define IMON_OUTPUT_SFL_MASK 0x08000000
+
+#define IMON_OUTPUT_PBARS_MASK 0x10000000
+#define IMON_OUTPUT_DISK_IN_MASK 0x20000000
+
+
+#define IMON_ICON_ALL (uint64_t) 0x00FFFFFFFFFFFFFFLL
+//Byte 6
+#define IMON_ICON_DISK_OFF (uint64_t) 0x7F7000FFFFFFFFFFLL
+#define IMON_ICON_DISK_ON (uint64_t) 0x0080FF0000000000LL
+
+#define IMON_ICON_DISK_IN (uint64_t) 0x0080000000000000LL
+#define IMON_ICON_CD_IN (uint64_t) 0x00806B0000000000LL
+#define IMON_ICON_DVD_IN (uint64_t) 0x0080550000000000LL
+
+// Byte 5
+#define IMON_ICON_WMA2 ((uint64_t) 0x1 << 39)
+#define IMON_ICON_WAV ((uint64_t) 0x1 << 38)
+#define IMON_ICON_REP ((uint64_t) 0x1 << 37)
+#define IMON_ICON_SFL ((uint64_t) 0x1 << 36)
+#define IMON_ICON_ALARM ((uint64_t) 0x1 << 35)
+#define IMON_ICON_REC ((uint64_t) 0x1 << 34)
+#define IMON_ICON_VOL ((uint64_t) 0x1 << 33)
+#define IMON_ICON_TIME ((uint64_t) 0x1 << 32)
+// Byte 4
+#define IMON_ICON_XVID ((uint64_t) 0x1 << 31)
+#define IMON_ICON_WMV ((uint64_t) 0x1 << 30)
+#define IMON_ICON_MPG2 ((uint64_t) 0x1 << 29)
+#define IMON_ICON_AC3 ((uint64_t) 0x1 << 28)
+#define IMON_ICON_DTS ((uint64_t) 0x1 << 27)
+#define IMON_ICON_WMA ((uint64_t) 0x1 << 26)
+#define IMON_ICON_MP3 ((uint64_t) 0x1 << 25)
+#define IMON_ICON_OGG ((uint64_t) 0x1 << 24)
+
+//Byte 3
+#define IMON_ICON_SRC ((uint64_t) 0x1 << 23)
+#define IMON_ICON_FIT ((uint64_t) 0x1 << 22)
+#define IMON_ICON_TV_2 ((uint64_t) 0x1 << 21)
+#define IMON_ICON_HDTV ((uint64_t) 0x1 << 20)
+#define IMON_ICON_SCR1 ((uint64_t) 0x1 << 19)
+#define IMON_ICON_SCR2 ((uint64_t) 0x1 << 18)
+#define IMON_ICON_MPG ((uint64_t) 0x1 << 17)
+#define IMON_ICON_DIVX ((uint64_t) 0x1 << 16)
+// Byte 2
+#define IMON_SPKR_FC ((uint64_t) 0x1 << 15)
+#define IMON_SPKR_FR ((uint64_t) 0x1 << 14)
+#define IMON_SPKR_SL ((uint64_t) 0x1 << 13)
+#define IMON_SPKR_LFE ((uint64_t) 0x1 << 12)
+#define IMON_SPKR_SR ((uint64_t) 0x1 << 11)
+#define IMON_SPKR_RL ((uint64_t) 0x1 << 10)
+#define IMON_SPKR_SPDIF ((uint64_t) 0x1 << 9)
+#define IMON_SPKR_RR ((uint64_t) 0x1 << 8)
+// Byte 1
+#define IMON_ICON_MUSIC ((uint64_t) 0x1 << 7)
+#define IMON_ICON_MOVIE ((uint64_t) 0x1 << 6)
+#define IMON_ICON_PHOTO ((uint64_t) 0x1 << 5)
+#define IMON_ICON_CD_DVD ((uint64_t) 0x1 << 4)
+#define IMON_ICON_TV ((uint64_t) 0x1 << 3)
+#define IMON_ICON_WEBCAST ((uint64_t) 0x1 << 2)
+#define IMON_ICON_NEWS ((uint64_t) 0x1 << 1)
+#define IMON_SPKR_FL ((uint64_t) 0x1)
+
+
+/**
+ * This is the definition for a "big" font, which is a font that
+ * simply takes up twice as many pixels as the normal font.
+ * (12 col x 18 row pixels). It is only used for drawing numbers.
+ */
+typedef struct {
+ int ch;
+ unsigned short pixels[12];
+} imon_bigfont;
+
+/* TODO
+ * Some of these characters need a bit of tweaking...
+ */
+static imon_bigfont bigfont[] = {
+ { '0', { 0x0000, 0x07E0, 0x1FF8, 0x3FFC, 0x7FFE, 0x4002, 0x4002, 0x4002, 0x3FFC, 0x3FFC, 0x1FF8, 0x07E0 } },
+ { '1', { 0x0000, 0x0000, 0x0000, 0x4002, 0x7FFE, 0x7FFE, 0x7FFE, 0x7FFE, 0x0002, 0x0000, 0x0000, 0x0000 } },
+ { '2', { 0x0000, 0x1806, 0x3C2C, 0x7C7C, 0x5C5C, 0x40DE, 0x7F9E, 0x7F8E, 0x3F0E, 0x1E0C, 0x0018, 0x0000 } },
+ { '3', { 0x0000, 0x001C, 0x3C3C, 0x7C3E, 0x7C1A, 0x0080, 0x4182, 0x7FFE, 0x7FFE, 0x3E7C, 0x1C38, 0x0000 } },
+ { '4', { 0x0000, 0x0030, 0x0050, 0x0190, 0x0610, 0x0002, 0x1FFE, 0x3FFE, 0x7FFE, 0x7FFE, 0x0012, 0x0002 } },
+ { '5', { 0x0000, 0x0018, 0x7FBC, 0x793E, 0x3B1A, 0x3800, 0x3B02, 0x3BFE, 0x31FE, 0x61FC, 0x00F8, 0x0000 } },
+ { '6', { 0x0000, 0x07E0, 0x1FF8, 0x3FFC, 0x7FFE, 0x4002, 0x0180, 0x5982, 0x7DFE, 0x3DFC, 0x18FC, 0x0078 } },
+ { '7', { 0x0000, 0x0800, 0x7000, 0x3000, 0x703C, 0x787E, 0x79FE, 0x7BFC, 0x3E00, 0x3000, 0x6000, 0x0000 } },
+ { '8', { 0x0000, 0x1C3C, 0x3E7E, 0x7FFE, 0x7FFE, 0x4182, 0x4182, 0x7FFE, 0x7FFE, 0x3E7E, 0x1C3C, 0x0000 } },
+ { '9', { 0x0000, 0x1E18, 0x3F3C, 0x7FBE, 0x7F9A, 0x0180, 0x4002, 0x7FFE, 0x3FFC, 0x1FF8, 0x07E0, 0x0000 } },
+ { ':', { 0x0000, 0x030C, 0x079E, 0x079E, 0x030C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } },
+
+ /* Marks the end of the array, but also serves as the character that
+ * unknown inputs are mapped to (essentially, a "space")
+ */
+ { '\0', { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} }
+};
+
+static void imonlcd_display_init(Driver *drvthis);
+
+static void draw_bigchar(imon_bigfont *font, int ch, int x, int y, PrivateData *p);
+static void setLineLength( int topLine, int botLine, int topProgress, int botProgress, PrivateData *p );
+static void setBuiltinProgressBars( int topLine, int botLine,
+ int topProgress, int botProgress, PrivateData *p );
+static int lengthToPixels( int length );
+static void send_command_data( uint64_t commandData, PrivateData *p );
+static void send_packet(PrivateData *p);
+
+
+/**
+ * Initialize the driver.
+ * \param drvthis Pointer to driver structure.
+ * \retval 0 Success.
+ * \retval <0 Error.
+ */
+MODULE_EXPORT int imonlcd_init (Driver *drvthis)
+{
+ PrivateData *p = NULL;
+
+ // Allocate, initialize and store private p
+ p = (PrivateData *) calloc(1, sizeof(PrivateData));
+ if (p == NULL) {
+ debug(RPT_ERR, "%s: failed to allocate private data", drvthis->name);
+ return -1;
+ }
+
+ if (drvthis->store_private_ptr(drvthis, p)) {
+ debug(RPT_ERR, "%s: failed to store private data pointer", drvthis->name);
+ return -1;
+ }
+
+ char buf[256];
+
+ int graph_width, graph_height; // width and height of screen, in pixels
+ int tmp;
+
+ p->imon_fd = -1;
+
+ graph_width = 0;
+ graph_height = 0;
+
+ p->width = 0; // Display width, in characters
+ p->height = 0; // Display height, in characters
+ p->cellwidth = LCD_DEFAULT_CELL_WIDTH; // width of a character, in pixels
+ p->cellheight = LCD_DEFAULT_CELL_HEIGHT; // height of a character, in pixels
+
+ p->last_cd_state = 0;
+ p->last_icon_state = 0x0; // no icons turned on at startup
+ p->lastPrivateIconState = 0x0; // no icons turned on at startup
+ p->discMode = 0;
+
+ /* Get settings from config file*/
+
+ /* Get device */
+ strncpy(buf, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(buf));
+ buf[sizeof(buf)-1] = '\0';
+ report(RPT_INFO, "%s: using Device %s", drvthis->name, buf);
+
+ /* TODO: check if this is applicapable for the imonlcd driver as well */
+ /* Open device for writing */
+ if ((p->imon_fd = open(buf, O_WRONLY)) < 0) {
+ report(RPT_ERR, "%s: ERROR opening %s (%s).", drvthis->name, buf, strerror(errno));
+ report(RPT_ERR, "%s: Did you load the iMON VFD kernel module?", drvthis->name);
+ report(RPT_ERR, "%s: More info in lcdproc/docs/README.imon", drvthis->name);
+ return -1;
+ }
+
+ /* Get protocol version */
+ tmp = drvthis->config_get_int(drvthis->name, "Protocol", 0, DEFAULT_PROTOCOL);
+ if ((tmp < 0) || (tmp > 1))
+ {
+ report(RPT_WARNING, "%s: Protocol must be between 0 and 1; using default %d",
+ drvthis->name, DEFAULT_PROTOCOL);
+ tmp = DEFAULT_PROTOCOL;
+ }
+ p->protocol = tmp;
+
+ /* Set commands based on protocol version */
+ if ( p->protocol == PROTOCOL_FFDC )
+ {
+ p->command_display = (uint64_t) (COMMANDS_DISPLAY | COMMANDS_DISPLAY_BYTE_FFDC);
+ p->command_shutdown = (uint64_t) (COMMANDS_SHUTDOWN | COMMANDS_DISPLAY_BYTE_FFDC);
+ p->command_display_on = (uint64_t) (COMMANDS_DISPLAY_ON | COMMANDS_DISPLAY_BYTE_FFDC);
+ p->command_clear_alarm = (uint64_t) (COMMANDS_CLEAR_ALARM | COMMANDS_ALARM_BYTE_FFDC);
+ } else if ( p->protocol == PROTOCOL_0038 )
+ {
+ p->command_display = (uint64_t) (COMMANDS_DISPLAY | COMMANDS_DISPLAY_BYTE_0038);
+ p->command_shutdown = (uint64_t) (COMMANDS_SHUTDOWN | COMMANDS_DISPLAY_BYTE_0038);
+ p->command_display_on = (uint64_t) (COMMANDS_DISPLAY_ON | COMMANDS_DISPLAY_BYTE_0038);
+ p->command_clear_alarm = (uint64_t) (COMMANDS_CLEAR_ALARM | COMMANDS_ALARM_BYTE_0038);
+ } else //default - use FFDC
+ {
+ report(RPT_WARNING, "%s: Protocol version not recognized: %d; using default %d",
+ drvthis->name, p->protocol, PROTOCOL_FFDC);
+ p->command_display = (uint64_t) (COMMANDS_DISPLAY | COMMANDS_DISPLAY_BYTE_FFDC);
+ p->command_shutdown = (uint64_t) (COMMANDS_SHUTDOWN | COMMANDS_DISPLAY_BYTE_FFDC);
+ p->command_display_on = (uint64_t) (COMMANDS_DISPLAY_ON | COMMANDS_DISPLAY_BYTE_FFDC);
+ p->command_clear_alarm = (uint64_t) (COMMANDS_CLEAR_ALARM | COMMANDS_ALARM_BYTE_FFDC);
+ }
+
+
+
+ /* Get size settings*/
+ strncpy(buf, drvthis->config_get_string(drvthis->name, "Size", 0, DEFAULT_SIZE), sizeof(buf));
+ buf[sizeof(buf)-1] = '\0';
+ if ((sscanf(buf , "%dx%d", &graph_width, &graph_height) != 2)
+ || (graph_width <= 0) || (graph_height <= 0)
+ || (graph_height < LCD_DEFAULT_CELL_HEIGHT)
+ || ((graph_width / p->cellwidth) > LCD_MAX_WIDTH)
+ || ((graph_height / p->cellheight) > LCD_MAX_HEIGHT))
+ {
+ report(RPT_WARNING, "%s: cannot read Size: %s; using default %s",
+ drvthis->name, buf, DEFAULT_SIZE);
+ sscanf(DEFAULT_SIZE , "%dx%d", &graph_width, &graph_height);
+ }
+ /* Convert dimension in pixels to characters. */
+ p->width = (graph_width / p->cellwidth);
+ p->height = (graph_height / p->cellheight);
+
+ /* Store this to make working with the frame buffer memory easier. */
+ p->bytesperline = graph_width;
+
+ /* Get the "on exit" setting so we know what to do when we shut the device down */
+ tmp = drvthis->config_get_int(drvthis->name, "OnExit", 0, DEFAULT_ON_EXIT);
+ if ((tmp < 0) || (tmp > 3))
+ {
+ report(RPT_WARNING, "%s: OnExit must be between 0 and 3; using default %d",
+ drvthis->name, DEFAULT_ON_EXIT);
+ tmp = DEFAULT_ON_EXIT;
+ }
+ p->on_exit = tmp;
+
+ /* Get the "contrast" setting */
+ tmp = drvthis->config_get_int(drvthis->name, "Contrast", 0, DEFAULT_CONTRAST);
+ if ((tmp < 0) || (tmp > 1000))
+ {
+ report(RPT_WARNING, "%s: Contrast must be between 0 and 1000; using default %d",
+ drvthis->name, DEFAULT_CONTRAST);
+ tmp = DEFAULT_CONTRAST;
+ }
+ p->contrast = tmp;
+
+ /* Get the "backlight" setting */
+ p->backlightOn = drvthis->config_get_bool(drvthis->name, "Backlight", 0, DEFAULT_BACKLIGHT);
+
+ /* Get the "disc-mode" setting */
+ p->discMode = drvthis->config_get_bool(drvthis->name, "DiscMode", 0, DEFAULT_DISCMODE);
+
+ /* We need a little bit of extra memory in the frame buffer so that all
+ of the last 7-bit-long packet data will be within the frame buffer.
+ See imonlcd_flush() for where we take advantage of this.
+ */
+ tmp = 0;
+ while (((p->bytesperline * p->height) + tmp) % IMONLCD_PACKET_DATA_SIZE) {
+ tmp++;
+ }
+
+ /* Make sure the frame buffer is there... */
+ p->framebuf = (unsigned char *) malloc((p->bytesperline * p->height) + tmp);
+ if (p->framebuf == NULL)
+ {
+ report(RPT_ERR, "%s: unable to allocate framebuffer", drvthis->name);
+ return -1;
+ }
+ /* Clear the framebuffer. */
+ imonlcd_clear(drvthis);
+ /* This is the extra memory that will fill out the last packet's data. */
+ memset(p->framebuf+(p->bytesperline * p->height), 0xFF, tmp);
+
+ /* Make sure the framebuffer backing store is there... */
+ p->backingstore = (unsigned char *) malloc(p->bytesperline * p->height);
+ if (p->backingstore == NULL)
+ {
+ report(RPT_ERR, "%s: unable to create framebuffer backing store", drvthis->name);
+ return -1;
+ }
+ memset(p->backingstore, ' ', p->bytesperline * p->height);
+
+ imonlcd_display_init(drvthis);
+
+ report(RPT_DEBUG, "%s: init() done", drvthis->name);
+
+ return 0;
+}
+
+
+
+static void imonlcd_display_init(Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+
+ /* Send the "initialize" commands to the screen. */
+
+ if ( p->backlightOn )
+ send_command_data( p->command_display_on, p );
+ else
+ send_command_data( p->command_shutdown, p );
+ send_command_data( p->command_clear_alarm, p );
+ imonlcd_set_contrast( drvthis, p->contrast );
+ send_command_data( COMMANDS_INIT, p ); // unknown, required init command
+ send_command_data( COMMANDS_SET_ICONS, p );
+ send_command_data( COMMANDS_SET_LINES0, p ); // clear the progress-bars
+ send_command_data( COMMANDS_SET_LINES1, p ); // on top and bottom of the
+ send_command_data( COMMANDS_SET_LINES2, p ); // display
+}
+
+
+
+/**
+ * Close the driver (do necessary clean-up).
+ * \param drvthis Pointer to driver structure.
+ */
+MODULE_EXPORT void imonlcd_close (Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+
+ if (p != NULL) {
+ if (p->imon_fd >= 0) {
+ if (p->on_exit == ON_EXIT_SHOWMSG) {
+ // "show message" means "do nothing" -- the message is there already
+ report(RPT_INFO, "%s: closing, leaving \"goodbye\" message.", drvthis->name);
+ } else if (p->on_exit == ON_EXIT_BLANKSCREEN) {
+ // turning backlight off (confirmed for my Silverstone LCD)
+ // (as "cybrmage" at mediaportal pointed out, his LCD is an Antec built-in one
+ // and turns completely off with this command)
+ // TODO: Why does the backlight turn on again at reboot and/or shutdown
+ // just when the computer turns it's power off / reboots.
+ // Is it just my bios sending a reset to all USB-devices, is it
+ // the USB-kernel-code that's sending the reset?!
+ // Maybe gets solved with setting the alarm!?
+ report(RPT_INFO, "%s: closing, turning backlight off.", drvthis->name);
+ send_command_data( p->command_shutdown, p );
+ send_command_data( p->command_clear_alarm, p );
+ } else {
+ // by default, show the big clock. We need to set it to the current
+ // time, then it just keeps counting automatically.
+ report(RPT_INFO, "%s: closing, showing clock.", drvthis->name);
+
+ time_t tt = time(NULL);
+ struct tm *t = localtime(&tt);
+ uint64_t data;
+
+ //data = ((uint64_t)0x50 << 56);
+ data = p->command_display;
+ data += ((uint64_t)t->tm_sec << 48);
+ data += ((uint64_t)t->tm_min << 40);
+ data += ((uint64_t)t->tm_hour << 32);
+ data += ((uint64_t)t->tm_mday << 24);
+ data += ((uint64_t)t->tm_mon << 16);
+ data += (((uint64_t)t->tm_year) << 8);
+ data += 0x80;
+ send_command_data(data, p );
+ send_command_data( p->command_clear_alarm, p );
+ }
+
+ close(p->imon_fd);
+ }
+
+ if (p->framebuf != NULL)
+ free(p->framebuf);
+ p->framebuf = NULL;
+
+ free(p);
+ }
+ drvthis->store_private_ptr(drvthis, NULL);
+}
+
+
+/**
+ * Provide some information about this driver.
+ * \param drvthis Pointer to driver structure.
+ * \return Constant string with information.
+ */
+MODULE_EXPORT const char * imonlcd_get_info (Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+
+ strcpy(p->info, "SoundGraph iMON LCD driver version : 15c2:ffdc and 15c2:0038 ");
+ return p->info;
+}
+
+
+/**
+ * Clear the screen.
+ * \param drvthis Pointer to driver structure.
+ */
+MODULE_EXPORT void imonlcd_clear (Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+
+ memset(p->framebuf, 0x00, p->bytesperline * p->height);
+}
+
+
+/**
+ * Flush data on screen to the LCD.
+ * \param drvthis Pointer to driver structure.
+ */
+MODULE_EXPORT void imonlcd_flush (Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+
+ unsigned char msb;
+ int offset = 0;
+
+ /* The display only provides for a complete screen refresh.
+ If nothing has changed, don't refresh.
+ */
+ if ( memcmp(p->backingstore, p->framebuf, (p->bytesperline * p->height)) == 0 )
+ return;
+
+ for (msb = 0x20; msb < 0x3c; msb++)
+ {
+ /* Copy the packet data from the frame buffer. */
+ memcpy(p->tx_buf, p->framebuf+offset, IMONLCD_PACKET_DATA_SIZE);
+
+ /* Add the memory register byte to the packet data. */
+ p->tx_buf[IMONLCD_PACKET_DATA_SIZE] = msb;
+
+ send_packet(p);
+
+ offset += IMONLCD_PACKET_DATA_SIZE;
+ }
+
+ /* Update the backing store. */
+ memcpy(p->backingstore, p->framebuf, (p->bytesperline * p->height));
+}
+
+
+/**
+ * Print a string on the screen at position (x,y).
+ * The upper-left corner is (1,1), the lower-right corner is (p->width, p->height).
+ * \param drvthis Pointer to driver structure.
+ * \param x Horizontal character position (column).
+ * \param y Vertical character position (row).
+ * \param string String that gets written.
+ */
+MODULE_EXPORT void imonlcd_string (Driver *drvthis, int x, int y, const char string[])
+{
+ int i;
+
+ for (i = 0; string[i] != '\0'; i++)
+ imonlcd_chr(drvthis, x+i, y, string[i]);
+}
+
+
+/**
+ * Print a character on the screen at position (x,y).
+ * The upper-left corner is (1,1), the lower-right corner is (p->width, p->height).
+ * \param drvthis Pointer to driver structure.
+ * \param x Horizontal character position (column).
+ * \param y Vertical character position (row).
+ * \param ch Character that gets written.
+ */
+MODULE_EXPORT void imonlcd_chr (Driver *drvthis, int x, int y, char ch)
+{
+ PrivateData *p = drvthis->private_data;
+
+ if ((x < 1) || (y < 1) || (x > p->width) || (y > p->height))
+ return;
+
+ x--; y--;
+ /* Convert from characters to pixels. */
+ x *= p->cellwidth;
+ y *= p->bytesperline;
+
+ unsigned char column_byte;
+ int row, col, start_loc;
+
+ start_loc = (unsigned char)ch * (p->cellwidth * p->cellheight);
+
+ for (col = 0; col < p->cellwidth; col++)
+ {
+ column_byte = 0;
+
+ for (row = 0; row < p->cellheight; row++)
+ {
+ column_byte <<= 1;
+
+ (column_byte |= (fontdata_6x8[(start_loc + (row * 6) + col)]) > 0);
+ }
+ x++;
+ p->framebuf[x + y] = column_byte;
+ }
+}
+
+/**
+ * Draw a vertical bar bottom-up.
+ * \param drvthis Pointer to driver structure.
+ * \param x Horizontal character position (column) of the starting point.
+ * \param y Vertical character position (row) of the starting point.
+ * \param len Number of characters that the bar is high at 100%
+ * \param promille Current height level of the bar in promille.
+ * \param options Options (currently unused).
+ */
+MODULE_EXPORT void imonlcd_vbar (Driver *drvthis, int x, int y, int len, int promille, int options)
+{
+ PrivateData *p = drvthis->private_data;
+
+ /* use the t6963_font character for the short bar and let the lcd_lib do the rest. */
+ lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, 212);
+}
+
+
+/**
+ * Draw a horizontal bar to the right.
+ * \param drvthis Pointer to driver structure.
+ * \param x Horizontal character position (column) of the starting point.
+ * \param y Vertical character position (row) of the starting point.
+ * \param len Number of characters that the bar is long at 100%
+ * \param promille Current length level of the bar in promille (i.e. from 0 to 1000).
+ * \param options Options (currently unused).
+ */
+MODULE_EXPORT void imonlcd_hbar (Driver *drvthis, int x, int y, int len, int promille, int options)
+{
+ PrivateData *p = drvthis->private_data;
+
+ /* use the t6963_font character for the short bar and let the lcd_lib do the rest. */
+ lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, 220);
+}
+
+
+/**
+ * Place an icon on the screen.
+ * \param drvthis Pointer to driver structure.
+ * \param x Horizontal character position (column).
+ * \param y Vertical character position (row).
+ * \param icon synbolic value representing the icon.
+ * \retval 0 Icon has been successfully defined/written.
+ * \retval <0 Server core shall define/write the icon.
+ */
+MODULE_EXPORT int imonlcd_icon (Driver *drvthis, int x, int y, int icon)
+{
+ char ch1 = '?';
+ char ch2 = '\0';
+
+ switch (icon) {
+ case ICON_BLOCK_FILLED: ch1 = 219; break;
+ case ICON_HEART_OPEN: ch1 = 4; break;
+ case ICON_HEART_FILLED: ch1 = 3; break;
+ case ICON_ARROW_UP: ch1 = 24; break;
+ case ICON_ARROW_DOWN: ch1 = 25; break;
+ case ICON_ARROW_LEFT: ch1 = 27; break;
+ case ICON_ARROW_RIGHT: ch1 = 26; break;
+
+ case ICON_STOP: ch1 = 9; ch2 = ' '; break;
+ case ICON_PAUSE: ch1 = 19; ch2 = ' '; break;
+ case ICON_PLAY: ch1 = 16; ch2 = ' '; break;
+ case ICON_PLAYR: ch1 = 17; ch2 = ' '; break;
+ case ICON_FF: ch1 = 16; ch2 = 16; break;
+ case ICON_FR: ch1 = 17; ch2 = 17; break;
+ case ICON_NEXT: ch1 = 16; ch2 = '|'; break;
+ case ICON_PREV: ch1 = '|'; ch2 = 17; break;
+ case ICON_REC: ch1 = 15; ch2 = ' '; break;
+
+ /* let the server core do the rest */
+ default: return -1;
+ }
+
+ imonlcd_chr(drvthis, x, y, ch1);
+ if (ch2 != '\0')
+ imonlcd_chr(drvthis, x+1, y, ch2);
+
+ return 0;
+}
+
+/**
+ * Draws a "big" number at the specified x-coordinate.
+ *
+ * Normally, the number that is displayed is "meant" to be 3x4 characters, but because we have a bit
+ * more flexibility, I've drawn the numbers as just being 12x16 pixels. That means that while the
+ * client will pass x-values between 0 and 16, we need to scale it and make sure the numbers remain
+ * centered.
+ *
+ * \param drvthis A pointer to the Driver structure.
+ * \param x The x-coordinate to display the character at.
+ * \param num The number to display ("10" is the colon).
+ */
+MODULE_EXPORT void imonlcd_num (Driver *drvthis, int x, int num)
+{
+ PrivateData *p = drvthis->private_data;
+
+ // This isn't that great, it makes assumptions about the coordinates the client passes to us.
+ // However, it works for MythTV... and looks pretty cool, too :-)
+ // TODO: Check the number flashing with the colon with mythtv
+ if(num < 10)
+ x = 12 + (int)(((x - 1) * p->cellwidth) * 0.75);
+ else
+ x = 12 + (int)(((x - 1) * p->cellwidth) * 0.72);
+
+ draw_bigchar(bigfont, (num >= 10 ? ':' : (num + '0')), x, 0, p);
+}
+
+/**
+ * Sets the "output state" for the device. We use this to control the icons around the outside the
+ * display. The bits in \c state correspond to the icons as follows:
+ *
+ * bit 0 : disc icon (0=off, 1='spin') , if Toprow==4, use CD-animation, else use "HDD-recording-animation"
+ * bit 1,2,3 : top row (0=none, 1=music, 2=movie, 3=photo, 4=CD/DVD, 5=TV, 6=Web, 7=News/Weather)
+ * bit 4,5 : 'speaker' icons (0=off, 1=L+R, 2=5.1ch, 3=7.1ch)
+ * bit 6 : S/PDIF icon
+ * bit 7 : 'SRC'
+ * bit 8 : 'FIT'
+ * bit 9 : 'TV'
+ * bit 10 : 'HDTV'
+ * bit 11 : 'SRC1'
+ * bit 12 : 'SRC2'
+ * bit 13,14,15: bottom-right icons (0=off, 1=MP3, 2=OGG, 3=WMA, 4=WAV)
+ * bit 16,17,18: bottom-middle icons (0=off, 1=MPG, 2=AC3, 3=DTS, 4=WMA)
+ * bit 19,20,21: bottom-left icons (0=off, 1=MPG, 2=DIVX, 3=XVID, 4=WMV)
+ * bit 22 : 'VOL' (volume)
+ * bit 23 : 'TIME'
+ * bit 24 : 'ALARM'
+ * bit 25 : 'REC' (recording)
+ * bit 26 : 'REP' (repeat)
+ * bit 27 : 'SFL' (shuffle)
+ * bit 28 : Abuse this for progress bars (if set to 1), lower bits represent
+ * the length (6 bits each: P|6xTP|6xTL|6xBL|6xBP with P = bit 28,
+ * TP=Top Progress, TL = Top Line, BL = Bottom Line, BP = Bottom Progress).
+ * If bit 28 is set to 1, lower bits are interpreted as
+ * lengths; otherwise setting the symbols as usual.
+ * 0 <= length <= 32, bars extend from left to right.
+ * length > 32, bars extend from right to left, length is counted
+ * from 32 up (i.e. 35 means a length of 3).
+ *
+ * Remember: There are two kinds of calls!
+ * With bit 28 set to 1: Set all bars (leaving the symbols as is),
+ * with bit 28 set to 0: Set the symbols (leaving the bars as is).
+ * Beware: TODO: May become a race condition, if both calls are executed
+ * before the display gets updated. Keep this in mind in your
+ * client-code.
+ * bit 29 : 'disc-in icon' - half ellipsoid under the disc symbols (0=off, 1=on)
+ */
+
+MODULE_EXPORT void imonlcd_output (Driver *drvthis, int state)
+{
+
+ PrivateData *p = drvthis->private_data;
+ uint64_t icon = 0x0;
+
+ if ( state == -1 ) // the value for "on" in the lcdproc-protocol
+ {
+ icon = (uint64_t)IMON_ICON_ALL;
+ send_command_data( COMMANDS_SET_ICONS | icon, p);
+ p->lastPrivateIconState = state;
+ setLineLength( 32, 32, 32, 32, p );
+
+ return;
+ }
+ else if ( state == 0x0 ) // the value for "off" in the lcdproc-protocol
+ {
+ icon = (uint64_t)0x0;;
+ send_command_data( COMMANDS_SET_ICONS | icon, p);
+ p->lastPrivateIconState = state;
+ setLineLength( 0, 0, 0, 0, p );
+ return;
+ }
+ // bit 28 : Abuse this for progress bars. See above for usage.
+ else if ( ( state & IMON_OUTPUT_PBARS_MASK ) != 0 && state > 0 )
+ {
+ int topProgress = ( state & 63 ); // extract the bar-values
+ int topLine = ( state & (63<<6) ) >> 6; // for each bar separately
+ int botProgress = ( state & (63<<12) ) >> 12;
+ int botLine = ( state & (63<<18) ) >> 18;
+
+ botProgress = botProgress > 32 ? -( botProgress - 32 ) : botProgress;
+ topProgress = topProgress > 32 ? -( topProgress - 32 ) : topProgress;
+ botLine = botLine > 32 ? -( botLine - 32 ) : botLine;
+ topLine = topLine > 32 ? -( topLine - 32 ) : topLine;
+
+ setLineLength( topLine, botLine, topProgress, botProgress, p );
+
+ state = p->lastPrivateIconState; // continue and set all other icons as before
+ }
+
+ // bit 0 : disc icon (0=off, 1='spin')
+ if ( ( state & IMON_OUTPUT_CD_MASK ) != 0 )
+ {
+ switch( p->last_cd_state ) {
+ case 0:
+ p->last_cd_state = 1;
+ if ( p->discMode == 1 )
+ icon |= ( (uint64_t)(255 - 128 - 8) << 40); // all on except top & bottom
+ else
+ icon |= ( (uint64_t)(128 | 8) << 40); // top & bottom on
+ break;
+ case 1:
+ p->last_cd_state = 2;
+ if ( p->discMode == 1 )
+ icon |= ( (uint64_t)(255 - 16 - 1) << 40); //all on except top-right & bottom-left
+ else
+ icon |= ( (uint64_t)(1 | 16) << 40); // top-right & bottom-left on
+ break;
+ case 2:
+ p->last_cd_state = 3;
+ if ( p->discMode == 1 )
+ icon |= ( (uint64_t)(255 - 32 - 2) << 40); // all on except right & left
+ else
+ icon |= ( (uint64_t)(32 | 2) << 40); // right & left on
+ break;
+ default:
+ p->last_cd_state = 0;
+ if ( p->discMode == 1 )
+ icon |= ( (uint64_t)(255 - 64 - 4) << 40); // all on except top-left & bottom-right
+ else
+ icon |= ( (uint64_t)(4 | 64) << 40); // top-left & bottom-right on
+ break;
+ }
+ }
+
+ // bit 1,2,3 : top row (0=none, 1=music, 2=movie, 3=photo, 4=CD/DVD, 5=TV, 6=Web, 7=News/Weather)
+ if ( ( ( state & IMON_OUTPUT_TOPROW_MASK ) != 0) )
+ {
+ switch( ( ( state & IMON_OUTPUT_TOPROW_MASK ) >> 1 ) )
+ {
+ case 1:
+ icon |= IMON_ICON_MUSIC;
+ break;
+ case 2:
+ icon |= IMON_ICON_MOVIE;
+ break;
+ case 3:
+ icon |= IMON_ICON_PHOTO;
+ break;
+ case 4:
+ icon |= IMON_ICON_CD_DVD;
+ break;
+ case 5:
+ icon |= IMON_ICON_TV;
+ break;
+ case 6:
+ icon |= IMON_ICON_WEBCAST;
+ break;
+ case 7:
+ icon |= IMON_ICON_NEWS;
+ break;
+ default:
+ break;
+ }
+ }
+ // bit 4,5 : 'speaker' icons (0=off, 1=L+R, 2=5.1ch, 3=7.1ch)
+ if ( ( ( state & IMON_OUTPUT_SPEAKER_MASK ) != 0) )
+ {
+ switch( ( ( state & IMON_OUTPUT_SPEAKER_MASK ) >> 4 ) )
+ {
+ case 1:
+ icon |= IMON_SPKR_FL | IMON_SPKR_FR;
+ break;
+ case 2:
+ icon |= IMON_SPKR_FL | IMON_SPKR_FC | IMON_SPKR_FR | IMON_SPKR_RL | IMON_SPKR_RR;
+ break;
+ case 3:
+ icon |= IMON_SPKR_FL | IMON_SPKR_FC | IMON_SPKR_FR | IMON_SPKR_RL | IMON_SPKR_RR | IMON_SPKR_SL | IMON_SPKR_SR;
+ break;
+ default:
+ break;
+ }
+ }
+ // bit 6 : S/PDIF icon
+ icon = ( ( state & IMON_OUTPUT_SPDIF_MASK ) != 0 ) ? (icon | IMON_SPKR_SPDIF) : (icon & ~IMON_SPKR_SPDIF);
+ // bit 7 : 'SRC'
+ icon = ( ( state & IMON_OUTPUT_SRC_MASK ) != 0 ) ? (icon | IMON_ICON_SRC) : (icon & ~IMON_ICON_SRC);
+ // bit 8 : 'FIT'
+ icon = ( ( state & IMON_OUTPUT_FIT_MASK ) != 0 ) ? (icon | IMON_ICON_FIT) : (icon & ~IMON_ICON_FIT);
+ // bit 9 : 'TV'
+ icon = ( ( state & IMON_OUTPUT_TV_MASK ) != 0 ) ? (icon | IMON_ICON_TV_2) : (icon & ~IMON_ICON_TV_2);
+ // bit 10 : 'HDTV'
+ icon = ( ( state & IMON_OUTPUT_HDTV_MASK ) != 0 ) ? (icon | IMON_ICON_HDTV) : (icon & ~IMON_ICON_HDTV);
+ // bit 11 : 'SRC1'
+ icon = ( ( state & IMON_OUTPUT_SCR1_MASK ) != 0 ) ? (icon | IMON_ICON_SCR1) : (icon & ~IMON_ICON_SCR1);
+ // bit 12 : 'SRC2'
+ icon = ( ( state & IMON_OUTPUT_SCR2_MASK ) != 0 ) ? (icon | IMON_ICON_SCR2) : (icon & ~IMON_ICON_SCR2);
+ // bit 13,14,15: bottom-right icons (0=off, 1=MP3, 2=OGG, 3=WMA, 4=WAV)
+ if ( ( ( state & IMON_OUTPUT_BRICONS_MASK ) != 0) )
+ {
+ switch( ( ( state & IMON_OUTPUT_BRICONS_MASK ) >> 13 ) )
+ {
+ case 1:
+ icon |= IMON_ICON_MP3;
+ break;
+ case 2:
+ icon |= IMON_ICON_OGG;
+ break;
+ case 3:
+ icon |= IMON_ICON_WMA;
+ break;
+ case 4:
+ icon |= IMON_ICON_WAV;
+ break;
+ default:
+ break;
+ }
+ }
+ // bit 16,17,18: bottom-middle icons (0=off, 1=MPG, 2=AC3, 3=DTS, 4=WMA)
+ if ( ( ( state & IMON_OUTPUT_BMICONS_MASK ) != 0) )
+ {
+ switch( ( ( state & IMON_OUTPUT_BMICONS_MASK ) >> 16 ) )
+ {
+ case 1:
+ icon |= IMON_ICON_MPG;
+ break;
+ case 2:
+ icon |= IMON_ICON_AC3;
+ break;
+ case 3:
+ icon |= IMON_ICON_DTS;
+ break;
+ case 4:
+ icon |= IMON_ICON_WMA;
+ break;
+ default:
+ break;
+ }
+ }
+ // bit 19,20,21: bottom-left icons (0=off, 1=MPG, 2=DIVX, 3=XVID, 4=WMV)
+ if ( ( ( state & IMON_OUTPUT_BLICONS_MASK ) != 0) )
+ {
+ switch( ( ( state & IMON_OUTPUT_BLICONS_MASK ) >> 19 ) )
+ {
+ case 1:
+ icon |= IMON_ICON_MPG;
+ break;
+ case 2:
+ icon |= IMON_ICON_DIVX;
+ break;
+ case 3:
+ icon |= IMON_ICON_XVID;
+ break;
+ case 4:
+ icon |= IMON_ICON_WMV;
+ break;
+ default:
+ break;
+ }
+ }
+ // bit 22 : 'VOL' (volume)
+ icon = ( ( state & IMON_OUTPUT_VOL_MASK ) != 0 ) ? (icon | IMON_ICON_VOL) : (icon & ~IMON_ICON_VOL);
+ // bit 23 : 'TIME'
+ icon = ( ( state & IMON_OUTPUT_TIME_MASK ) != 0 ) ? (icon | IMON_ICON_TIME) : (icon & ~IMON_ICON_TIME);
+ // bit 24 : 'ALARM'
+ icon = ( ( state & IMON_OUTPUT_ALARM_MASK ) != 0 ) ? (icon | IMON_ICON_ALARM) : (icon & ~IMON_ICON_ALARM);
+ // bit 25 : 'REC' (recording)
+ icon = ( ( state & IMON_OUTPUT_REC_MASK ) != 0 ) ? (icon | IMON_ICON_REC) : (icon & ~IMON_ICON_REC);
+ // bit 26 : 'REP' (repeat)
+ icon = ( ( state & IMON_OUTPUT_REP_MASK ) != 0 ) ? (icon | IMON_ICON_REP) : (icon & ~IMON_ICON_REP);
+ // bit 27 : 'SFL' (shuffle)
+ icon = ( ( state & IMON_OUTPUT_SFL_MASK ) != 0 ) ? (icon | IMON_ICON_SFL) : (icon & ~IMON_ICON_SFL);
+ // bit 29 : 'disc-in'
+ icon = ( ( state & IMON_OUTPUT_DISK_IN_MASK ) != 0 ) ? (icon | IMON_ICON_DISK_IN) : (icon & ~IMON_ICON_DISK_IN);
+
+ p->last_icon_state = (uint64_t)icon;
+ p->lastPrivateIconState = state;
+ send_command_data( COMMANDS_SET_ICONS | p->last_icon_state, p);
+}
+
+/**
+ * Return the display width in characters.
+ * \param drvthis Pointer to driver structure.
+ * \return Number of characters the display is wide.
+ */
+MODULE_EXPORT int imonlcd_width (Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+
+ return p->width;
+}
+
+
+/**
+ * Return the display height in characters.
+ * \param drvthis Pointer to driver structure.
+ * \return Number of characters the display is high.
+ */
+MODULE_EXPORT int imonlcd_height (Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+
+ return p->height;
+}
+
+
+/**
+ * Return the width of a character in pixels.
+ * \param drvthis Pointer to driver structure.
+ * \return Number of pixel columns a character cell is wide.
+ */
+MODULE_EXPORT int imonlcd_cellwidth (Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+
+ return p->cellwidth;
+}
+
+
+/**
+ * Return the height of a character in pixels.
+ * \param drvthis Pointer to driver structure.
+ * \return Number of pixel lines a character cell is high.
+ */
+MODULE_EXPORT int imonlcd_cellheight (Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+
+ return p->cellheight;
+}
+
+
+/**
+ * Sends a command to the screen. The kernel module expects data to be
+ * sent in 8 byte chunks, so for simplicity, we allow you to define
+ * the data as a 64-bit integer.
+ * However, we have to reverse the bytes to the order the display requires.
+ *
+ * \param value The data to send. Must be in a format that is recognized
+ * by the device. The kernel module doesn't actually do
+ * validation.
+ * \param p The private data containing the file descriptor to write to.
+ */
+static void send_command_data( uint64_t value, PrivateData *p )
+{
+ /*if ((commandData & COMMAND_MASK) == (COMMANDS_DISPLAY & COMMAND_MASK)) {
+ printf("%s: sending command: %lX\n", "imonlcd", commandData);
+ }*/
+
+ int i;
+ /* Fill the send buffer. */
+ for (i = 0; i < sizeof(p->tx_buf); i++)
+ {
+ p->tx_buf[i] = (unsigned char)((value >> (i * 8)) & 0xFF);
+ }
+
+ send_packet(p);
+}
+
+/**
+ * Sends data to the screen.
+ *
+ * \param p The private data structure containing a tx_buf with the data to send.
+ */
+static void send_packet(PrivateData *p)
+{
+ int err;
+ err = write(p->imon_fd, p->tx_buf, sizeof(p->tx_buf));
+
+ if ( err <= 0 )
+ printf( "%s: error writing to file descriptor: %d", "imon", err );
+}
+
+
+/**
+ * Sets the contrast of the display.
+ *
+ * \param drvthis Pointer to driver structure.
+ * \param promille The value the contrast is set to in promille
+ * (0 = lowest contrast; 1000 = highest contrast).
+ * \return 0 on failure, >0 on success.
+ */
+MODULE_EXPORT
+void imonlcd_set_contrast( Driver *drvthis, int promille )
+{
+ PrivateData *p = drvthis->private_data;
+
+ if ( promille < 0) {
+ promille = 0;
+ } else if ( promille > 1000 ) {
+ promille = 1000;
+ }
+
+ p->contrast = promille;
+
+ /* Send contrast normalized to the hardware-understandable-value (0 to 40).
+ 0 is the lowest and 40 is the highest.
+ The actual perceived contrast varies depending on the type of display.
+ */
+ send_command_data(COMMANDS_LOW_CONTRAST + (uint64_t)( p->contrast/25 ), p);
+}
+
+/**
+ * Gets the current contrast of the display.
+ *
+ * \param drvthis Pointer to driver structure.
+ * \return The current contrast in promille (0 = lowest contrast;
+ * 1000 = highest contrast).
+ */
+MODULE_EXPORT int imonlcd_get_contrast( Driver *drvthis )
+{
+ PrivateData *p = drvthis->private_data;
+ return p->contrast;
+}
+
+/**
+ * Sets the backlight state of the display.
+ *
+ * \param drvthis Pointer to driver structure.
+ * \param on The backlight state boolean-like: 0 = off; >0 = on.
+ */
+MODULE_EXPORT void imonlcd_backlight(Driver *drvthis, int on)
+{
+ PrivateData *p = drvthis->private_data;
+
+ /*
+ * TODO: For some reason, lcdproc keeps calling this and flipping the
+ * 'on' so you end up flashing the backlight for no particular reason
+ * (and on my Antec, turning the backlight off, turns the whole thing
+ * off, so it's really bad...)
+ */
+ return;
+
+ // To prevent superfluous (and erroneous) communication
+ if ( p->backlightOn == on )
+ return;
+ else
+ p->backlightOn = on;
+
+ if ( on )
+ {
+ send_command_data( p->command_display_on, p );
+ }
+ else
+ {
+ send_command_data( p->command_shutdown, p );
+ }
+}
+
+
+/**
+ * Draws a "big" character -- that is, one that's twice as big as a
+ * normal character -- at the specified position on the screen.
+ * \param font
+ * \param ch
+ * \param x - horizontal position
+ * \param y - vertical poisition
+ * \param p - pointer to the PrivateData structure
+ */
+static void draw_bigchar(imon_bigfont *font, int ch, int x, int y, PrivateData *p)
+{
+ imon_bigfont *defn = font;
+ int i;
+
+ while (defn->ch != ch && defn->ch != '\0') {
+ defn++;
+ }
+
+ int colBorder = 12; // correction for the number flashing with the colon running "lcdproc K"
+ if ( ch == ':' ) // TODO: Please check anybody with mythtv
+ colBorder = 6;
+ for(i = 0; i < colBorder; i++) {
+ p->framebuf[x + i + (y * colBorder)] = (defn->pixels[i] & 0xFF00) >> 8;
+ }
+ for(i = 0; i < colBorder; i++) {
+ p->framebuf[x + i + (y * colBorder) + p->bytesperline] = (defn->pixels[i] & 0x00FF);
+ }
+}
+
+
+/*
+ * TODO: Check if either setLineLength or setBuiltinProgressBars could be
+ * removed as the former is only a wrapper to the latter.
+ */
+/**
+ * Sets the length of the built-in progress-bars and lines.
+ * Values from -32 to 32 are allowed. Positive values indicate that bars extend
+ * from left to right, negative values indicate that the run from right to left.
+ * Conventient method to simplify setting the bars with "human understandable
+ * values".
+ *
+ * \see setBuiltinProgressBars, lengthToPixels
+ *
+ * \param topLine
+ * \param botLine
+ * \param topProgress
+ * \param botProgress
+ * \param p The private data structure containing the file descriptor to write to.
+ */
+static void setLineLength( int topLine, int botLine, int topProgress, int botProgress, PrivateData *p )
+{
+ setBuiltinProgressBars( lengthToPixels( topLine ),
+ lengthToPixels( botLine ),
+ lengthToPixels( topProgress ),
+ lengthToPixels( botProgress ),
+ p
+ );
+}
+
+/* TODO: Add parameter descriptions */
+/**
+ * Sets the length of the built-in progress-bars and lines.
+ * Values from -32 to 32 are allowed. Positive values indicate that bars extend
+ * from left to right, negative values indicate that the run from right to left.
+ *
+ * \param topLine
+ * \param botLine
+ * \param topProgress
+ * \param botProgress
+ * \param p The private data structure containing the file descriptor to write to.
+ */
+static void setBuiltinProgressBars( int topLine, int botLine,
+ int topProgress, int botProgress, PrivateData *p )
+{
+ // Least sig. bit is on the right
+ uint64_t data;
+
+ data = ( (uint64_t) topProgress ) << 8 * 4;
+ data |= (uint64_t) topLine & 0x00000000FFFFFFFFLL;
+ data &= 0x00FFFFFFFFFFFFFFLL;
+ send_command_data( COMMANDS_SET_LINES0 | data, p );
+
+ data = ( ( (uint64_t) topProgress ) >> 8 * 3 ) & 0x00000000000000FFLL;
+ data |= ( ( (uint64_t) botProgress ) << 8 ) & 0x000000FFFFFFFF00LL;
+ data |= ( ( (uint64_t) botLine ) << 8 * 5 ) & 0x00FFFF0000000000LL;
+ send_command_data( COMMANDS_SET_LINES1 | data, p );
+
+ data = ( (uint64_t) botLine ) >> 8 * 2;
+ send_command_data( COMMANDS_SET_LINES2 | data, p );
+}
+
+/**
+ * Maps values to corresponding pixmaps for the built-in progress bars.
+ * Values from -32 to 32 are allowed. Positive values indicate that bars extend
+ * from left to right, negative values indicate that they run from right to left.
+ *
+ * \param length The length of the bar.
+ * \return The pixmap that represents the given length.
+ *
+ */
+static int lengthToPixels( int length )
+{
+ int pixLen[] =
+ {
+ 0x00, 0x00000080, 0x000000c0, 0x000000e0, 0x000000f0,
+ 0x000000f8, 0x000000fc, 0x000000fe, 0x000000ff,
+ 0x000080ff, 0x0000c0ff, 0x0000e0ff, 0x0000f0ff,
+ 0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff,
+ 0x0080ffff, 0x00c0ffff, 0x00e0ffff, 0x00f0ffff,
+ 0x00f8ffff, 0x00fcffff, 0x00feffff, 0x00ffffff,
+ 0x80ffffff, 0xc0ffffff, 0xe0ffffff, 0xf0ffffff,
+ 0xf8ffffff, 0xfcffffff, 0xfeffffff, 0xffffffff
+ };
+
+ if ( abs( length ) > 32 )
+ {
+ return (0);
+ }
+ if ( length >= 0 )
+ {
+ return pixLen[ length ];
+ }
+ else
+ {
+ return ( pixLen[ 32 + length ] ^ 0xffffffff );
+ }
+}
+
+// EOF
+
Index: server/drivers/imonlcd.h
===================================================================
RCS file: server/drivers/imonlcd.h
diff -N server/drivers/imonlcd.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ server/drivers/imonlcd.h 18 Mar 2009 16:54:26 -0000
@@ -0,0 +1,81 @@
+/**
+ * Driver for SoundGraph iMON OEM LCD Modules
+ *
+ * Requires the lirc_imon module included with lirc >= 0.8.4a
+ */
+
+/* Modified March 2009 by Jonathan Kyler for inclusion in lcdproc
+ *
+ * Added 0038 support
+ * Added Protocol configuration parameter
+ *
+ * Modified March 2009 by Eric Pooch - lots of cleanup and streamlining
+ * Removed fixed "96" width listed everywhere
+ * Streamlined config file parsing
+ * Sped up font access
+ * Implemented backing store to avoid unnecessary refreshes
+ * Adjusted p->width and p->height to use character width and height properly
+ * Fixed long long defines
+ * Replaced send_data() and send_byte_data() with send_packet()
+ * Improved send_command_data()
+ * Reduced functions for basic character drawing - removed draw_char() and draw_string()
+ *
+ * Copyright (c) 2009, Jonathan Kyler
+ * 2004, Venky Raju
+ * 2007, Christian Leuschen
+ * 2007, Dean Harding
+ * 2009, Eric Pooch < epooch (at) cox (dot) net>
+ *
+ *
+ * This source code is being released under the GPL.
+ * Please see the file COPYING in this package for details.
+ *
+ */
+
+#ifndef IMONLCD_H
+#define IMONLCD_H
+
+#include "lcd.h"
+
+/* mandatory functions (necessary for all drivers) */
+MODULE_EXPORT int imonlcd_init (Driver *drvthis);
+MODULE_EXPORT void imonlcd_close (Driver *drvthis);
+
+/* essential output functions (necessary for output drivers) */
+MODULE_EXPORT int imonlcd_width (Driver *drvthis);
+MODULE_EXPORT int imonlcd_height (Driver *drvthis);
+MODULE_EXPORT void imonlcd_clear (Driver *drvthis);
+MODULE_EXPORT void imonlcd_flush (Driver *drvthis);
+MODULE_EXPORT void imonlcd_string (Driver *drvthis, int x, int y, const char string[]);
+MODULE_EXPORT void imonlcd_chr (Driver *drvthis, int x, int y, char c);
+
+/* essential input functions (necessary for all input drivers) */
+/* char *imonlcd_get_key NOT IMPLEMENTED */
+
+/* extended output functions (optional; core provides alternatives) */
+MODULE_EXPORT void imonlcd_vbar (Driver *drvthis, int x, int y, int len, int promille, int options);
+MODULE_EXPORT void imonlcd_hbar (Driver *drvthis, int x, int y, int len, int promille, int options);
+MODULE_EXPORT void imonlcd_num (Driver *drvthis, int x, int num);
+/* MODULE_EXPORT void imonlcd_heartbeat (Driver *drvthis, int state); NOT IMPLEMENTED */
+/* MODULE_EXPORT int imonlcd_icon (Driver *drvthis, int x, int y, int icon); NOT IMPLEMENTED */
+/* MODULE_EXPORT void imonlcd_cursor (Driver *drvthis, int x, int y, int type); NOT IMPLEMENTED */
+
+/* user-defined character functions, are those still supported ? */
+/* MODULE_EXPORT void imonlcd_set_char (Driver *drvthis, int n, char *dat); NOT IMPLEMENTED */
+/* MODULE_EXPORT int imonlcd_get_free_chars (Driver *drvthis); NOT IMPLEMENTED */
+MODULE_EXPORT int imonlcd_cellwidth (Driver *drvthis);
+MODULE_EXPORT int imonlcd_cellheight (Driver *drvthis);
+
+/* Hardware functions */
+MODULE_EXPORT int imonlcd_get_contrast (Driver *drvthis);
+MODULE_EXPORT void imonlcd_set_contrast (Driver *drvthis, int promille);
+/* MODULE_EXPORT int imonlcd_get_brightness (Driver *drvthis, int state); NOT IMPLEMENTED */
+/* MODULE_EXPORT void imonlcd_set_brightness (Driver *drvthis, int state, int promille); NOT IMPLEMENTED */
+MODULE_EXPORT void imonlcd_backlight(Driver *drvthis, int on);
+MODULE_EXPORT void imonlcd_output (Driver *drvthis, int state);
+
+/* informational functions */
+MODULE_EXPORT const char *imonlcd_get_info (Driver *drvthis);
+
+#endif
+