[Lcdproc] Patch to use iMon special characters

John Saunders JohnS@resmed.com.au
Wed Oct 11 23:46:01 2006


I have created this patch for the iMon driver that
uses the pre-defined special characters to enhance
the look of lcdproc. It includes the following
changes...

1) Uses special chars 0x00 to 0x07 to draw vertical bars
2) Imports the curses function for horizontal bars to fix
   a known bug, and uses special chars to make the bars
   look much nicer that ###-.
3) Implements the icon function and uses special chars to
   draw many of the icons so they look better.
4) Removes trailing spaces from a number of lines.

It was tested with the iMon inside VFD included in the
Antec Fusion case (USB ID 15C2:FFDC), and lirc 0.8.0
/dev/lcd0 driver. I tested all of the lcdproc pages and
MythTV.

diff -urN lcdproc-0.5.0/server/drivers/imon.c
lcdproc-0.5.0-new/server/drivers/imon.c
--- lcdproc-0.5.0/server/drivers/imon.c	2006-04-12 17:53:53.000000000 +1000
+++ lcdproc-0.5.0-new/server/drivers/imon.c	2006-10-11
22:28:15.000000000 +1000
@@ -44,7 +44,41 @@
 
 #include "imon.h"
 
-#define PAD		'#'
+// iMon reserves the first 8 locations for the
+// special bargraph characters
+#define IMON_CHAR_1_BAR		0x00
+#define IMON_CHAR_2_BARS	0x01
+#define IMON_CHAR_3_BARS	0x02
+#define IMON_CHAR_4_BARS	0x03
+#define IMON_CHAR_5_BARS	0x04
+#define IMON_CHAR_6_BARS	0x05
+#define IMON_CHAR_7_BARS	0x06
+#define IMON_CHAR_8_BARS	0x07
+
+// Standard music control characters
+#define IMON_CHAR_PLAY		0x10	// >  Play
+#define IMON_CHAR_RPLAY		0x11	// <  Reverse Play
+#define IMON_CHAR_PAUSE		0xA0	// || Pause
+#define IMON_CHAR_RECORD	0x16	// O  Record
+
+#define IMON_CHAR_TRI_UP	0x1E	// ^
+#define IMON_CHAR_TRI_DOWN	0x1F	// V
+#define IMON_CHAR_DLB_TRI_UP	0x14
+#define IMON_CHAR_DBL_TRI_DOWN	0x15
+
+#define IMON_CHAR_ARROW_UP	0x18
+#define IMON_CHAR_ARROW_DOWN	0x19
+#define IMON_CHAR_ARROW_RIGHT	0x1A
+#define IMON_CHAR_ARROW_LEFT	0x1B
+#define IMON_CHAR_ENTER		0x17
+
+#define IMON_CHAR_HOUSE		0x7F
+
+#define IMON_CHAR_HEART		0x9D
+
+#define IMON_CHAR_BLOCK_FILLED	IMON_CHAR_8_BARS
+#define IMON_CHAR_BLOCK_EMPTY	' '
+
 #define DEFAULT_DEVICE	"/dev/usb/lcd"
 #define DEFAULT_SIZE	"16x2"
 /* The two value below are only used internally, we don't support custom
char. */
@@ -70,7 +104,7 @@
 } PrivateData;
 
 
-/** 
+/**
  * driver initialization
  */
 MODULE_EXPORT int imon_init (Driver *drvthis)
@@ -118,7 +152,7 @@
 	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", 
+		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);
 	}
@@ -133,10 +167,10 @@
 
 	report(RPT_DEBUG, "%s: init() done", drvthis->name);
 	
-	return 1;		 
+	return 1;
 }
 
-/** 
+/**
  * provides some info about this driver
  */
 MODULE_EXPORT const char * imon_get_info (Driver *drvthis)
@@ -146,7 +180,7 @@
 	return p->info;
 }
 
-/** 
+/**
  * closes driver
  */
 MODULE_EXPORT void imon_close (Driver *drvthis)
@@ -166,8 +200,8 @@
 	drvthis->store_private_ptr(drvthis, NULL);
 }
 
