From 955ae7b8e49d15cfb94b39cc266189a8b9243d70 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Jun 22 2009 14:02:20 +0000 Subject: - Update to lcdproc v0.5.3 release - Drop upstreamed imonlcd and memset_swp patches - Switch to upstream's rpm initscripts (albeit still patched, need to get that bit upstream for the next release) --- diff --git a/.cvsignore b/.cvsignore index ff1d16f..945d27f 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1,2 @@ lcdproc-0.5.2.tar.gz +lcdproc-0.5.3.tar.gz diff --git a/lcdproc-0.5.2-imonlcd.patch b/lcdproc-0.5.2-imonlcd.patch deleted file mode 100644 index 2628aac..0000000 --- a/lcdproc-0.5.2-imonlcd.patch +++ /dev/null @@ -1,2859 +0,0 @@ -diff -Naurp lcdproc-0.5.2/acinclude.m4 lcdproc-0.5.2.imonlcd/acinclude.m4 ---- lcdproc-0.5.2/acinclude.m4 2007-04-14 10:39:28.000000000 -0400 -+++ lcdproc-0.5.2.imonlcd/acinclude.m4 2008-11-07 10:31:38.374066457 -0500 -@@ -6,7 +6,7 @@ AC_ARG_ENABLE(drivers, - [ 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,imonlcd2,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 @@ AC_ARG_ENABLE(drivers, - 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,imonlcd2,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,14 @@ dnl else - DRIVERS="$DRIVERS imon${SO}" - actdrivers=["$actdrivers imon"] - ;; -+ imonlcd) -+ DRIVERS="$DRIVERS imonlcd${SO}" -+ actdrivers=["$actdrivers imonlcd"] -+ ;; -+ imonlcd2) -+ DRIVERS="$DRIVERS imonlcd2${SO}" -+ actdrivers=["$actdrivers imonlcd2"] -+ ;; - IOWarrior) - if test "$enable_libusb" = yes ; then - DRIVERS="$DRIVERS IOWarrior${SO}" -diff -Naurp lcdproc-0.5.2/server/drivers/imonlcd2.c lcdproc-0.5.2.imonlcd/server/drivers/imonlcd2.c ---- lcdproc-0.5.2/server/drivers/imonlcd2.c 1969-12-31 19:00:00.000000000 -0500 -+++ lcdproc-0.5.2.imonlcd/server/drivers/imonlcd2.c 2008-11-07 10:39:57.741816312 -0500 -@@ -0,0 +1,1347 @@ -+/** -+ * Driver for SoundGraph iMON OEM (and others) LCD Module, newer version -+ * -+ * In order to be able to use it, you have to install the lirc_imon -+ * kernel module for LIRC (http://www.lirc.org) -+ * -+ * Copyright (c) 2007, Dean Harding , but (heavily :p) -+ * on the work of Venky Raju. -+ * Vastly (hopefully) improved by Christian Leuschen . -+ * -+ * 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" -+ -+ -+#include "imonlcd.h" -+ -+#define DEFAULT_DEVICE "/dev/lcd0" -+#define DEFAULT_SIZE "96x16" // This is the size in "pixels"... -+#define DEFAULT_CONTRAST "625" -+#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" -+ -+// 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 { -+ char info[255]; -+ int imon_fd; -+ unsigned char *framebuf; -+ int height; -+ int width; -+ int cellwidth; -+ int 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 -+ -+ /* -+ * 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) 0x0100000000000000 -+#define COMMANDS_SET_CONTRAST (uint64_t) 0x0300000000000000 -+#define COMMANDS_DISPLAY (uint64_t) 0x8800000000000000 -+#define COMMANDS_SHUTDOWN (uint64_t) 0x8800000000000008 -+#define COMMANDS_DISPLAY_ON (uint64_t) 0x8800000000000040 -+#define COMMANDS_CLEAR_ALARM (uint64_t) 0x8a00000000000000 -+#define COMMANDS_SET_LINES0 (uint64_t) 0x1000000000000000 -+#define COMMANDS_SET_LINES1 (uint64_t) 0x1100000000000000 -+#define COMMANDS_SET_LINES2 (uint64_t) 0x1200000000000000 -+ -+/* -+ * 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) 0x00FFFFFFFFFFFFFF -+//Byte 6 -+#define IMON_ICON_DISK_OFF (uint64_t) 0x7F7000FFFFFFFFFF -+#define IMON_ICON_DISK_ON (uint64_t) 0x0080FF0000000000 -+ -+#define IMON_ICON_DISK_IN (uint64_t) 0x0080000000000000 -+#define IMON_ICON_CD_IN (uint64_t) 0x00806B0000000000 -+#define IMON_ICON_DVD_IN (uint64_t) 0x0080550000000000 -+ -+// 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) -+ -+/* -+ * The iMON LCD doesn't have a "text mode" -- everthing is pixel-based. So we need to define -+ * our own font, basically. This structure holds the definition of that font. The characters -+ * we define here are 6x8 pixels in size, each byte in the 'pixels' array represents one column -+ * of pixels. The most significant bit is the top row, the least significant bit is the bottom -+ * row. -+ */ -+typedef struct { -+ int ch; -+ char pixels[6]; -+} imon_font; -+ -+static imon_font font[] = { -+ { ' ', { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }, -+ { '!', { 0x0, 0x0, 0x0, 0xF6, 0x0, 0x0 } }, -+ { '"', { 0x0, 0x0, 0xE0, 0x0, 0xE0, 0x0 } }, -+ { '#', { 0x0, 0x28, 0xFE, 0x28, 0xFE, 0x28 } }, -+ { '$', { 0x0, 0x0, 0xE0, 0x20, 0x78, 0x0 } }, -+ { '%', { 0x0, 0xC4, 0xC8, 0x10, 0x26, 0x46 } }, -+ { '&', { 0x0, 0x6C, 0x92, 0x6A, 0x4, 0xA } }, -+ { '\'', { 0x0, 0x0, 0x0, 0xE0, 0x0, 0x0 } }, -+ { '(', { 0x0, 0x0, 0x38, 0x44, 0x82, 0x0 } }, -+ { ')', { 0x0, 0x0, 0x82, 0x44, 0x38, 0x0 } }, -+ { '*', { 0x0, 0x28, 0x10, 0x7C, 0x10, 0x28 } }, -+ { '+', { 0x0, 0x10, 0x10, 0x7C, 0x10, 0x10 } }, -+ { ',', { 0x0, 0x0, 0xA, 0xC, 0x0, 0x0 } }, -+ { '-', { 0x0, 0x10, 0x10, 0x10, 0x10, 0x10 } }, -+ { '.', { 0x0, 0x0, 0x6, 0x6, 0x0, 0x0 } }, -+ { '/', { 0x0, 0x4, 0x8, 0x10, 0x20, 0x40 } }, -+ { '0', { 0x0, 0x7C, 0x8A, 0x92, 0xA2, 0x7C } }, -+ { '1', { 0x0, 0x0, 0x42, 0xFE, 0x2, 0x0 } }, -+ { '2', { 0x0, 0x42, 0x86, 0x8A, 0x92, 0x62 } }, -+ { '3', { 0x0, 0x84, 0x82, 0xA2, 0xD2, 0x8C } }, -+ { '4', { 0x0, 0x18, 0x28, 0x48, 0xFE, 0x8 } }, -+ { '5', { 0x0, 0xE4, 0xA2, 0xA2, 0xA2, 0x9C } }, -+ { '6', { 0x0, 0x3C, 0x52, 0x92, 0x92, 0xC } }, -+ { '7', { 0x0, 0x80, 0x8E, 0x90, 0xA0, 0xC0 } }, -+ { '8', { 0x0, 0x6C, 0x92, 0x92, 0x92, 0x6C } }, -+ { '9', { 0x0, 0x60, 0x92, 0x92, 0x94, 0x78 } }, -+ { ':', { 0x0, 0x0, 0x6C, 0x6C, 0x0, 0x0 } }, -+ { ';', { 0x0, 0x0, 0x6A, 0x6C, 0x0, 0x0 } }, -+ { '<', { 0x0, 0x10, 0x28, 0x44, 0x82, 0x0 } }, -+ { '=', { 0x0, 0x28, 0x28, 0x28, 0x28, 0x28 } }, -+ { '>', { 0x0, 0x0, 0x82, 0x44, 0x28, 0x10 } }, -+ { '?', { 0x0, 0x40, 0x80, 0x8A, 0x90, 0x60 } }, -+ { '@', { 0x0, 0x7C, 0x82, 0xBA, 0x92, 0x72 } }, -+ { 'A', { 0x0, 0x7E, 0x90, 0x90, 0x90, 0x7E } }, -+ { 'B', { 0x0, 0xFE, 0x92, 0x92, 0x92, 0x6C } }, -+ { 'C', { 0x0, 0x7C, 0x82, 0x82, 0x82, 0x44 } }, -+ { 'D', { 0x0, 0xFE, 0x82, 0x82, 0x82, 0x7C } }, -+ { 'E', { 0x0, 0xFE, 0x92, 0x92, 0x92, 0x82 } }, -+ { 'F', { 0x0, 0xFE, 0x90, 0x90, 0x90, 0x80 } }, -+ { 'G', { 0x0, 0x7C, 0x82, 0x92, 0x92, 0x5E } }, -+ { 'H', { 0x0, 0xFE, 0x10, 0x10, 0x10, 0xFE } }, -+ { 'I', { 0x0, 0x0, 0x82, 0xFE, 0x82, 0x0 } }, -+ { 'J', { 0x0, 0x4, 0x2, 0x82, 0xFC, 0x80 } }, -+ { 'K', { 0x0, 0xFE, 0x10, 0x28, 0x44, 0x82 } }, -+ { 'L', { 0x0, 0xFE, 0x2, 0x2, 0x2, 0x2 } }, -+ { 'M', { 0x0, 0xFE, 0x40, 0x30, 0x40, 0xFE } }, -+ { 'N', { 0x0, 0xFE, 0x20, 0x10, 0x8, 0xFE } }, -+ { 'O', { 0x0, 0x7C, 0x82, 0x82, 0x82, 0x7C } }, -+ { 'P', { 0x0, 0xFE, 0x90, 0x90, 0x90, 0x60 } }, -+ { 'Q', { 0x0, 0x7C, 0x82, 0x8A, 0x84, 0x7A } }, -+ { 'R', { 0x0, 0xFE, 0x90, 0x98, 0x94, 0x62 } }, -+ { 'S', { 0x0, 0x62, 0x92, 0x92, 0x92, 0x8C } }, -+ { 'T', { 0x0, 0x80, 0x80, 0xFE, 0x80, 0x80 } }, -+ { 'U', { 0x0, 0xFC, 0x2, 0x2, 0x2, 0xFC } }, -+ { 'V', { 0x0, 0xF0, 0xC, 0x2, 0xC, 0xF0 } }, -+ { 'W', { 0x0, 0xFC, 0x2, 0xC, 0x2, 0xFC } }, -+ { 'X', { 0x0, 0xC6, 0x28, 0x10, 0x28, 0xC6 } }, -+ { 'Y', { 0x0, 0xE0, 0x10, 0xE, 0x10, 0xE0 } }, -+ { 'Z', { 0x0, 0x86, 0x8A, 0x92, 0xA2, 0xC2 } }, -+ { '[', { 0x0, 0x0, 0xFE, 0x82, 0x0, 0x0 } }, -+ { '\\', { 0x0, 0x40, 0x20, 0x10, 0x8, 0x4 } }, -+ { ']', { 0x0, 0x0, 0x82, 0xFE, 0x0, 0x0 } }, -+ { '^', { 0x0, 0x20, 0x40, 0x80, 0x40, 0x20 } }, -+ { '_', { 0x0, 0x2, 0x2, 0x2, 0x2, 0x2 } }, -+ { '`', { 0x0, 0x0, 0x0, 0xC0, 0x20, 0x0 } }, -+ { 'a', { 0x0, 0x4, 0x2A, 0x2A, 0x2A, 0x1E } }, -+ { 'b', { 0x0, 0xFE, 0x12, 0x22, 0x22, 0x1C } }, -+ { 'c', { 0x0, 0x1C, 0x22, 0x22, 0x22, 0x4 } }, -+ { 'd', { 0x0, 0x1C, 0x22, 0x22, 0x12, 0xFE } }, -+ { 'e', { 0x0, 0x1C, 0x2A, 0x2A, 0x2A, 0x18 } }, -+ { 'f', { 0x0, 0x10, 0x7E, 0x90, 0x80, 0x40 } }, -+ { 'g', { 0x0, 0x30, 0x4A, 0x4A, 0x4A, 0x7C } }, -+ { 'h', { 0x0, 0xFE, 0x10, 0x20, 0x20, 0x1E } }, -+ { 'i', { 0x0, 0x0, 0x22, 0xBE, 0x2, 0x0 } }, -+ { 'j', { 0x0, 0x4, 0x2, 0x22, 0xBC, 0x0 } }, -+ { 'k', { 0x0, 0x0, 0xFE, 0x8, 0x14, 0x22 } }, -+ { 'l', { 0x0, 0x0, 0x82, 0xFE, 0x2, 0x0 } }, -+ { 'm', { 0x0, 0x3E, 0x20, 0x18, 0x20, 0x1E } }, -+ { 'n', { 0x0, 0x3E, 0x10, 0x20, 0x20, 0x1E } }, -+ { 'o', { 0x0, 0x1C, 0x22, 0x22, 0x22, 0x1C } }, -+ { 'p', { 0x0, 0x3E, 0x28, 0x28, 0x28, 0x10 } }, -+ { 'q', { 0x0, 0x10, 0x28, 0x28, 0x18, 0x3E } }, -+ { 'r', { 0x0, 0x3E, 0x10, 0x20, 0x20, 0x10 } }, -+ { 's', { 0x0, 0x12, 0x2A, 0x2A, 0x2A, 0x4 } }, -+ { 't', { 0x0, 0x20, 0xFC, 0x22, 0x2, 0x4 } }, -+ { 'u', { 0x0, 0x3C, 0x2, 0x2, 0x4, 0x3E } }, -+ { 'v', { 0x0, 0x38, 0x4, 0x2, 0x4, 0x38 } }, -+ { 'w', { 0x0, 0x3C, 0x2, 0xC, 0x2, 0x3C } }, -+ { 'x', { 0x0, 0x22, 0x14, 0x8, 0x14, 0x22 } }, -+ { 'y', { 0x0, 0x30, 0xA, 0xA, 0xA, 0x3C } }, -+ { 'z', { 0x0, 0x22, 0x26, 0x2A, 0x32, 0x22 } }, -+ { '{', { 0x0, 0x0, 0x10, 0x6C, 0x82, 0x82 } }, -+ { '|', { 0x0, 0x0, 0x0, 0xFE, 0x0, 0x0 } }, -+ { '}', { 0x0, 0x82, 0x82, 0x6C, 0x10, 0x0 } }, -+ { '~', { 0x0, 0x20, 0x40, 0x20, 0x10, 0x20 } }, -+/* -+ { 'Ö', { 0x0, 0x1C, 0xA2, 0x22, 0xA2, 0x1C } }, -+ { 'Ä', { 0x0, 0x04, 0xAA, 0x2A, 0xAA, 0x1E } }, -+ { 'Ü', { 0x0, 0x3C, 0x82, 0x02, 0x84, 0x3E } }, -+ { 'ö', { 0x0, 0x1C, 0xA2, 0x22, 0xA2, 0x1C } }, -+ { 'ä', { 0x0, 0x04, 0xAA, 0x2A, 0xAA, 0x1E } }, -+ { 'ü', { 0x0, 0x3C, 0x82, 0x02, 0x84, 0x3E } }, -+ { 'ß', { 0x0, 0x7E, 0x80, 0xA8, 0xA8, 0x50 } }, -+*/ -+ /* TODO -+ * Add more characters here. The 'ch' member is an int so theoretically, you could -+ * specify UTF-32 code points as the ch. But then you'd have to translate the UTF-8 -+ * (or whatever) input to imonlcd_string to UTF-32, which doesn't sound like much fun... -+ */ -+ -+ /* Marks the end of the array, but also serves as the character that -+ * unknown inputs are mapped to (essentially, a "space") -+ */ -+ { '\0' } -+}; -+ -+/** -+ * This is the definition for a "big" font, which is a font that simply takes up twice as many pixels -+ * as the normal font. We only use it 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' } -+}; -+ -+static void send_data(uint64_t value, int fd); -+static void send_byte_data(unsigned char data[], int fd); -+static void set_screen(unsigned char *columns, int fd); -+static void draw_char(imon_font *font, char ch, int x, int y, unsigned char *columns); -+static void draw_bigchar(imon_bigfont *font, int ch, int x, int y, unsigned char *columns); -+static void draw_string(imon_font *font, char *string, int fd); -+static void setLineLength( int topLine, int botLine, int topProgress, int botProgress, int fd ); -+static void setBuiltinProgressBars( int topLine, int botLine, -+ int topProgress, int botProgress, int fd ); -+static int lengthToPixels( int length ); -+static void send_command_data( uint64_t commandData, int fd ); -+ -+/** -+ * Initialize the driver. -+ * \param drvthis Pointer to driver structure. -+ * \return Information of success (1) or failure (< 0). -+ */ -+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]; -+ p->imon_fd = -1; -+ p->width = 0; -+ p->height = 0; -+ p->cellwidth = LCD_DEFAULT_CELL_WIDTH; -+ p->cellheight = LCD_DEFAULT_CELL_HEIGHT; -+ 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); -+ -+ /* 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 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", &p->width, &p->height) != 2) -+ || (p->width <= 0) || (p->width > LCD_MAX_WIDTH) -+ || (p->height <= 0) || (p->height > LCD_MAX_HEIGHT)) { -+ report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", -+ drvthis->name, buf, DEFAULT_SIZE); -+ sscanf(DEFAULT_SIZE , "%dx%d", &p->width, &p->height); -+ } -+ -+ /* Get the "on exit" setting so we know what to do when we shut the device down */ -+ strncpy(buf, drvthis->config_get_string(drvthis->name, "OnExit", 0, DEFAULT_ON_EXIT), sizeof(buf)); -+ buf[sizeof(buf)-1] = '\0'; -+ if ((sscanf(buf, "%d", &p->on_exit) != 1)) { -+ report(RPT_WARNING, "%s: cannot read OnExit: %s, using default %d", -+ drvthis->name, buf, DEFAULT_ON_EXIT); -+ sscanf(DEFAULT_ON_EXIT, "%d", &p->on_exit); -+ } -+ -+ /* Get the "contrast" setting */ -+ strncpy(buf, drvthis->config_get_string(drvthis->name, "Contrast", 0, DEFAULT_CONTRAST), sizeof(buf)); -+ buf[sizeof(buf)-1] = '\0'; -+ if ((sscanf(buf, "%d", &p->contrast) != 1)) { -+ report(RPT_WARNING, "%s: cannot read Contrast: %s, using default %d", -+ drvthis->name, buf, DEFAULT_CONTRAST); -+ sscanf(DEFAULT_CONTRAST, "%d", &p->contrast); -+ } -+ /* Get the "backlight" setting */ -+ strncpy(buf, drvthis->config_get_string(drvthis->name, "Backlight", 0, DEFAULT_BACKLIGHT), sizeof(buf)); -+ buf[sizeof(buf)-1] = '\0'; -+ if ((sscanf(buf, "%d", &p->backlightOn) != 1)) { -+ report(RPT_WARNING, "%s: cannot read Backlight: %s, using default %d", -+ drvthis->name, buf, DEFAULT_BACKLIGHT); -+ sscanf(DEFAULT_BACKLIGHT, "%d", &p->backlightOn); -+ } -+ /* Get the "disc-mode" setting */ -+ strncpy(buf, drvthis->config_get_string(drvthis->name, "DiscMode", 0, DEFAULT_DISCMODE), sizeof(buf)); -+ buf[sizeof(buf)-1] = '\0'; -+ if ((sscanf(buf, "%d", &p->discMode) != 1)) { -+ report(RPT_WARNING, "%s: cannot read DiscMode: %s, using default %d", -+ drvthis->name, buf, DEFAULT_DISCMODE); -+ sscanf(DEFAULT_DISCMODE, "%d", &p->discMode); -+ } -+ /* Make sure the frame buffer is there... */ -+ report(RPT_INFO, "%s: allocating %d bytes for framebuffer.", drvthis->name, p->width * (p->height / p->cellheight)); -+ p->framebuf = (unsigned char *) malloc(p->width * (p->height / p->cellheight)); -+ if (p->framebuf == NULL) { -+ report(RPT_ERR, "%s: unable to allocate framebuffer", drvthis->name); -+ return -1; -+ } -+ memset(p->framebuf, 0x00, p->width * (p->height / p->cellheight)); -+ -+ /* Send the "initialize" commands to the screen */ -+ /* TODO -+ * I still need to figure out what most of these do, and what should be "configurable"... -+ */ -+ if ( p->backlightOn ) -+ send_command_data( COMMANDS_DISPLAY_ON, p->imon_fd ); -+ else -+ send_command_data( COMMANDS_SHUTDOWN, p->imon_fd ); -+ send_command_data( COMMANDS_CLEAR_ALARM, p->imon_fd ); -+ imonlcd_set_contrast( drvthis, p->contrast ); -+ send_command_data( 0x0200000000000000, p->imon_fd ); // unknown -+ send_command_data( COMMANDS_SET_ICONS, p->imon_fd ); -+ send_command_data( COMMANDS_SET_LINES0, p->imon_fd ); // clear the progress-bars -+ send_command_data( COMMANDS_SET_LINES1, p->imon_fd ); // on top and bottom of the -+ send_command_data( COMMANDS_SET_LINES2, p->imon_fd ); // display -+ -+ report(RPT_DEBUG, "%s: init() done", drvthis->name); -+ -+ return 1; -+} -+ -+/** -+ * 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( COMMANDS_SHUTDOWN, p->imon_fd ); -+ send_command_data( COMMANDS_CLEAR_ALARM, p->imon_fd ); -+ } 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 += ((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->imon_fd); -+ send_command_data( COMMANDS_CLEAR_ALARM, p->imon_fd ); -+ } -+ -+ 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 OEM (and others) LCD driver"); -+ 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, 0, p->width * (p->height / 8)); -+} -+ -+ -+/** -+ * 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; -+ -+ set_screen(p->framebuf, p->imon_fd); -+} -+ -+ -+/** -+ * 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->cellwidth, p->height/p->cellheight). -+ * \param drvthis Pointer to driver structure. -+ * \param x Horizontal character position (column). -+ * \param y Vertical character position (row). -+ * \param c Character that gets written. -+ */ -+MODULE_EXPORT void imonlcd_chr (Driver *drvthis, int x, int y, char ch) -+{ -+ PrivateData *p = drvthis->private_data; -+ -+ y--; x--; -+ -+ if ((x < 0) || (y < 0) || (x >= (p->width / p->cellwidth)) || (y >= (p->height / p->cellheight))) -+ return; -+ -+ draw_char(font, ch, x * p->cellwidth, y * p->cellheight, p->framebuf); -+} -+ -+/** -+ * 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; -+ -+ if ((x < 0) || (y < 0) || (y > (p->width / p->cellwidth))) -+ return; -+ -+ // Pixels is the number of pixels we need to draw, vertically, based on the passed-in promille. -+ int pixels = (int) ( (double)( ( 2 * len * p->cellheight ) * ( (double)promille / 2000 ) ) ); -+ -+ x--; y--; -+ x *= p->cellwidth; -+ -+ int j, k; -+ unsigned char barChar; -+ -+ for ( j=0; j0 && k < 8; pixels-- ) -+ { -+ barChar = barChar | (1 << k); -+ k++; -+ } -+ p->framebuf[x+1 + ((y-j) * 96)] = barChar; -+ p->framebuf[x+2 + ((y-j) * 96)] = barChar; -+ p->framebuf[x+3 + ((y-j) * 96)] = barChar; -+ p->framebuf[x+4 + ((y-j) * 96)] = barChar; -+ p->framebuf[x+5 + ((y-j) * 96)] = barChar; -+ -+ } -+} -+ -+ -+/** -+ * 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; -+ -+ if ((x < 0) || (y < 0) || (y > (p->height / p->cellheight))) -+ return; -+ -+ // Pixels is the number of pixels we need to draw, horizontally, based on the passed-in promille. -+ int pixels = (int) ( (double)( ( 2 * len * p->cellwidth ) * ( (double)promille / 2000 ) ) ); -+ -+ x--; y--; -+ x *= p->cellwidth; -+ -+ for (; pixels >= 0; pixels--) { -+ -+ if (x > (p->width * p->cellwidth)) -+ return; -+ -+ p->framebuf[x + (y * 96)] = 0x3C; -+ x++; -+ } -+} -+ -+/** -+ * 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 point of the the Driver structure. -+ * \param the x-coordinate to display the character at. -+ * \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, and really it only works when your screen is 96 pixels wide and -+ // even then, 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 "lcdproc K". Done! Please anyone recheck 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->framebuf); -+} -+ -+/** -+ * 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->imon_fd); -+ p->lastPrivateIconState = state; -+ setLineLength( 32, 32, 32, 32, p->imon_fd ); -+ -+ 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->imon_fd); -+ p->lastPrivateIconState = state; -+ setLineLength( 0, 0, 0, 0, p->imon_fd ); -+ 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->imon_fd ); -+ -+ 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 | IMON_SPKR_LFE; -+ 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 | IMON_SPKR_LFE; -+ 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_WMA2; -+ 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_MPG2; -+ 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->imon_fd); -+} -+ -+/** -+ * 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/p->cellwidth; -+} -+ -+ -+/** -+ * 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/p->cellheight; -+} -+ -+ -+/** -+ * 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 data 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. -+ * -+ * \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 fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void send_data(uint64_t value, int fd) -+{ -+ /* TODO -+ * In order to make big- and little-endian issues more clear, we should probably -+ * drop this method in favour of the send_byte_data method... -+ */ -+ -+ // Note: We do it like this so that we can be sure we work on big- and little- -+ // endian machines the same way. -+ unsigned char data[8]; -+ data[0] = (value & 0xFF00000000000000) >> (7 * 8); -+ data[1] = (value & 0x00FF000000000000) >> (6 * 8); -+ data[2] = (value & 0x0000FF0000000000) >> (5 * 8); -+ data[3] = (value & 0x000000FF00000000) >> (4 * 8); -+ data[4] = (value & 0x00000000FF000000) >> (3 * 8); -+ data[5] = (value & 0x0000000000FF0000) >> (2 * 8); -+ data[6] = (value & 0x000000000000FF00) >> (1 * 8); -+ data[7] = (value & 0x00000000000000FF); -+ -+ send_byte_data(data, fd); -+} -+ -+/** -+ * TODO: Check why exactly this has to be done ;-) and if this also works for -+ * 64-bit OSs. -+ * Sends data 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. -+ * The bytes are reversed because all commands seem to need this to work! -+ * -+ * \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 fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void send_command_data( uint64_t commandData, int fd ) -+{ -+ if ((commandData & 0xFF00000000000000L) == 0x8800000000000000L) { -+ printf("%s: sending command: %lX\n", "imonlcd2", commandData); -+ } -+ -+ unsigned char data[8]; -+ data[7] = (unsigned char)((commandData >> 56) & 0xFF); -+ data[6] = (unsigned char)((commandData >> 48) & 0xFF); -+ data[5] = (unsigned char)((commandData >> 40) & 0xFF); -+ data[4] = (unsigned char)((commandData >> 32) & 0xFF); -+ data[3] = (unsigned char)((commandData >> 24) & 0xFF); -+ data[2] = (unsigned char)((commandData >> 16) & 0xFF); -+ data[1] = (unsigned char)((commandData >> 8) & 0xFF); -+ data[0] = (unsigned char)(commandData & 0xFF); -+ -+ send_byte_data(data, fd); -+ -+} -+ -+/** -+ * Sends data to the screen. -+ * -+ * \param data The 8 byte packet to send to the screen. -+ * \param fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void send_byte_data(unsigned char data[], int fd) -+{ -+ write(fd, data, 8); -+} -+ -+/** -+ * 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 int 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 usually the best, in my opinion) and 40 is the highest. TODO: @Dean: really 0=best?! -+ send_command_data(0x03FFFFFF00580A00L + (uint64_t)( p->contrast/25 ), p->imon_fd); -+ return 1; -+} -+ -+/** -+ * 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( COMMANDS_DISPLAY_ON, p->imon_fd ); -+ } -+ else -+ { -+ send_command_data( COMMANDS_SHUTDOWN, p->imon_fd ); -+ } -+} -+ -+/** -+ * Sets the pixels on the screen, using the specified "columns". -+ * Each column is eight pixels high (and represented by one byte) -+ * and the columns are filled from left to right. When the end -+ * of the screen is hit, the columns wrap to the next line. Each -+ * line is 96 pixels wide, so you need to pass an array of 192 -+ * bytes. -+ * -+ * \param columns The data for each column. -+ * \param fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void set_screen(unsigned char *columns, int fd) -+{ -+ /* TODO -+ * This could be implemented as a single call to write() with all the data, -+ * but that would require corresponding changes to the lirc kernel module. -+ */ -+ int i; -+ uint64_t msb; -+ uint64_t data; -+ int byteno; -+ -+ i = 0; -+ for (msb = 0x20; msb <= 0x3b; msb++) { -+ data = 0; -+ for (byteno = 1; byteno < 8; byteno ++) { -+ data |= columns[i]; -+ data <<= 8; -+ i++; -+ } -+ data |= msb; -+ send_data(data, fd); -+ } -+} -+ -+/** -+ * Draws a "big" character -- that is, one that's twice as big as a normal character -- at -+ * the specified position on the screen. -+ */ -+static void draw_bigchar(imon_bigfont *font, int ch, int x, int y, unsigned char *columns) -+{ -+ 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++) { -+ columns[x + i + (y * colBorder)] = (defn->pixels[i] & 0xFF00) >> 8; -+ } -+ for(i = 0; i < colBorder; i++) { -+ columns[x + i + (y * colBorder) + 96] = (defn->pixels[i] & 0x00FF); -+ } -+} -+ -+/** -+ * Draws a single character at the specified (x,y) coordinates of the given screen data. -+ */ -+static void draw_char(imon_font *font, char ch, int x, int y, unsigned char *columns) -+{ -+ imon_font *defn = font; -+ int i; -+ -+ while (defn->ch != ch && defn->ch != '\0') { -+ defn++; -+ } -+ -+ for(i = 0; i < 6; i++) { -+ columns[x + i + (y * 12)] = defn->pixels[i]; -+ } -+} -+ -+/** -+ * 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 fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void setLineLength( int topLine, int botLine, int topProgress, int botProgress, int fd ) -+{ -+ setBuiltinProgressBars( lengthToPixels( topLine ), -+ lengthToPixels( botLine ), -+ lengthToPixels( topProgress ), -+ lengthToPixels( botProgress ), -+ fd -+ ); -+} -+ -+/** -+ * 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 fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void setBuiltinProgressBars( int topLine, int botLine, -+ int topProgress, int botProgress, int fd ) -+{ -+ // Least sig. bit is on the right -+ uint64_t data; -+ -+ data = ( (uint64_t) topProgress ) << 8 * 4; -+ data |= (uint64_t) topLine & 0x00000000FFFFFFFF; -+ data &= 0x00FFFFFFFFFFFFFF; -+ send_command_data( COMMANDS_SET_LINES0 | data, fd ); -+ -+ data = ( ( (uint64_t) topProgress ) >> 8 * 3 ) & 0x00000000000000FF; -+ data |= ( ( (uint64_t) botProgress ) << 8 ) & 0x000000FFFFFFFF00; -+ data |= ( ( (uint64_t) botLine ) << 8 * 5 ) & 0x00FFFF0000000000; -+ send_command_data( COMMANDS_SET_LINES1 | data, fd ); -+ -+ data = ( (uint64_t) botLine ) >> 8 * 2; -+ send_command_data( COMMANDS_SET_LINES2 | data, fd ); -+} -+ -+/** -+ * 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 -+ -diff -Naurp lcdproc-0.5.2/server/drivers/imonlcd.c lcdproc-0.5.2.imonlcd/server/drivers/imonlcd.c ---- lcdproc-0.5.2/server/drivers/imonlcd.c 1969-12-31 19:00:00.000000000 -0500 -+++ lcdproc-0.5.2.imonlcd/server/drivers/imonlcd.c 2008-11-07 10:30:16.285849399 -0500 -@@ -0,0 +1,1349 @@ -+/** -+ * Driver for SoundGraph iMON OEM (and others) LCD Module -+ * -+ * In order to be able to use it, you have to install the lirc_imonlcd -+ * kernel module for LIRC (http://www.lirc.org) -- until that module is -+ * available in the main LIRC branch, you can get a patch for it from -+ * the same place you got this patch. -+ * -+ * Copyright (c) 2007, Dean Harding , but (heavily :p) -+ * on the work of Venky Raju. -+ * Vastly (hopefully) improved by Christian Leuschen . -+ * -+ * 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" -+ -+ -+#include "imonlcd.h" -+ -+#define DEFAULT_DEVICE "/dev/lcd0" -+#define DEFAULT_SIZE "96x16" // This is the size in "pixels"... -+#define DEFAULT_CONTRAST "625" -+#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" -+ -+// 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 { -+ char info[255]; -+ int imon_fd; -+ unsigned char *framebuf; -+ int height; -+ int width; -+ int cellwidth; -+ int 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 -+ -+ /* -+ * 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) 0x0100000000000000 -+#define COMMANDS_SET_CONTRAST (uint64_t) 0x0300000000000000 -+#define COMMANDS_DISPLAY (uint64_t) 0x5000000000000000 -+#define COMMANDS_SHUTDOWN (uint64_t) 0x5000000000000008 -+#define COMMANDS_DISPLAY_ON (uint64_t) 0x5000000000000040 -+#define COMMANDS_CLEAR_ALARM (uint64_t) 0x5100000000000000 -+#define COMMANDS_SET_LINES0 (uint64_t) 0x1000000000000000 -+#define COMMANDS_SET_LINES1 (uint64_t) 0x1100000000000000 -+#define COMMANDS_SET_LINES2 (uint64_t) 0x1200000000000000 -+ -+/* -+ * 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) 0x00FFFFFFFFFFFFFF -+//Byte 6 -+#define IMON_ICON_DISK_OFF (uint64_t) 0x7F7000FFFFFFFFFF -+#define IMON_ICON_DISK_ON (uint64_t) 0x0080FF0000000000 -+ -+#define IMON_ICON_DISK_IN (uint64_t) 0x0080000000000000 -+#define IMON_ICON_CD_IN (uint64_t) 0x00806B0000000000 -+#define IMON_ICON_DVD_IN (uint64_t) 0x0080550000000000 -+ -+// 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) -+ -+/* -+ * The iMON LCD doesn't have a "text mode" -- everthing is pixel-based. So we need to define -+ * our own font, basically. This structure holds the definition of that font. The characters -+ * we define here are 6x8 pixels in size, each byte in the 'pixels' array represents one column -+ * of pixels. The most significant bit is the top row, the least significant bit is the bottom -+ * row. -+ */ -+typedef struct { -+ int ch; -+ char pixels[6]; -+} imon_font; -+ -+static imon_font font[] = { -+ { ' ', { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }, -+ { '!', { 0x0, 0x0, 0x0, 0xF6, 0x0, 0x0 } }, -+ { '"', { 0x0, 0x0, 0xE0, 0x0, 0xE0, 0x0 } }, -+ { '#', { 0x0, 0x28, 0xFE, 0x28, 0xFE, 0x28 } }, -+ { '$', { 0x0, 0x0, 0xE0, 0x20, 0x78, 0x0 } }, -+ { '%', { 0x0, 0xC4, 0xC8, 0x10, 0x26, 0x46 } }, -+ { '&', { 0x0, 0x6C, 0x92, 0x6A, 0x4, 0xA } }, -+ { '\'', { 0x0, 0x0, 0x0, 0xE0, 0x0, 0x0 } }, -+ { '(', { 0x0, 0x0, 0x38, 0x44, 0x82, 0x0 } }, -+ { ')', { 0x0, 0x0, 0x82, 0x44, 0x38, 0x0 } }, -+ { '*', { 0x0, 0x28, 0x10, 0x7C, 0x10, 0x28 } }, -+ { '+', { 0x0, 0x10, 0x10, 0x7C, 0x10, 0x10 } }, -+ { ',', { 0x0, 0x0, 0xA, 0xC, 0x0, 0x0 } }, -+ { '-', { 0x0, 0x10, 0x10, 0x10, 0x10, 0x10 } }, -+ { '.', { 0x0, 0x0, 0x6, 0x6, 0x0, 0x0 } }, -+ { '/', { 0x0, 0x4, 0x8, 0x10, 0x20, 0x40 } }, -+ { '0', { 0x0, 0x7C, 0x8A, 0x92, 0xA2, 0x7C } }, -+ { '1', { 0x0, 0x0, 0x42, 0xFE, 0x2, 0x0 } }, -+ { '2', { 0x0, 0x42, 0x86, 0x8A, 0x92, 0x62 } }, -+ { '3', { 0x0, 0x84, 0x82, 0xA2, 0xD2, 0x8C } }, -+ { '4', { 0x0, 0x18, 0x28, 0x48, 0xFE, 0x8 } }, -+ { '5', { 0x0, 0xE4, 0xA2, 0xA2, 0xA2, 0x9C } }, -+ { '6', { 0x0, 0x3C, 0x52, 0x92, 0x92, 0xC } }, -+ { '7', { 0x0, 0x80, 0x8E, 0x90, 0xA0, 0xC0 } }, -+ { '8', { 0x0, 0x6C, 0x92, 0x92, 0x92, 0x6C } }, -+ { '9', { 0x0, 0x60, 0x92, 0x92, 0x94, 0x78 } }, -+ { ':', { 0x0, 0x0, 0x6C, 0x6C, 0x0, 0x0 } }, -+ { ';', { 0x0, 0x0, 0x6A, 0x6C, 0x0, 0x0 } }, -+ { '<', { 0x0, 0x10, 0x28, 0x44, 0x82, 0x0 } }, -+ { '=', { 0x0, 0x28, 0x28, 0x28, 0x28, 0x28 } }, -+ { '>', { 0x0, 0x0, 0x82, 0x44, 0x28, 0x10 } }, -+ { '?', { 0x0, 0x40, 0x80, 0x8A, 0x90, 0x60 } }, -+ { '@', { 0x0, 0x7C, 0x82, 0xBA, 0x92, 0x72 } }, -+ { 'A', { 0x0, 0x7E, 0x90, 0x90, 0x90, 0x7E } }, -+ { 'B', { 0x0, 0xFE, 0x92, 0x92, 0x92, 0x6C } }, -+ { 'C', { 0x0, 0x7C, 0x82, 0x82, 0x82, 0x44 } }, -+ { 'D', { 0x0, 0xFE, 0x82, 0x82, 0x82, 0x7C } }, -+ { 'E', { 0x0, 0xFE, 0x92, 0x92, 0x92, 0x82 } }, -+ { 'F', { 0x0, 0xFE, 0x90, 0x90, 0x90, 0x80 } }, -+ { 'G', { 0x0, 0x7C, 0x82, 0x92, 0x92, 0x5E } }, -+ { 'H', { 0x0, 0xFE, 0x10, 0x10, 0x10, 0xFE } }, -+ { 'I', { 0x0, 0x0, 0x82, 0xFE, 0x82, 0x0 } }, -+ { 'J', { 0x0, 0x4, 0x2, 0x82, 0xFC, 0x80 } }, -+ { 'K', { 0x0, 0xFE, 0x10, 0x28, 0x44, 0x82 } }, -+ { 'L', { 0x0, 0xFE, 0x2, 0x2, 0x2, 0x2 } }, -+ { 'M', { 0x0, 0xFE, 0x40, 0x30, 0x40, 0xFE } }, -+ { 'N', { 0x0, 0xFE, 0x20, 0x10, 0x8, 0xFE } }, -+ { 'O', { 0x0, 0x7C, 0x82, 0x82, 0x82, 0x7C } }, -+ { 'P', { 0x0, 0xFE, 0x90, 0x90, 0x90, 0x60 } }, -+ { 'Q', { 0x0, 0x7C, 0x82, 0x8A, 0x84, 0x7A } }, -+ { 'R', { 0x0, 0xFE, 0x90, 0x98, 0x94, 0x62 } }, -+ { 'S', { 0x0, 0x62, 0x92, 0x92, 0x92, 0x8C } }, -+ { 'T', { 0x0, 0x80, 0x80, 0xFE, 0x80, 0x80 } }, -+ { 'U', { 0x0, 0xFC, 0x2, 0x2, 0x2, 0xFC } }, -+ { 'V', { 0x0, 0xF0, 0xC, 0x2, 0xC, 0xF0 } }, -+ { 'W', { 0x0, 0xFC, 0x2, 0xC, 0x2, 0xFC } }, -+ { 'X', { 0x0, 0xC6, 0x28, 0x10, 0x28, 0xC6 } }, -+ { 'Y', { 0x0, 0xE0, 0x10, 0xE, 0x10, 0xE0 } }, -+ { 'Z', { 0x0, 0x86, 0x8A, 0x92, 0xA2, 0xC2 } }, -+ { '[', { 0x0, 0x0, 0xFE, 0x82, 0x0, 0x0 } }, -+ { '\\', { 0x0, 0x40, 0x20, 0x10, 0x8, 0x4 } }, -+ { ']', { 0x0, 0x0, 0x82, 0xFE, 0x0, 0x0 } }, -+ { '^', { 0x0, 0x20, 0x40, 0x80, 0x40, 0x20 } }, -+ { '_', { 0x0, 0x2, 0x2, 0x2, 0x2, 0x2 } }, -+ { '`', { 0x0, 0x0, 0x0, 0xC0, 0x20, 0x0 } }, -+ { 'a', { 0x0, 0x4, 0x2A, 0x2A, 0x2A, 0x1E } }, -+ { 'b', { 0x0, 0xFE, 0x12, 0x22, 0x22, 0x1C } }, -+ { 'c', { 0x0, 0x1C, 0x22, 0x22, 0x22, 0x4 } }, -+ { 'd', { 0x0, 0x1C, 0x22, 0x22, 0x12, 0xFE } }, -+ { 'e', { 0x0, 0x1C, 0x2A, 0x2A, 0x2A, 0x18 } }, -+ { 'f', { 0x0, 0x10, 0x7E, 0x90, 0x80, 0x40 } }, -+ { 'g', { 0x0, 0x30, 0x4A, 0x4A, 0x4A, 0x7C } }, -+ { 'h', { 0x0, 0xFE, 0x10, 0x20, 0x20, 0x1E } }, -+ { 'i', { 0x0, 0x0, 0x22, 0xBE, 0x2, 0x0 } }, -+ { 'j', { 0x0, 0x4, 0x2, 0x22, 0xBC, 0x0 } }, -+ { 'k', { 0x0, 0x0, 0xFE, 0x8, 0x14, 0x22 } }, -+ { 'l', { 0x0, 0x0, 0x82, 0xFE, 0x2, 0x0 } }, -+ { 'm', { 0x0, 0x3E, 0x20, 0x18, 0x20, 0x1E } }, -+ { 'n', { 0x0, 0x3E, 0x10, 0x20, 0x20, 0x1E } }, -+ { 'o', { 0x0, 0x1C, 0x22, 0x22, 0x22, 0x1C } }, -+ { 'p', { 0x0, 0x3E, 0x28, 0x28, 0x28, 0x10 } }, -+ { 'q', { 0x0, 0x10, 0x28, 0x28, 0x18, 0x3E } }, -+ { 'r', { 0x0, 0x3E, 0x10, 0x20, 0x20, 0x10 } }, -+ { 's', { 0x0, 0x12, 0x2A, 0x2A, 0x2A, 0x4 } }, -+ { 't', { 0x0, 0x20, 0xFC, 0x22, 0x2, 0x4 } }, -+ { 'u', { 0x0, 0x3C, 0x2, 0x2, 0x4, 0x3E } }, -+ { 'v', { 0x0, 0x38, 0x4, 0x2, 0x4, 0x38 } }, -+ { 'w', { 0x0, 0x3C, 0x2, 0xC, 0x2, 0x3C } }, -+ { 'x', { 0x0, 0x22, 0x14, 0x8, 0x14, 0x22 } }, -+ { 'y', { 0x0, 0x30, 0xA, 0xA, 0xA, 0x3C } }, -+ { 'z', { 0x0, 0x22, 0x26, 0x2A, 0x32, 0x22 } }, -+ { '{', { 0x0, 0x0, 0x10, 0x6C, 0x82, 0x82 } }, -+ { '|', { 0x0, 0x0, 0x0, 0xFE, 0x0, 0x0 } }, -+ { '}', { 0x0, 0x82, 0x82, 0x6C, 0x10, 0x0 } }, -+ { '~', { 0x0, 0x20, 0x40, 0x20, 0x10, 0x20 } }, -+/* -+ { 'Ö', { 0x0, 0x1C, 0xA2, 0x22, 0xA2, 0x1C } }, -+ { 'Ä', { 0x0, 0x04, 0xAA, 0x2A, 0xAA, 0x1E } }, -+ { 'Ü', { 0x0, 0x3C, 0x82, 0x02, 0x84, 0x3E } }, -+ { 'ö', { 0x0, 0x1C, 0xA2, 0x22, 0xA2, 0x1C } }, -+ { 'ä', { 0x0, 0x04, 0xAA, 0x2A, 0xAA, 0x1E } }, -+ { 'ü', { 0x0, 0x3C, 0x82, 0x02, 0x84, 0x3E } }, -+ { 'ß', { 0x0, 0x7E, 0x80, 0xA8, 0xA8, 0x50 } }, -+*/ -+ /* TODO -+ * Add more characters here. The 'ch' member is an int so theoretically, you could -+ * specify UTF-32 code points as the ch. But then you'd have to translate the UTF-8 -+ * (or whatever) input to imonlcd_string to UTF-32, which doesn't sound like much fun... -+ */ -+ -+ /* Marks the end of the array, but also serves as the character that -+ * unknown inputs are mapped to (essentially, a "space") -+ */ -+ { '\0' } -+}; -+ -+/** -+ * This is the definition for a "big" font, which is a font that simply takes up twice as many pixels -+ * as the normal font. We only use it 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' } -+}; -+ -+static void send_data(uint64_t value, int fd); -+static void send_byte_data(unsigned char data[], int fd); -+static void set_screen(unsigned char *columns, int fd); -+static void draw_char(imon_font *font, char ch, int x, int y, unsigned char *columns); -+static void draw_bigchar(imon_bigfont *font, int ch, int x, int y, unsigned char *columns); -+static void draw_string(imon_font *font, char *string, int fd); -+static void setLineLength( int topLine, int botLine, int topProgress, int botProgress, int fd ); -+static void setBuiltinProgressBars( int topLine, int botLine, -+ int topProgress, int botProgress, int fd ); -+static int lengthToPixels( int length ); -+static void send_command_data( uint64_t commandData, int fd ); -+ -+/** -+ * Initialize the driver. -+ * \param drvthis Pointer to driver structure. -+ * \return Information of success (1) or failure (< 0). -+ */ -+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]; -+ p->imon_fd = -1; -+ p->width = 0; -+ p->height = 0; -+ p->cellwidth = LCD_DEFAULT_CELL_WIDTH; -+ p->cellheight = LCD_DEFAULT_CELL_HEIGHT; -+ 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); -+ -+ /* 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 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", &p->width, &p->height) != 2) -+ || (p->width <= 0) || (p->width > LCD_MAX_WIDTH) -+ || (p->height <= 0) || (p->height > LCD_MAX_HEIGHT)) { -+ report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", -+ drvthis->name, buf, DEFAULT_SIZE); -+ sscanf(DEFAULT_SIZE , "%dx%d", &p->width, &p->height); -+ } -+ -+ /* Get the "on exit" setting so we know what to do when we shut the device down */ -+ strncpy(buf, drvthis->config_get_string(drvthis->name, "OnExit", 0, DEFAULT_ON_EXIT), sizeof(buf)); -+ buf[sizeof(buf)-1] = '\0'; -+ if ((sscanf(buf, "%d", &p->on_exit) != 1)) { -+ report(RPT_WARNING, "%s: cannot read OnExit: %s, using default %d", -+ drvthis->name, buf, DEFAULT_ON_EXIT); -+ sscanf(DEFAULT_ON_EXIT, "%d", &p->on_exit); -+ } -+ -+ /* Get the "contrast" setting */ -+ strncpy(buf, drvthis->config_get_string(drvthis->name, "Contrast", 0, DEFAULT_CONTRAST), sizeof(buf)); -+ buf[sizeof(buf)-1] = '\0'; -+ if ((sscanf(buf, "%d", &p->contrast) != 1)) { -+ report(RPT_WARNING, "%s: cannot read Contrast: %s, using default %d", -+ drvthis->name, buf, DEFAULT_CONTRAST); -+ sscanf(DEFAULT_CONTRAST, "%d", &p->contrast); -+ } -+ /* Get the "backlight" setting */ -+ strncpy(buf, drvthis->config_get_string(drvthis->name, "Backlight", 0, DEFAULT_BACKLIGHT), sizeof(buf)); -+ buf[sizeof(buf)-1] = '\0'; -+ if ((sscanf(buf, "%d", &p->backlightOn) != 1)) { -+ report(RPT_WARNING, "%s: cannot read Backlight: %s, using default %d", -+ drvthis->name, buf, DEFAULT_BACKLIGHT); -+ sscanf(DEFAULT_BACKLIGHT, "%d", &p->backlightOn); -+ } -+ /* Get the "disc-mode" setting */ -+ strncpy(buf, drvthis->config_get_string(drvthis->name, "DiscMode", 0, DEFAULT_DISCMODE), sizeof(buf)); -+ buf[sizeof(buf)-1] = '\0'; -+ if ((sscanf(buf, "%d", &p->discMode) != 1)) { -+ report(RPT_WARNING, "%s: cannot read DiscMode: %s, using default %d", -+ drvthis->name, buf, DEFAULT_DISCMODE); -+ sscanf(DEFAULT_DISCMODE, "%d", &p->discMode); -+ } -+ /* Make sure the frame buffer is there... */ -+ report(RPT_INFO, "%s: allocating %d bytes for framebuffer.", drvthis->name, p->width * (p->height / p->cellheight)); -+ p->framebuf = (unsigned char *) malloc(p->width * (p->height / p->cellheight)); -+ if (p->framebuf == NULL) { -+ report(RPT_ERR, "%s: unable to allocate framebuffer", drvthis->name); -+ return -1; -+ } -+ memset(p->framebuf, 0x00, p->width * (p->height / p->cellheight)); -+ -+ /* Send the "initialize" commands to the screen */ -+ /* TODO -+ * I still need to figure out what most of these do, and what should be "configurable"... -+ */ -+ if ( p->backlightOn ) -+ send_command_data( COMMANDS_DISPLAY_ON, p->imon_fd ); -+ else -+ send_command_data( COMMANDS_SHUTDOWN, p->imon_fd ); -+ send_command_data( COMMANDS_CLEAR_ALARM, p->imon_fd ); -+ imonlcd_set_contrast( drvthis, p->contrast ); -+ send_command_data( 0x0200000000000000, p->imon_fd ); // unknown -+ send_command_data( COMMANDS_SET_ICONS, p->imon_fd ); -+ send_command_data( COMMANDS_SET_LINES0, p->imon_fd ); // clear the progress-bars -+ send_command_data( COMMANDS_SET_LINES1, p->imon_fd ); // on top and bottom of the -+ send_command_data( COMMANDS_SET_LINES2, p->imon_fd ); // display -+ -+ report(RPT_DEBUG, "%s: init() done", drvthis->name); -+ -+ return 1; -+} -+ -+/** -+ * 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( COMMANDS_SHUTDOWN, p->imon_fd ); -+ send_command_data( COMMANDS_CLEAR_ALARM, p->imon_fd ); -+ } 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 += ((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->imon_fd); -+ send_command_data( COMMANDS_CLEAR_ALARM, p->imon_fd ); -+ } -+ -+ 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 OEM (and others) LCD driver"); -+ 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, 0, p->width * (p->height / 8)); -+} -+ -+ -+/** -+ * 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; -+ -+ set_screen(p->framebuf, p->imon_fd); -+} -+ -+ -+/** -+ * 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->cellwidth, p->height/p->cellheight). -+ * \param drvthis Pointer to driver structure. -+ * \param x Horizontal character position (column). -+ * \param y Vertical character position (row). -+ * \param c Character that gets written. -+ */ -+MODULE_EXPORT void imonlcd_chr (Driver *drvthis, int x, int y, char ch) -+{ -+ PrivateData *p = drvthis->private_data; -+ -+ y--; x--; -+ -+ if ((x < 0) || (y < 0) || (x >= (p->width / p->cellwidth)) || (y >= (p->height / p->cellheight))) -+ return; -+ -+ draw_char(font, ch, x * p->cellwidth, y * p->cellheight, p->framebuf); -+} -+ -+/** -+ * 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; -+ -+ if ((x < 0) || (y < 0) || (y > (p->width / p->cellwidth))) -+ return; -+ -+ // Pixels is the number of pixels we need to draw, vertically, based on the passed-in promille. -+ int pixels = (int) ( (double)( ( 2 * len * p->cellheight ) * ( (double)promille / 2000 ) ) ); -+ -+ x--; y--; -+ x *= p->cellwidth; -+ -+ int j, k; -+ unsigned char barChar; -+ -+ for ( j=0; j0 && k < 8; pixels-- ) -+ { -+ barChar = barChar | (1 << k); -+ k++; -+ } -+ p->framebuf[x+1 + ((y-j) * 96)] = barChar; -+ p->framebuf[x+2 + ((y-j) * 96)] = barChar; -+ p->framebuf[x+3 + ((y-j) * 96)] = barChar; -+ p->framebuf[x+4 + ((y-j) * 96)] = barChar; -+ p->framebuf[x+5 + ((y-j) * 96)] = barChar; -+ -+ } -+} -+ -+ -+/** -+ * 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; -+ -+ if ((x < 0) || (y < 0) || (y > (p->height / p->cellheight))) -+ return; -+ -+ // Pixels is the number of pixels we need to draw, horizontally, based on the passed-in promille. -+ int pixels = (int) ( (double)( ( 2 * len * p->cellwidth ) * ( (double)promille / 2000 ) ) ); -+ -+ x--; y--; -+ x *= p->cellwidth; -+ -+ for (; pixels >= 0; pixels--) { -+ -+ if (x > (p->width * p->cellwidth)) -+ return; -+ -+ p->framebuf[x + (y * 96)] = 0x3C; -+ x++; -+ } -+} -+ -+/** -+ * 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 point of the the Driver structure. -+ * \param the x-coordinate to display the character at. -+ * \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, and really it only works when your screen is 96 pixels wide and -+ // even then, 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 "lcdproc K". Done! Please anyone recheck 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->framebuf); -+} -+ -+/** -+ * 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->imon_fd); -+ p->lastPrivateIconState = state; -+ setLineLength( 32, 32, 32, 32, p->imon_fd ); -+ -+ 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->imon_fd); -+ p->lastPrivateIconState = state; -+ setLineLength( 0, 0, 0, 0, p->imon_fd ); -+ 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->imon_fd ); -+ -+ 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 | IMON_SPKR_LFE; -+ 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 | IMON_SPKR_LFE; -+ 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_WMA2; -+ 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_MPG2; -+ 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->imon_fd); -+} -+ -+/** -+ * 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/p->cellwidth; -+} -+ -+ -+/** -+ * 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/p->cellheight; -+} -+ -+ -+/** -+ * 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 data 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. -+ * -+ * \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 fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void send_data(uint64_t value, int fd) -+{ -+ /* TODO -+ * In order to make big- and little-endian issues more clear, we should probably -+ * drop this method in favour of the send_byte_data method... -+ */ -+ -+ // Note: We do it like this so that we can be sure we work on big- and little- -+ // endian machines the same way. -+ unsigned char data[8]; -+ data[0] = (value & 0xFF00000000000000) >> (7 * 8); -+ data[1] = (value & 0x00FF000000000000) >> (6 * 8); -+ data[2] = (value & 0x0000FF0000000000) >> (5 * 8); -+ data[3] = (value & 0x000000FF00000000) >> (4 * 8); -+ data[4] = (value & 0x00000000FF000000) >> (3 * 8); -+ data[5] = (value & 0x0000000000FF0000) >> (2 * 8); -+ data[6] = (value & 0x000000000000FF00) >> (1 * 8); -+ data[7] = (value & 0x00000000000000FF); -+ -+ send_byte_data(data, fd); -+} -+ -+/** -+ * TODO: Check why exactly this has to be done ;-) and if this also works for -+ * 64-bit OSs. -+ * Sends data 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. -+ * The bytes are reversed because all commands seem to need this to work! -+ * -+ * \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 fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void send_command_data( uint64_t commandData, int fd ) -+{ -+ if ((commandData & 0xFF00000000000000L) == 0x5000000000000000L) { -+ printf("%s: sending command: %lX\n", "imonlcd", commandData); -+ } -+ -+ unsigned char data[8]; -+ data[7] = (unsigned char)((commandData >> 56) & 0xFF); -+ data[6] = (unsigned char)((commandData >> 48) & 0xFF); -+ data[5] = (unsigned char)((commandData >> 40) & 0xFF); -+ data[4] = (unsigned char)((commandData >> 32) & 0xFF); -+ data[3] = (unsigned char)((commandData >> 24) & 0xFF); -+ data[2] = (unsigned char)((commandData >> 16) & 0xFF); -+ data[1] = (unsigned char)((commandData >> 8) & 0xFF); -+ data[0] = (unsigned char)(commandData & 0xFF); -+ -+ send_byte_data(data, fd); -+ -+} -+ -+/** -+ * Sends data to the screen. -+ * -+ * \param data The 8 byte packet to send to the screen. -+ * \param fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void send_byte_data(unsigned char data[], int fd) -+{ -+ write(fd, data, 8); -+} -+ -+/** -+ * 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 int 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 usually the best, in my opinion) and 40 is the highest. TODO: @Dean: really 0=best?! -+ send_command_data(0x03FFFFFF00580A00L + (uint64_t)( p->contrast/25 ), p->imon_fd); -+ return 1; -+} -+ -+/** -+ * 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( COMMANDS_DISPLAY_ON, p->imon_fd ); -+ } -+ else -+ { -+ send_command_data( COMMANDS_SHUTDOWN, p->imon_fd ); -+ } -+} -+ -+/** -+ * Sets the pixels on the screen, using the specified "columns". -+ * Each column is eight pixels high (and represented by one byte) -+ * and the columns are filled from left to right. When the end -+ * of the screen is hit, the columns wrap to the next line. Each -+ * line is 96 pixels wide, so you need to pass an array of 192 -+ * bytes. -+ * -+ * \param columns The data for each column. -+ * \param fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void set_screen(unsigned char *columns, int fd) -+{ -+ /* TODO -+ * This could be implemented as a single call to write() with all the data, -+ * but that would require corresponding changes to the lirc kernel module. -+ */ -+ int i; -+ uint64_t msb; -+ uint64_t data; -+ int byteno; -+ -+ i = 0; -+ for (msb = 0x20; msb <= 0x3b; msb++) { -+ data = 0; -+ for (byteno = 1; byteno < 8; byteno ++) { -+ data |= columns[i]; -+ data <<= 8; -+ i++; -+ } -+ data |= msb; -+ send_data(data, fd); -+ } -+} -+ -+/** -+ * Draws a "big" character -- that is, one that's twice as big as a normal character -- at -+ * the specified position on the screen. -+ */ -+static void draw_bigchar(imon_bigfont *font, int ch, int x, int y, unsigned char *columns) -+{ -+ 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++) { -+ columns[x + i + (y * colBorder)] = (defn->pixels[i] & 0xFF00) >> 8; -+ } -+ for(i = 0; i < colBorder; i++) { -+ columns[x + i + (y * colBorder) + 96] = (defn->pixels[i] & 0x00FF); -+ } -+} -+ -+/** -+ * Draws a single character at the specified (x,y) coordinates of the given screen data. -+ */ -+static void draw_char(imon_font *font, char ch, int x, int y, unsigned char *columns) -+{ -+ imon_font *defn = font; -+ int i; -+ -+ while (defn->ch != ch && defn->ch != '\0') { -+ defn++; -+ } -+ -+ for(i = 0; i < 6; i++) { -+ columns[x + i + (y * 12)] = defn->pixels[i]; -+ } -+} -+ -+/** -+ * 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 fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void setLineLength( int topLine, int botLine, int topProgress, int botProgress, int fd ) -+{ -+ setBuiltinProgressBars( lengthToPixels( topLine ), -+ lengthToPixels( botLine ), -+ lengthToPixels( topProgress ), -+ lengthToPixels( botProgress ), -+ fd -+ ); -+} -+ -+/** -+ * 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 fd A file descriptor pointing to the /dev/lcd* file that we write to. -+ */ -+static void setBuiltinProgressBars( int topLine, int botLine, -+ int topProgress, int botProgress, int fd ) -+{ -+ // Least sig. bit is on the right -+ uint64_t data; -+ -+ data = ( (uint64_t) topProgress ) << 8 * 4; -+ data |= (uint64_t) topLine & 0x00000000FFFFFFFF; -+ data &= 0x00FFFFFFFFFFFFFF; -+ send_command_data( COMMANDS_SET_LINES0 | data, fd ); -+ -+ data = ( ( (uint64_t) topProgress ) >> 8 * 3 ) & 0x00000000000000FF; -+ data |= ( ( (uint64_t) botProgress ) << 8 ) & 0x000000FFFFFFFF00; -+ data |= ( ( (uint64_t) botLine ) << 8 * 5 ) & 0x00FFFF0000000000; -+ send_command_data( COMMANDS_SET_LINES1 | data, fd ); -+ -+ data = ( (uint64_t) botLine ) >> 8 * 2; -+ send_command_data( COMMANDS_SET_LINES2 | data, fd ); -+} -+ -+/** -+ * 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 -+ -diff -Naurp lcdproc-0.5.2/server/drivers/imonlcd.h lcdproc-0.5.2.imonlcd/server/drivers/imonlcd.h ---- lcdproc-0.5.2/server/drivers/imonlcd.h 1969-12-31 19:00:00.000000000 -0500 -+++ lcdproc-0.5.2.imonlcd/server/drivers/imonlcd.h 2008-11-07 10:30:16.286851426 -0500 -@@ -0,0 +1,49 @@ -+/** -+ * Driver for SoundGraph iMON OEM (and others) LCD Module -+ * -+ * In order to be able to use it, you have to install the lirc_imonlcd -+ * kernel module for LIRC (http://www.lirc.org) -- until that module is -+ * available in the main LIRC branch, you can get a patch for it from -+ * the same place you got this patch. -+ * -+ * Copyright (c) 2007, Dean Harding , but (heavily :p) -+ * on the work of Venky Raju. -+ * -+ * 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" -+ -+MODULE_EXPORT int imonlcd_init (Driver *drvthis); -+MODULE_EXPORT void imonlcd_close (Driver *drvthis); -+MODULE_EXPORT int imonlcd_width (Driver *drvthis); -+MODULE_EXPORT int imonlcd_height (Driver *drvthis); -+MODULE_EXPORT int imonlcd_cellwidth (Driver *drvthis); -+MODULE_EXPORT int imonlcd_cellheight (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); -+MODULE_EXPORT const char *imonlcd_get_info (Driver *drvthis); -+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_output (Driver *drvthis, int state); -+MODULE_EXPORT int imonlcd_set_contrast (Driver *drvthis, int promille); -+MODULE_EXPORT int imonlcd_get_contrast (Driver *drvthis); -+MODULE_EXPORT void imonlcd_backlight(Driver *drvthis, int on); -+ -+/** -+ * These are not supported by the iMON LCD module -+ */ -+//MODULE_EXPORT int imonlcd_get_free_chars (Driver *drvthis); -+//MODULE_EXPORT void imonlcd_set_char (Driver *drvthis, int n, char *dat); -+//MODULE_EXPORT int imonlcd_icon (Driver *drvthis, int x, int y, int icon); -+ -+#endif -+ -diff -Naurp lcdproc-0.5.2/server/drivers/Makefile.am lcdproc-0.5.2.imonlcd/server/drivers/Makefile.am ---- lcdproc-0.5.2/server/drivers/Makefile.am 2007-04-14 10:39:53.000000000 -0400 -+++ lcdproc-0.5.2.imonlcd/server/drivers/Makefile.am 2008-11-07 10:32:58.927066724 -0500 -@@ -19,7 +19,7 @@ AM_LDFLAGS = @LDSHARED@ - #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 imonlcd2 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,8 @@ hd44780_LDADD = libLCD.a @HD44780_D - hd44780_DEPENDENCIES = @HD44780_DRIVERS@ - icp_a106_LDADD = libLCD.a - imon_LDADD = libLCD.a -+imonlcd_LDADD = libLCD.a -+imonlcd2_LDADD = libLCD.a - IOWarrior_LDADD = @libusb_libs@ libLCD.a libbignum.a - irman_LDADD = @LIBIRMAN@ - lcterm_LDADD = libLCD.a -@@ -75,6 +77,8 @@ EXTRA_hd44780_SOURCES = hd44780-4bit.c h - - 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 -+imonlcd2_SOURCES = lcd.h lcd_lib.h imonlcd.h imonlcd2.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 ---- lcdproc-0.5.2/LCDd.conf 2007-04-14 10:41:51.000000000 -0400 -+++ lcdproc-0.5.2.imonlcd/LCDd.conf 2008-11-07 12:01:18.193816869 -0500 -@@ -37,7 +37,7 @@ - # - # The following drivers are supported: - # 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, imonlcd2, 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 -@@ -508,7 +508,7 @@ Size=20x4 - - - --## Soundgraph/Ahanix/Silverstone/Uneed/Accent iMON driver ## -+## Soundgraph/Ahanix/Silverstone/Uneed/Accent iMON VFD driver ## - [imon] - - # select the device to use -@@ -517,6 +517,15 @@ Device=/dev/lcd0 - # display dimensions - Size=16x2 - -+## Soundgraph first-gen lcd device ## -+[imonlcd] -+Device=/dev/lcd0 -+Contrast=200 -+ -+## Soundgraph second-gen lcd device ## -+[imonlcd2] -+Device=/dev/lcd0 -+Contrast=200 - - - ## IrMan driver ## diff --git a/lcdproc-0.5.2-initscripts.patch b/lcdproc-0.5.2-initscripts.patch deleted file mode 100644 index fe83c45..0000000 --- a/lcdproc-0.5.2-initscripts.patch +++ /dev/null @@ -1,310 +0,0 @@ -diff -up lcdproc-0.5.2/scripts/init-LCDd.LSB.in.initscripts lcdproc-0.5.2/scripts/init-LCDd.LSB.in ---- lcdproc-0.5.2/scripts/init-LCDd.LSB.in.initscripts 2007-04-14 16:41:20.000000000 +0200 -+++ lcdproc-0.5.2/scripts/init-LCDd.LSB.in 2009-05-13 17:14:25.000000000 +0200 -@@ -1,10 +1,18 @@ - #! /bin/sh -+# -+# chkconfig: - 70 21 -+# description: LCDd(8) is the LCDproc server used for displaying text and other data to LCDs. \ -+# Apart from the main client lcdproc(1) there are various clients. \ -+# See http://lcdproc.omnipotent.net for details. -+# processname: LCDd -+# -+# config: /etc/sysconfig/lcdproc/LCDd.conf - --#### BEGIN INIT INFO -+### BEGIN INIT INFO - # Provides: LCDd - # Required-Start: $syslog $local_fs $network $remote_fs - # Required-Stop: $syslog $local_fs $network $remote_fs --# Default-Start: 2 3 4 5 -+# Default-Start: - # Default-Stop: S 0 1 6 - # Short-Description: LCDproc Server Daemon - # Description: LSB init script for LCDd, the display -@@ -12,57 +20,92 @@ - ### END INIT INFO - - --# local variables --prefix=@prefix@ --exec_prefix=@exec_prefix@ --bindir=@bindir@ --sbindir=@sbindir@ --etc=@sysconfdir@ -- --PATH=/sbin:/bin:/usr/sbin:/usr/bin --NAME=LCDd --DAEMON=${sbindir}/$NAME --DESC="LCDproc display server daemon" --DEFAULTS=/etc/default/$NAME --START=yes -- --# Source defaults file; edit that file to configure this script. --if [ -e "${DEFAULTS}" ]; then -- . "${DEFAULTS}" -+prog=LCDd -+lockfile=/var/lock/subsys/$prog -+configfile=@sysconfdir@/$prog.conf -+RETVAL=0 -+ -+ -+# load LSB 3.x init functions -+if [ -e /lib/lsb/init-functions ]; then -+ . /lib/lsb/init-functions - fi - --# If we're not to start the daemon, simply exit --if [ "${START}" != "yes" ]; then -- exit 0 -+# Source function library. -+if [ -e /etc/rc.d/init.d/functions ]; then -+ . /etc/rc.d/init.d/functions - fi - --# installation check --test -x $DAEMON || exit 5 -+# check that non-default config file exists. -+ [ -f $configfile ] || exit 6 - --# load LSB 3.x init functions --. /lib/lsb/init-functions -+ -+start() { -+ echo -n $"Starting $prog services: " -+ daemon $prog -c $configfile -+ RETVAL=$? -+ echo -+ [ $RETVAL -eq 0 ] && touch $lockfile || \ -+ RETVAL=1 -+ return $RETVAL -+} -+ -+stop() { -+ echo -n $"Shutting down $prog services: " -+ killproc $prog -+ RETVAL=$? -+ echo -+ [ $RETVAL -eq 0 ] && rm -f $lockfile -+ return $RETVAL -+} -+ -+reload() { -+ echo -n $"Reloading $prog file: " -+ killproc $prog -HUP -+ RETVAL=$? -+ echo -+ return $RETVAL -+} -+ -+rhstatus() { -+ status $prog -+ return $? -+} -+ -+ -+# Allow status as non-root. -+if [ "$1" = status ]; then -+ rhstatus -+ exit $? -+fi - - - case "$1" in - start) -- log_daemon_msg "Starting $DESC" "$NAME" -- start_daemon $DAEMON $OPTIONS -- log_end_msg $? -+ start - ;; - stop) -- log_daemon_msg "Stopping $DESC" "$NAME" -- killproc $DAEMON -- log_end_msg $? -- ;; -- restart|reload|force-reload) -- $0 stop -- sleep 1 -- $0 start -+ stop -+ ;; -+ status) -+ status $prog -+ ;; -+ restart|force-reload) -+ stop -+ start -+ ;; -+ try-restart|condrestart) -+ if [ -f $lockfile ]; then -+ stop -+ start -+ fi -+ ;; -+ reload) -+ reload - ;; - *) -- echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2 -+ echo $"Usage: $0 {start|stop|status|restart|try-restart|force-reload}" - exit 2 -- ;; - esac - --exit 0 -+exit $RETVAL -diff -up lcdproc-0.5.2/scripts/init-lcdproc.LSB.in.initscripts lcdproc-0.5.2/scripts/init-lcdproc.LSB.in ---- lcdproc-0.5.2/scripts/init-lcdproc.LSB.in.initscripts 2007-04-14 16:41:20.000000000 +0200 -+++ lcdproc-0.5.2/scripts/init-lcdproc.LSB.in 2009-05-13 10:37:32.000000000 +0200 -@@ -1,10 +1,19 @@ - #! /bin/sh -+# -+# chkconfig: - 71 20 -+# description: LCDd(8) is the LCDproc server used for displaying text and other data to LCDs. \ -+# Apart from the main client lcdproc(1) there are various clients. \ -+# See http://lcdproc.omnipotent.net for details. -+# processname: lcdproc -+# -+# config: /etc/sysconfig/lcdproc/lcdproc.conf - --#### BEGIN INIT INFO -+### BEGIN INIT INFO - # Provides: lcdproc - # Required-Start: $syslog $local_fs $network $remote_fs - # Required-Stop: $syslog $local_fs $network $remote_fs --# Default-Start: 2 3 4 5 -+# Should-Start: LCDd -+# Default-Start: - # Default-Stop: S 0 1 6 - # Short-Description: LCDproc system status information viewer - # Description: LSB init script for lcdproc, the system -@@ -12,57 +21,91 @@ - ### END INIT INFO - - --# local variables --prefix=@prefix@ --exec_prefix=@exec_prefix@ --bindir=@bindir@ --sbindir=@sbindir@ --etc=@sysconfdir@ -- --PATH=/sbin:/bin:/usr/sbin:/usr/bin --NAME=lcdproc --DAEMON=${bindir}/$NAME --DESC="LCDproc system status monitor" --DEFAULTS=/etc/default/$NAME --START=yes -- --# Source defaults file; edit that file to configure this script. --if [ -e "${DEFAULTS}" ]; then -- . "${DEFAULTS}" -+prog=lcdproc -+lockfile=/var/lock/subsys/$prog -+configfile=@sysconfdir@/$prog.conf -+RETVAL=0 -+ -+# load LSB 3.x init functions -+if [ -e /lib/lsb/init-functions ]; then -+ . /lib/lsb/init-functions - fi - --# If we're not to start the daemon, simply exit --if [ "${START}" != "yes" ]; then -- exit 0 -+# Source function library. -+if [ -e /etc/rc.d/init.d/functions ]; then -+ . /etc/rc.d/init.d/functions - fi - --# installation check --test -x $DAEMON || exit 5 -+# check that non-default config file exists. -+ [ -f $configfile ] || exit 6 - --# load LSB 3.x init functions --. /lib/lsb/init-functions -+ -+start() { -+ echo -n $"Starting $prog services: " -+ daemon $prog -c $configfile -+ RETVAL=$? -+ echo -+ [ $RETVAL -eq 0 ] && touch $lockfile || \ -+ RETVAL=1 -+ return $RETVAL -+} -+ -+stop() { -+ echo -n $"Shutting down $prog services: " -+ killproc $prog -+ RETVAL=$? -+ echo -+ [ $RETVAL -eq 0 ] && rm -f $lockfile -+ return $RETVAL -+} -+ -+reload() { -+ echo -n $"Reloading $prog file: " -+ killproc $prog -HUP -+ RETVAL=$? -+ echo -+ return $RETVAL -+} -+ -+rhstatus() { -+ status $prog -+ return $? -+} -+ -+ -+# Allow status as non-root. -+if [ "$1" = status ]; then -+ rhstatus -+ exit $? -+fi - - - case "$1" in - start) -- log_daemon_msg "Starting $DESC" "$NAME" -- start_daemon $DAEMON $OPTIONS -- log_end_msg $? -+ start - ;; - stop) -- log_daemon_msg "Stopping $DESC" "$NAME" -- killproc $DAEMON -- log_end_msg $? -- ;; -- restart|reload|force-reload) -- $0 stop -- sleep 1 -- $0 start -+ stop -+ ;; -+ status) -+ status $prog -+ ;; -+ restart|force-reload) -+ stop -+ start -+ ;; -+ try-restart|condrestart) -+ if [ -f $lockfile ]; then -+ stop -+ start -+ fi -+ ;; -+ reload) -+ reload - ;; - *) -- echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2 -+ echo $"Usage: $0 {start|stop|status|restart|try-restart|force-reload}" - exit 2 -- ;; - esac - --exit 0 -+exit $RETVAL diff --git a/lcdproc-0.5.2-memset_swp.patch b/lcdproc-0.5.2-memset_swp.patch deleted file mode 100644 index 3b36a7a..0000000 --- a/lcdproc-0.5.2-memset_swp.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- lcdproc-0.5.2/server/drivers/pylcd.c.memset_swp 2007-08-12 19:27:34.000000000 +0200 -+++ lcdproc-0.5.2/server/drivers/pylcd.c 2007-08-12 19:42:05.000000000 +0200 -@@ -118,7 +118,7 @@ - - if (zeichen!=0x02) - { -- memset(buffer, MAXCOUNT, 0); -+ memset(buffer, 0, MAXCOUNT); - return False; - } - -@@ -146,7 +146,7 @@ - } - else - { -- memset(buffer, MAXCOUNT, 0); -+ memset(buffer, 0, MAXCOUNT); - return False; - } - } diff --git a/lcdproc-0.5.3-initscripts.patch b/lcdproc-0.5.3-initscripts.patch new file mode 100644 index 0000000..7b74d1f --- /dev/null +++ b/lcdproc-0.5.3-initscripts.patch @@ -0,0 +1,305 @@ +Index: lcdproc-0.5.3/scripts/init-LCDd.rpm.in +=================================================================== +--- lcdproc-0.5.3.orig/scripts/init-LCDd.rpm.in ++++ lcdproc-0.5.3/scripts/init-LCDd.rpm.in +@@ -1,5 +1,5 @@ + #!/bin/sh +-# This is the LCDd init-script for RPM based (RedHat, Mandrake) systems ++# This is the LCDd init-script for RPM based (Red Hat, Mandrake) systems + # + # Copyright (C) 2001 Rene Wagner + # 2001 Guillaume Filion +@@ -19,25 +19,53 @@ + # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + # + # +-# chkconfig: 345 70 21 ++# chkconfig: - 70 21 + # description: LCDd(8) is the LCDproc server used for displaying text and other data to LCDs. \ + # Apart from the main client lcdproc(1) there are various clients. \ + # See http://lcdproc.omnipotent.net for details. + # processname: LCDd + # pidfile: /var/run/LCDd.pid + # config: @sysconfdir@/LCDd.conf ++# ++### BEGIN INIT INFO ++# Provides: LCDd ++# Required-Start: $syslog $local_fs $network $remote_fs ++# Required-Stop: $syslog $local_fs $network $remote_fs ++# Should-Start: udev ++# Default-Start: ++# Default-Stop: S 0 1 6 ++# Short-Description: LCDproc Server Daemon ++# Description: init script for LCDd, the display ++# server daemon in the LCDproc suite ++### END INIT INFO ++ ++prog=LCDd ++lockfile=/var/lock/subsys/$prog ++configfile=@sysconfdir@/$prog.conf ++ ++# load LSB 3.x init functions ++if [ -e /lib/lsb/init-functions ]; then ++ . /lib/lsb/init-functions ++fi + + # Source function library. +-. /etc/rc.d/init.d/functions ++if [ -e /etc/rc.d/init.d/functions ]; then ++ . /etc/rc.d/init.d/functions ++fi + + # Source networking configuration. +-. /etc/sysconfig/network ++if [ -e /etc/sysconfig/network ]; then ++ . /etc/sysconfig/network ++fi + + # Check that networking is up. + if [ ${NETWORKING} = "no" ]; then + exit 0 + fi + ++# check that non-default config file exists. ++[ -f $configfile ] || exit 6 ++ + RETVAL=0 + + prefix=@prefix@ +@@ -46,41 +74,49 @@ bindir=@bindir@ + sbindir=@sbindir@ + etc=@sysconfdir@ + +-LCDd=${sbindir}/LCDd +-configfile=${etc}/LCDd.conf +- +-[ -x ${LCDd} ] || exit 0 ++[ -x ${bindir}/${prog} ] || exit 0 + + start() { +- echo -n "Starting up LCDd: " +- daemon ${LCDd} -c ${configfile} +- ++ echo -n "Starting ${prog} service: " ++ daemon ${prog} -c ${configfile} + RETVAL=$? +- [ $RETVAL -eq 0 ] && touch /var/lock/subsys/LCDd + echo ++ [ $RETVAL -eq 0 ] && touch ${lockfile} || \ ++ RETVAL=1 ++ return $RETVAL + } + + stop() { +- echo -n "Shutting down LCDd: " +- killproc LCDd ++ echo -n "Shutting down ${prog} service: " ++ killproc ${prog} + RETVAL=$? +- [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/LCDd + echo ++ [ $RETVAL -eq 0 ] && rm -f ${lockfile} ++ return $RETVAL + } + +-dostatus() { +- status LCDd ++reload() { ++ echo -n $"Reloading ${prog} conig file: " ++ killproc ${prog} -HUP + RETVAL=$? ++ echo ++ return $RETVAL ++} ++ ++dostatus() { ++ status ${prog} ++ return $? + } + + restart() { + stop + start +- RETVAL=$? ++ return $? + } + + condrestart() { +- [ -e /var/lock/subsys/LCDd ] && restart || : ++ [ -f ${lockfile} ] && restart || : ++ return $? + } + + # See how we were called. +@@ -94,15 +130,18 @@ case "$1" in + status) + dostatus + ;; +- restart) ++ restart|force-reload) + restart + ;; +- condrestart) ++ try-restart|condrestart) + condrestart + ;; ++ reload) ++ reload ++ ;; + *) +- echo "Usage: $0 {start|stop|status|restart|condrestart}" +- exit 1 ++ echo "Usage: $0 {start|stop|status|restart|condrestart|reload}" ++ exit 2 + esac + + exit $RETVAL +Index: lcdproc-0.5.3/scripts/init-lcdproc.rpm.in +=================================================================== +--- lcdproc-0.5.3.orig/scripts/init-lcdproc.rpm.in ++++ lcdproc-0.5.3/scripts/init-lcdproc.rpm.in +@@ -19,68 +19,104 @@ + # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + # + # +-# chkconfig: 345 71 20 ++# chkconfig: - 71 20 + # description: LCDd(8) is the LCDproc server used for displaying text and other data to LCDs. \ + # Apart from the main client lcdproc(1) there are various clients. \ + # See http://lcdproc.omnipotent.net for details. + # processname: lcdproc + # pidfile: /var/run/lcdproc.pid +-# config: /etc/sysconfig/lcdproc ++# config: @sysconfdir@/lcdproc.conf ++# ++### BEGIN INIT INFO ++# Provides: lcdproc ++# Required-Start: $syslog $local_fs $network $remote_fs ++# Required-Stop: $syslog $local_fs $network $remote_fs ++# Should-Start: LCDd ++# Default-Start: ++# Default-Stop: S 0 1 6 ++# Short-Description: LCDproc system status information viewer ++# Description: LSB init script for lcdproc, the system ++# status information viewer in the LCDproc suite ++### END INIT INFO ++ ++prog=lcdproc ++lockfile=/var/lock/subsys/$prog ++configfile=@sysconfdir@/$prog.conf ++RETVAL=0 ++ ++# load LSB 3.x init functions ++if [ -e /lib/lsb/init-functions ]; then ++ . /lib/lsb/init-functions ++fi + + # Source function library. +-. /etc/rc.d/init.d/functions ++if [ -e /etc/rc.d/init.d/functions ]; then ++ . /etc/rc.d/init.d/functions ++fi + + # Source networking configuration. +-. /etc/sysconfig/network ++if [ -e /etc/sysconfig/network ]; then ++ . /etc/sysconfig/network ++fi + + # Check that networking is up. + if [ ${NETWORKING} = "no" ]; then + exit 0 + fi + +-RETVAL=0 +- + prefix=@prefix@ + exec_prefix=@exec_prefix@ + bindir=@bindir@ + sbindir=@sbindir@ + etc=@sysconfdir@ + +-lcdproc=${bindir}/lcdproc ++[ -x ${bindir}/${prog} ] || exit 0 + +-[ -x ${lcdproc} ] || exit 0 ++# check that non-default config file exists. ++ [ -f $configfile ] || exit 6 + + + start() { +- echo -n "Starting up lcdproc: " +- daemon ${lcdproc} $SCREENS +- ++ echo -n "Starting ${prog} service: " ++ daemon ${prog} -c ${configfile} + RETVAL=$? +- [ $RETVAL -eq 0 ] && touch /var/lock/subsys/lcdproc + echo ++ [ $RETVAL -eq 0 ] && touch ${lockfile} || \ ++ RETVAL=1 ++ return $RETVAL + } + + stop() { +- echo -n "Shutting down lcdproc: " +- killproc lcdproc ++ echo -n "Shutting down ${prog} service: " ++ killproc ${prog} + RETVAL=$? +- [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/lcdproc + echo ++ [ $RETVAL -eq 0 ] && rm -f ${lockfile} ++ return $RETVAL + } + +-dostatus() { +- status lcdproc ++reload() { ++ echo -n $"Reloading ${prog} config file: " ++ killproc ${prog} -HUP + RETVAL=$? ++ echo ++ return $RETVAL ++} ++ ++dostatus() { ++ status ${prog} ++ return $? + } + + restart() { + stop + start +- RETVAL=$? ++ return $? + } + + condrestart() { +- [ -e /var/lock/subsys/lcdproc ] && restart || : ++ [ -f ${lockfile} ] && restart || : ++ return $? + } + + # See how we were called. +@@ -94,14 +130,17 @@ case "$1" in + status) + dostatus + ;; +- restart) ++ restart|force-reload) + restart + ;; +- condrestart) ++ try-restart|condrestart) + condrestart + ;; ++ reload) ++ reload ++ ;; + *) +- echo "Usage: $0 {start|stop|status|restart|condrestart}" ++ echo "Usage: $0 {start|stop|status|restart|condrestart|reload}" + exit 1 + esac + diff --git a/lcdproc.spec b/lcdproc.spec index a55c70f..950256a 100644 --- a/lcdproc.spec +++ b/lcdproc.spec @@ -1,23 +1,18 @@ Summary: LCDproc displays real-time system information on a 20x4 backlit LCD Name: lcdproc -Version: 0.5.2 -Release: 12%{?dist} +Version: 0.5.3 +Release: 1%{?dist} License: GPLv2 URL: http://lcdproc.omnipotent.net Group: System Environment/Libraries Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz -Patch0: lcdproc-0.5.2-initscripts.patch -Patch1: lcdproc-0.5.2-memset_swp.patch -Patch2: lcdproc-0.5.2-imonlcd.patch -Patch3: lcdproc-0.5.2-novalidate.patch +Patch0: lcdproc-0.5.3-initscripts.patch +Patch1: lcdproc-0.5.2-novalidate.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: doxygen BuildRequires: graphviz -# necessary for imonlcd patch -BuildRequires: libtool - BuildRequires: libusb-devel BuildRequires: lirc-devel BuildRequires: ncurses-devel @@ -55,19 +50,13 @@ See also http://lcdproc.omnipotent.net. %prep %setup -q %patch0 -p1 -b .initscripts -%patch1 -p1 -b .memset_swp -%patch2 -p1 -b .imonlcd -%patch3 -p1 -b .novalidate +%patch1 -p1 -b .novalidate chmod 644 server/drivers/timing.h sed -i -e 's|server/drivers|%{_libdir}/lcdproc|' LCDd.conf touch -r TODO LCDd.conf %build -# run autoreconf to pick up the imon lcd additions -# liboolize to refresh libtool -autoreconf -f -i -libtoolize --force %configure \ --sysconfdir=%{_sysconfdir}/sysconfig/%{name} \ --enable-libusb \ @@ -96,8 +85,8 @@ rm -rf $RPM_BUILD_ROOT%{_datadir}/doc # init install -d $RPM_BUILD_ROOT%{_initrddir} -install -pm 0755 scripts/init-LCDd.LSB $RPM_BUILD_ROOT%{_initrddir}/LCDd -install -pm 0755 scripts/init-lcdproc.LSB $RPM_BUILD_ROOT%{_initrddir}/lcdproc +install -pm 0755 scripts/init-LCDd.rpm $RPM_BUILD_ROOT%{_initrddir}/LCDd +install -pm 0755 scripts/init-lcdproc.rpm $RPM_BUILD_ROOT%{_initrddir}/lcdproc #Disable default configuration #Thoses are only provided as an example since ncurses isn't a suitable default configuration. @@ -134,7 +123,7 @@ rm -rf $RPM_BUILD_ROOT __doc %files %defattr(-,root,root,-) %doc README* INSTALL COPYING CREDITS TODO ChangeLog -%doc docs/*.txt docs/README.* __doc/* +%doc __doc/* %{_bindir}/* %dir %{_libdir}/lcdproc %{_libdir}/lcdproc/* @@ -148,6 +137,12 @@ rm -rf $RPM_BUILD_ROOT __doc %changelog +* Mon Jun 22 2009 Jarod Wilson - 0.5.3-1 +- Update to lcdproc v0.5.3 release +- Drop upstreamed imonlcd and memset_swp patches +- Switch to upstream's rpm initscripts (albeit still patched, need + to get that bit upstream for the next release) + * Wed May 13 2009 kwizart < kwizart at gmail.com > - 0.5.2-12 - Improve the initscripts patch - Fix #498384 diff --git a/sources b/sources index cbf2751..540f1dd 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -860f192d061d87dda6512b11b79daac2 lcdproc-0.5.2.tar.gz +fe9a7c9d8f2c5e76250ce2ea8f644921 lcdproc-0.5.3.tar.gz