-/** 
- * Clears the VFD screen 
+/**
+ * Clears the VFD screen
  */
 MODULE_EXPORT void imon_clear (Driver *drvthis)
 {
@@ -177,7 +211,7 @@
 }
 
 /**
- * Flushes all output to the VFD...  
+ * Flushes all output to the VFD...
  */
 MODULE_EXPORT void imon_flush (Driver *drvthis)
 {
@@ -188,7 +222,7 @@
 
 /**
  * Prints a string on the VFD display, at position (x,y).
- * The upper-left is (1,1) and the lower right is (16, 2).  
+ * The upper-left is (1,1) and the lower right is (16, 2).
  */
 MODULE_EXPORT void imon_string (Driver *drvthis, int x, int y, char
string[])
 {
@@ -210,45 +244,89 @@
 	if ((x < 0) || (y < 0) || (x >= p->width) || (y >= p->height))
 		return;
 
-	switch (ch) {
-		case '\0':
-		case -1:	/* ugly: this is 255 unsigned */
-			ch = PAD;
-			break;
-		default:
-			;
-	}
 	p->framebuf[(y * p->width) + x] = ch;
 }
 
 /**
- * Draws a vertical bar (adapted from the curses driver, because
- * this device does not support custom characters, as Venky
- * states in the original LCDproc-0.4.5 implementation)
+ * Prints a standard icon on the VFD display, at position (x,y).
+ * The upper-left is (1,1) and the lower right is (16,2).
+ */
+MODULE_EXPORT int imon_icon (Driver *drvthis, int x, int y, int icon)
+{
+  switch (icon)
+  {
+    case ICON_BLOCK_FILLED:
+      imon_chr(drvthis, x, y, IMON_CHAR_BLOCK_FILLED);
+      break;
+    case ICON_HEART_OPEN:
+      imon_chr(drvthis, x, y, IMON_CHAR_BLOCK_EMPTY);
+      break;
+    case ICON_HEART_FILLED:
+      imon_chr(drvthis, x, y, IMON_CHAR_HEART);
+      break;
+    case ICON_ARROW_UP:
+      imon_chr(drvthis, x, y, IMON_CHAR_ARROW_UP);
+      break;
+    case ICON_ARROW_DOWN:
+      imon_chr(drvthis, x, y, IMON_CHAR_ARROW_DOWN);
+      break;
+    case ICON_ARROW_LEFT:
+      imon_chr(drvthis, x, y, IMON_CHAR_ARROW_LEFT);
+      break;
+    case ICON_ARROW_RIGHT:
+      imon_chr(drvthis, x, y, IMON_CHAR_ARROW_RIGHT);
+      break;
+    case ICON_STOP:
+      imon_chr(drvthis, x, y, IMON_CHAR_BLOCK_FILLED);
+      imon_chr(drvthis, x+1, y, ' ');
+      break;
+    case ICON_PAUSE:
+      imon_chr(drvthis, x, y, IMON_CHAR_PAUSE);
+      imon_chr(drvthis, x+1, y, ' ');
+      break;
+    case ICON_PLAY:
+      imon_chr(drvthis, x, y, IMON_CHAR_PLAY);
+      imon_chr(drvthis, x+1, y, ' ');
+      break;
+    case ICON_PLAYR:
+      imon_chr(drvthis, x, y, IMON_CHAR_RPLAY);
+      imon_chr(drvthis, x+1, y, ' ');
+      break;
+    case ICON_FF:
+      imon_chr(drvthis, x, y, IMON_CHAR_PLAY);
+      imon_chr(drvthis, x+1, y, IMON_CHAR_PLAY);
+      break;
+    case ICON_FR:
+      imon_chr(drvthis, x, y, IMON_CHAR_RPLAY);
+      imon_chr(drvthis, x+1, y, IMON_CHAR_RPLAY);
+      break;
+    case ICON_NEXT:
+      imon_chr(drvthis, x, y, IMON_CHAR_PLAY);
+      imon_chr(drvthis, x+1, y, '|');
+      break;
+    case ICON_PREV:
+      imon_chr(drvthis, x, y, '|');
+      imon_chr(drvthis, x+1, y, IMON_CHAR_RPLAY);
+      break;
+    case ICON_REC:
+      imon_chr(drvthis, x, y, IMON_CHAR_RECORD);
+      imon_chr(drvthis, x+1, y, ' ');
+      break;
+    default:
+      return -1;
+  }
+  return 0;
+}
+
+/**
+ * Draws a vertical bar using the special characters 0x00 to 0x07
  */
 MODULE_EXPORT void imon_vbar (Driver *drvthis, int x, int y, int len, int
promille, int options)
 {
 	PrivateData *p = drvthis->private_data;
-	int pixels = ((long) 2 * len * p->cellheight) * promille / 2000;
-	int pos;
 
-	for (pos = 0; pos < len; pos++) {
-		if (pixels >= p->cellheight) {
-			/* write a "full" block to the screen... */
-			//drvthis->icon (drvthis, x, y-pos,
ICON_BLOCK_FILLED);
-			imon_chr(drvthis, x, y-pos, '#');
-		}
-		else if (pixels > 0) {
-			/* write a "partial" block to the screen... */
-			imon_chr(drvthis, x, y-pos, '|');
-			break;
-		}
-		else {
-			; // write nothing (not even a space) 
-		}
-
-		pixels -= p->cellheight * pos;
-	}
+	// Special characters start at 0 not 1, so pass -1 as first char.
+	lib_vbar_static(drvthis, x, y, len, promille, options,
p->cellheight, -1);
 }
 
 /**
@@ -262,26 +340,44 @@
 	int pixels = ((long) 2 * len * p->cellwidth) * promille / 2000;
 	int pos;
 
+	if ((x <= 0) || (y <= 0) || (y > p->height))
+		return;
+
+	/* x and y are the start position of the bar.
+	 * The bar by default grows in the 'right' direction
+	 * (other direction not yet implemented).
+	 * len is the number of characters that the bar is long at 100%
+	 * promille is the number of promilles (0..1000) that the bar should
be filled.
+	 */
+
 	for (pos = 0; pos < len; pos++) {
-		if (pixels >= p->cellwidth) {
+
+		if (x + pos > p->width)
+			return;
+
+		if (pixels >= p->cellwidth * 3/4) {
 			/* write a "full" block to the screen... */
-			//drvthis->icon (drvthis, x+pos, y,
ICON_BLOCK_FILLED);
-			imon_chr (drvthis, x+pos, y, '#');
+			imon_chr(drvthis, x+pos, y, IMON_CHAR_BLOCK_FILLED);
+		}
+		else if (pixels >= p->cellwidth * 2/4) {
+			/* write a partial block... */
+			imon_chr(drvthis, x+pos, y, IMON_CHAR_PLAY);
+			break;
 		}
-		else if (pixels > 0) {
-			/* write a "partial" block to the screen... */
-			imon_chr (drvthis, x+pos, y, '-');
+		else if (pixels >= p->cellwidth * 1/4) {
+			/* write a partial block... */
+			imon_chr(drvthis, x+pos, y, '>');
 			break;
 		}
 		else {
-			; // write nothing (not even a space) 
+			; // write nothing (not even a space)
 		}
 
-		pixels -= p->cellwidth * pos;
+		pixels -= p->cellwidth;
 	}
 }
 
-/** 
+/**
  * returns the display's width
  */
 MODULE_EXPORT int imon_width (Driver *drvthis)
@@ -291,7 +387,7 @@
 	return p->width;
 }
 
-/** 
+/**
  * returns the display's height
  */
 MODULE_EXPORT int  imon_height (Driver *drvthis)
@@ -301,7 +397,7 @@
 	return p->height;
 }
 
-/** 
+/**
  * returns the display's cell width
  */
 MODULE_EXPORT int imon_cellwidth (Driver *drvthis)
@@ -311,7 +407,7 @@
 	return p->cellwidth;
 }
 
-/** 
+/**
  * returns the display's cell height
  */
 MODULE_EXPORT int  imon_cellheight (Driver *drvthis)
diff -urN lcdproc-0.5.0/server/drivers/imon.h
lcdproc-0.5.0-new/server/drivers/imon.h
--- lcdproc-0.5.0/server/drivers/imon.h	2006-04-12 17:54:06.000000000 +1000
+++ lcdproc-0.5.0-new/server/drivers/imon.h	2006-10-10
23:51:09.000000000 +1000
@@ -37,6 +37,7 @@
 MODULE_EXPORT void imon_flush (Driver *drvthis);
 MODULE_EXPORT void imon_string (Driver *drvthis, int x, int y, char
string[]);
 MODULE_EXPORT void imon_chr (Driver *drvthis, int x, int y, char c);
+MODULE_EXPORT int  imon_icon (Driver *drvthis, int x, int y, int icon);
 MODULE_EXPORT const char *imon_get_info (Driver *drvthis);
 MODULE_EXPORT void imon_vbar (Driver *drvthis, int x, int y, int len, int
promille, int options);
 MODULE_EXPORT void imon_hbar (Driver *drvthis, int x, int y, int len, int
promille, int options);
@@ -44,9 +45,6 @@
 /**
  * theese are not (yet?) supported by the iMON IR/VFD kernel module
  */
-//MODULE_EXPORT int  imon_icon (Driver *drvthis, int x, int y, int icon);
-//MODULE_EXPORT int  imon_cellwidth (Driver *drvthis);
-//MODULE_EXPORT int  imon_cellheight (Driver *drvthis);
 //MODULE_EXPORT int  imon_get_free_chars (Driver *drvthis);
 //MODULE_EXPORT void imon_set_char (Driver *drvthis, int n, char *dat);
 //MODULE_EXPORT void imon_num (Driver *drvthis, int x, int num);




Warning:  Copyright ResMed.  Where the contents of this email and/or attachment includes materials prepared by ResMed, the use of those
materials is subject exclusively to the conditions of engagement between ResMed and the intended recipient.
 
This communication is confidential and may contain legally privileged information.
By the use of email over the Internet or other communication systems, ResMed is not waiving either confidentiality of, or legal
privilege in,the content of the email and of any attachments.
If the recipient of this message is not the intended addressee, please call ResMed immediately on  +61 2 8884 1000 Sydney, Australia.