Ultra-minimial module for using LCD proc with custom hardware

Fake Name <[email protected]> Tue, 21 Jan 2014 20:23:33 -0800
Newsgroups gmane.comp.sysutils.lcdproc
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------000104030108060909090303
Content-Type: multipart/alternative;
 boundary="------------050402090305050304020408"


--------------050402090305050304020408
Content-Type: text/plain; charset=windows-1252; format=flowed
Content-Transfer-Encoding: 7bit

Note: I'm not sure if this is making it to the list successfully. I've 
sent it a few times, but there have been some mail-client conf issues on 
my end.



Hi There~

Attached is the patch file for a new LCDproc driver I've been futzing 
with for a while. It's a driver that's basically intended for getting 
simple status info out of LCDproc into a connected MCU on the serial 
interface.

Basically, I have a number of linux servers and a PFsense router I like 
to monitor, and I have some custom hardware (It's not an arduino 
<http://arduino.cc/>, but it's similar 
<www.youtube.com/watch?v=RsW7MzdMGhg> (youtube video of the project)) 
hooked up to the various boxes.
In this case, since I'm not running a actual LCD, having to deal with 
all the control-codes LCDproc normally sends is actually a fair bit of 
trouble, particularly on a small 8 bit MCU. As such, I've written a 
custom driver that simply dumps the entire framebuffer at 1 Hz, which 
makes it maximally easy to write machine-readable screen layouts.

In this case, this is a fairly generic tool, but it's useful for all 
sorts of DIY applications.

I'm not sure what LCDproc's standing on this sort of driver is, but I 
hope there is interest.

The driver is based on the simpleserial driver (that doesn't seem to be 
in the distribution any more?). Anyways, it's named reallysimpleserial 
so as to avoid a namespace collision, but that may be a moot-point at 
this point since the simpleserial driver is no longer present.

I've tried to go down the "Add your driver 
<http://lcdproc.sourceforge.net/docs/current-dev.html#add-your-driver>" 
checklist, and created all the relevant documentation, let me know if 
there are things that need clarification, or are missing.

Connor

--------------050402090305050304020408
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: 7bit

<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    Note: I'm not sure if this is making it to the list successfully.
    I've sent it a few times, but there have been some mail-client conf
    issues on my end.<br>
    <br>
    <br>
    <br>
    Hi There~<br>
    <br>
    Attached is the patch file for a new LCDproc driver I've been
    futzing with for a while. It's a driver that's basically intended
    for getting simple status info out of LCDproc into a connected MCU
    on the serial interface.<br>
    <br>
    Basically, I have a number of linux servers and a PFsense router I
    like to monitor, and I have some custom hardware (It's not an <a
      href="http://arduino.cc/">arduino</a>, but <a
      href="www.youtube.com/watch?v=RsW7MzdMGhg">it's similar</a>
    (youtube video of the project)) hooked up to the various boxes.<br>
    In this case, since I'm not running a actual LCD, having to deal
    with all the control-codes LCDproc normally sends is actually a fair
    bit of trouble, particularly on a small 8 bit MCU. As such, I've
    written a custom driver that simply dumps the entire framebuffer at
    1 Hz, which makes it maximally easy to write machine-readable screen
    layouts.<br>
    <br>
    In this case, this is a fairly generic tool, but it's useful for all
    sorts of DIY applications. <br>
    <br>
    I'm not sure what LCDproc's standing on this sort of driver is, but
    I hope there is interest. <br>
    <br>
    The driver is based on the simpleserial driver (that doesn't seem to
    be in the distribution any more?). Anyways, it's named
    reallysimpleserial so as to avoid a namespace collision, but that
    may be a moot-point at this point since the simpleserial driver is
    no longer present.<br>
    <br>
    I've tried to go down the "<a
href="http://lcdproc.sourceforge.net/docs/current-dev.html#add-your-driver">Add

      your driver</a>" checklist, and created all the relevant
    documentation, let me know if there are things that need
    clarification, or are missing.<br>
    <br>
    Connor<br>
  </body>
</html>

--------------050402090305050304020408--

--------------000104030108060909090303
Content-Type: text/plain; charset=windows-1252;
 name="mymodifications.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="mymodifications.patch"

diff -urN -X lcdprocStock/diff_ignore lcdprocStock/acinclude.m4 lcdproc/acinclude.m4
--- lcdprocStock/acinclude.m4	2014-01-13 13:05:01.182310562 -0800
+++ lcdproc/acinclude.m4	2014-01-13 13:10:11.830999497 -0800
@@ -15,14 +15,14 @@
 	[                    ms6931,mtc_s16209x,MtxOrb,mx5000,NoritakeVFD,]
 	[                    picolcd,pyramid,sdeclcd,sed1330,sed1520,serialPOS,]
 	[                    serialVFD,shuttleVFD,sli,stv5730,SureElec,svga,]
-	[                    t6963,text,tyan,ula200,vlsys_m428,xosd]
+	[                    t6963,text,tyan,ula200,vlsys_m428,xosd,reallysimpleserial]
 	[                    ]
 	[                  'all' compiles all drivers;]
 	[                  'all,!xxx,!yyy' de-selects previously selected drivers],
 	drivers="$enableval",
 	drivers=[bayrad,CFontz,CFontzPacket,curses,CwLnx,glk,lb216,lcdm001,MtxOrb,pyramid,text])
 
-allDrivers=[bayrad,CFontz,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,g15,glcd,glcdlib,glk,hd44780,i2500vfd,icp_a106,imon,imonlcd,IOWarrior,irman,irtrans,joy,lb216,lcdm001,lcterm,lirc,lis,MD8800,mdm166a,ms6931,mtc_s16209x,MtxOrb,mx5000,NoritakeVFD,picolcd,pyramid,sdeclcd,sed1330,sed1520,serialPOS,serialVFD,shuttleVFD,sli,stv5730,SureElec,svga,t6963,text,tyan,ula200,vlsys_m428,xosd]
+allDrivers=[bayrad,CFontz,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,g15,glcd,glcdlib,glk,hd44780,i2500vfd,icp_a106,imon,imonlcd,IOWarrior,irman,irtrans,joy,lb216,lcdm001,lcterm,lirc,lis,MD8800,mdm166a,ms6931,mtc_s16209x,MtxOrb,mx5000,NoritakeVFD,picolcd,pyramid,sdeclcd,sed1330,sed1520,serialPOS,serialVFD,shuttleVFD,sli,stv5730,SureElec,svga,t6963,text,tyan,ula200,vlsys_m428,xosd,reallysimpleserial]
 if test "$debug" = yes; then
 	allDrivers=["${allDrivers},debug"]
 fi
@@ -529,6 +529,10 @@
 				actdrivers=["$actdrivers xosd"]
 			fi
 			;;
+		reallysimpleserial)
+			DRIVERS="$DRIVERS reallysimpleserial${SO}"
+			actdrivers=["$actdrivers reallysimpleserial"]
+			;;
 		*)
 			AC_MSG_ERROR([Unknown driver $driver])
 			;;
diff -urN -X lcdprocStock/diff_ignore lcdprocStock/docs/LCDd.8.in lcdproc/docs/LCDd.8.in
--- lcdprocStock/docs/LCDd.8.in	2014-01-13 13:05:01.182310562 -0800
+++ lcdproc/docs/LCDd.8.in	2014-01-13 13:18:52.951750842 -0800
@@ -312,6 +312,10 @@
 .TP
 .B xosd
 On Screen Display on X11
+.TP
+.B reallysimpleserial
+Dumps the entire framebuffer out the serial port at 1 hz. Usefull for talking to custom hardware, where 
+the LCD control characters are more trouble then beneficial (think custom gauges that display system status, et cetera).
 .PP
 Multiple drivers can be used simultaneously; thus, for example, a Matrix Orbital display (MtxOrb driver)
 can be combined with an infrared driver (irmanin driver).
diff -urN -X lcdprocStock/diff_ignore lcdprocStock/docs/lcdproc-user/drivers/reallysimpleserial.docbook lcdproc/docs/lcdproc-user/drivers/reallysimpleserial.docbook
--- lcdprocStock/docs/lcdproc-user/drivers/reallysimpleserial.docbook	1969-12-31 16:00:00.000000000 -0800
+++ lcdproc/docs/lcdproc-user/drivers/reallysimpleserial.docbook	2014-01-13 13:31:42.880830150 -0800
@@ -0,0 +1,81 @@
+<sect1 id="howto">
+<sect1info>
+  <author>
+    <firstname>Connor</firstname>
+    <surname>Wolf</surname>
+  </author>
+</sect1info>
+<!-- Only as a comment, as inline presentation is awful in Docbook 4.5
+Imaginary Industries 
+imaginaryindustries.com
+Email: [email protected]
+-->
+<title>The *Really* Simple Serial</title>
+
+<para>
+This section talks about using LCDproc with custom hardware.
+</para>
+
+<para>
+This driver is intended for using LCDproc with custom hardware. In the original implementation, this was
+for a PFsense router with a homemade arduino-style circuit that controlled analog panel meters to 
+display network traffic. It is intended for this sort of application, where the LCD control characters
+emitted normally, as well as the partial screen drawing, make parsing the serial stream a considerably
+complex affair, particularly on small (generally 8 bit) microprocessors.
+</para>
+
+
+<sect2 id="features">
+<title>Features</title>
+
+<para>
+The driver emulates a 40x4 display, and simply dumps the entire framebuffer out the serial port once 
+per second (1 Hz), postpended with a single "\n" character. As such, it generates 161 serial characters 
+per second.
+</para>
+
+<para>
+The baud rate is 9600 baud (I think), even with 161 characters, that's a theoretical minimum baud 
+of 161*10 = 1610 baud, so there is plenty of headroom.
+</para>
+
+</sect2>
+
+
+
+
+<sect2 id="requirements">
+<title>Requirements</title>
+
+<para>
+None. The only requirement is a serial port of some sort.
+</para>
+
+
+
+</sect2>
+
+
+<sect2 id="config">
+<title>Configuration in LCDd.conf</title>
+
+<sect3 id="config-section">
+<title>[reallysimpleserial]</title>
+
+<variablelist>
+<varlistentry>
+  <term>
+    <property>Device</property> =
+    <parameter><replaceable>DEVICE</replaceable></parameter>
+  </term>
+  <listitem><para>
+  Serial port to use. Default: <filename>/dev/cuau0</filename>
+  </para></listitem>
+</varlistentry>
+</variablelist>
+
+</sect3>
+
+</sect2>
+
+</sect1>
diff -urN -X lcdprocStock/diff_ignore lcdprocStock/docs/lcdproc-user/drivers.docbook lcdproc/docs/lcdproc-user/drivers.docbook
--- lcdprocStock/docs/lcdproc-user/drivers.docbook	2014-01-13 13:05:01.182310562 -0800
+++ lcdproc/docs/lcdproc-user/drivers.docbook	2014-01-13 13:32:21.533087343 -0800
@@ -57,6 +57,7 @@
 &ula200;
 &vlsys_m428;
 &xosd;
+&reallysimpleserial;
 
 &ppttrouble;
 
diff -urN -X lcdprocStock/diff_ignore lcdprocStock/docs/lcdproc-user/lcdproc-user.docbook lcdproc/docs/lcdproc-user/lcdproc-user.docbook
--- lcdprocStock/docs/lcdproc-user/lcdproc-user.docbook	2014-01-13 13:05:01.182310562 -0800
+++ lcdproc/docs/lcdproc-user/lcdproc-user.docbook	2014-01-13 13:31:59.236517017 -0800
@@ -64,6 +64,7 @@
   <!ENTITY vlsys_m428 SYSTEM "drivers/vlsys_m428.docbook">
   <!ENTITY ula200 SYSTEM "drivers/ula200.docbook">
   <!ENTITY xosd SYSTEM "drivers/xosd.docbook">
+  <!ENTITY reallysimpleserial SYSTEM "drivers/reallysimpleserial.docbook">
 
   <!-- Note: The parameters include file provides commonly used entities for
   config file descriptions. DO NOT DELETE! -->
diff -urN -X lcdprocStock/diff_ignore lcdprocStock/server/drivers/Makefile.am lcdproc/server/drivers/Makefile.am
--- lcdprocStock/server/drivers/Makefile.am	2014-01-13 13:05:01.190306680 -0800
+++ lcdproc/server/drivers/Makefile.am	2014-01-13 13:12:10.885926579 -0800
@@ -23,7 +23,7 @@
 
 lcdexecbindir = $(pkglibdir)
 lcdexecbin_PROGRAMS = @DRIVERS@
-EXTRA_PROGRAMS = bayrad CFontz CFontzPacket curses debug CwLnx ea65 EyeboxOne g15 glcd glcdlib glk hd44780 icp_a106 imon imonlcd IOWarrior irman joy lb216 lcdm001 lcterm lirc lis MD8800 mdm166a ms6931 mtc_s16209x MtxOrb mx5000 NoritakeVFD picolcd pyramid sdeclcd sed1330 sed1520 serialPOS serialVFD shuttleVFD stv5730 SureElec svga t6963 text tyan sli ula200 vlsys_m428 xosd i2500vfd irtrans
+EXTRA_PROGRAMS = bayrad CFontz CFontzPacket curses debug CwLnx ea65 EyeboxOne g15 glcd glcdlib glk hd44780 icp_a106 imon imonlcd IOWarrior irman joy lb216 lcdm001 lcterm lirc lis MD8800 mdm166a ms6931 mtc_s16209x MtxOrb mx5000 NoritakeVFD picolcd pyramid sdeclcd sed1330 sed1520 serialPOS serialVFD shuttleVFD stv5730 SureElec svga t6963 text tyan sli ula200 vlsys_m428 xosd i2500vfd irtrans reallysimpleserial
 noinst_LIBRARIES = libLCD.a libbignum.a
 
 g15_CFLAGS =         @LIBUSB_CFLAGS@ $(AM_CFLAGS)
@@ -134,6 +134,7 @@
 ula200_SOURCES =     lcd.h adv_bignum.h ula200.h ula200.c report.h
 vlsys_m428_SOURCES = lcd.h report.h vlsys_m428.c vlsys_m428.h
 xosd_SOURCES =       lcd.h xosdlib_drv.c xosdlib_drv.h report.h adv_bignum.h
+reallysimpleserial_SOURCES =    lcd.h reallysimpleserial.c reallysimpleserial.h
 
 AM_CPPFLAGS = -I$(top_srcdir)
 
diff -urN -X lcdprocStock/diff_ignore lcdprocStock/server/drivers/reallysimpleserial.c lcdproc/server/drivers/reallysimpleserial.c
--- lcdprocStock/server/drivers/reallysimpleserial.c	1969-12-31 16:00:00.000000000 -0800
+++ lcdproc/server/drivers/reallysimpleserial.c	2014-01-13 14:55:16.770706947 -0800
@@ -0,0 +1,364 @@
+/** \file server/drivers/reallysimpleserial.c
+ * LCDd \c reallysimpleserial driver .
+ * This is primarily of use when you want to use LCDproc as a data-source
+ * for an external MCU or other similar hardware, in a situation where
+ * the LCD control characters normally emitted are actually obnoxious, rather then 
+ * beneficial. 
+ * As such, it simply dumps the ENTIRE (no deltas or such) framebuffer at
+ * 1 Hz
+ */
+
+/* Copyright (C) 1998-2004 The LCDproc Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <termios.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <errno.h>
+
+
+#include "lcd.h"
+#include "reallysimpleserial.h"
+#include "report.h"
+
+
+/** private data for the \c reallysimpleserial driver */
+typedef struct reallysimpleserial_private_data {
+	int width;		/**< display width in characters */
+	int height;		/**< display height in characters */
+	char *framebuf;		/**< fram buffer */
+	int fd;		/**< handle to the device */
+	int refresh_timer;
+	
+} PrivateData;
+
+
+/* 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 = "reallysimpleserial_";
+
+
+/**
+ * Initialize the driver.
+ * \param drvthis  Pointer to driver structure.
+ * \retval 0       Success.
+ * \retval <0      Error.
+ */
+MODULE_EXPORT int
+reallysimpleserial_init (Driver *drvthis)
+{
+	PrivateData *p;
+	char buf[256];
+	char device[200];
+	
+	struct termios portset;
+	
+	/* Allocate and store private data */
+	p = (PrivateData *) calloc(1, sizeof(PrivateData));
+	if (p == NULL)
+		return -1;
+	if (drvthis->store_private_ptr(drvthis, p))
+		return -1;
+	
+
+	/* initialize private data */
+	p->refresh_timer = 480;
+
+	  // READ CONFIG FILE:
+	// which serial device should be used
+	strncpy(device, drvthis->config_get_string(drvthis->name , "Device" , 0 , DEFAULT_DEVICE),
+		sizeof(device));
+	device[sizeof(device)-1] = '\0';
+	report(RPT_INFO, "%s: using Device %s", drvthis->name, device);
+
+	
+	// Set display sizes
+	if ((drvthis->request_display_width() > 0)
+	    && (drvthis->request_display_height() > 0)) {
+		// Use size from primary driver
+		p->width = drvthis->request_display_width();
+		p->height = drvthis->request_display_height();
+	}
+	else {
+		/* Use our own size from config file */
+		strncpy(buf, drvthis->config_get_string(drvthis->name, "Size", 0, DISPLAY_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, DISPLAY_DEFAULT_SIZE);
+			sscanf(DISPLAY_DEFAULT_SIZE, "%dx%d", &p->width, &p->height);
+		}
+	}
+
+	// Allocate the framebuffer
+	p->framebuf = malloc(p->width * p->height);
+	if (p->framebuf == NULL) {
+		report(RPT_ERR, "%s: unable to create framebuffer", drvthis->name);
+		return -1;
+	}
+	memset(p->framebuf, ' ', p->width * p->height);
+
+	
+	/* Set up io port correctly, and open it... */
+	p->fd = open(device, O_RDWR | O_NOCTTY);
+	if (p->fd == -1) {
+		report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, device, strerror(errno));
+		if (errno == EACCES)
+			report(RPT_ERR, "%s: %s device could not be opened...", drvthis->name, device);
+  		return -1;
+	}
+	report(RPT_INFO, "%s: opened display on %s", drvthis->name, device);
+
+	tcgetattr(p->fd, &portset);
+
+	/* We use RAW mode */
+#ifdef HAVE_CFMAKERAW
+	/* The easy way */
+	cfmakeraw(&portset);
+#else
+	/* The hard way */
+	portset.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP
+			      | INLCR | IGNCR | ICRNL | IXON );
+	portset.c_oflag &= ~OPOST;
+	portset.c_lflag &= ~( ECHO | ECHONL | ICANON | ISIG | IEXTEN );
+	portset.c_cflag &= ~( CSIZE | PARENB | CRTSCTS );
+	portset.c_cflag |= CS8 | CREAD | CLOCAL;
+#endif
+	/* Set timeouts */
+	portset.c_cc[VMIN] = 1;
+	portset.c_cc[VTIME] = 3;
+
+	/* Set port speed */
+	cfsetospeed(&portset, B9600);
+	cfsetispeed(&portset, B0);
+
+	/* Do it... */
+	tcsetattr(p->fd, TCSANOW, &portset);
+
+	
+	report(RPT_DEBUG, "%s: init() done", drvthis->name);
+
+	return 0;
+}
+
+
+/**
+ * Close the driver (do necessary clean-up).
+ * \param drvthis  Pointer to driver structure.
+ */
+MODULE_EXPORT void
+reallysimpleserial_close (Driver *drvthis)
+{
+	PrivateData *p = drvthis->private_data;
+
+	if (p != NULL) {
+		if (p->fd >= 0)
+			close(p->fd);
+		if (p->framebuf != NULL)
+			free(p->framebuf);
+
+		free(p);
+	}
+	drvthis->store_private_ptr(drvthis, NULL);
+}
+
+
+/**
+ * Return the display width in characters.
+ * \param drvthis  Pointer to driver structure.
+ * \return         Number of characters the display is wide.
+ */
+MODULE_EXPORT int
+reallysimpleserial_width (Driver *drvthis)
+{
+	PrivateData *p = drvthis->private_data;
+
+	return p->width;
+}
+
+
+/**
+ * Return the display height in characters.
+ * \param drvthis  Pointer to driver structure.
+ * \return         Number of characters the display is high.
+ */
+MODULE_EXPORT int
+reallysimpleserial_height (Driver *drvthis)
+{
+	PrivateData *p = drvthis->private_data;
+
+	return p->height;
+}
+
+
+/**
+ * Clear the screen.
+ * \param drvthis  Pointer to driver structure.
+ */
+MODULE_EXPORT void
+reallysimpleserial_clear (Driver *drvthis)
+{
+	PrivateData *p = drvthis->private_data;
+
+	memset(p->framebuf, ' ', p->width * p->height);
+}
+
+
+/**
+ * Flush data on screen to the display.
+ * Output is actually only written to every eight calls, since LCDproc is hard-wired to do
+ * delta display updates at 8 Hz. Since we don't want delta updates in this mode, and 
+ * dumping the entire framebuffer at 8 Hz could be excessive, the update rate is therefore
+ * binned down to 1 Hz
+ * \param drvthis  Pointer to driver structure.
+ */
+MODULE_EXPORT void
+reallysimpleserial_flush (Driver *drvthis)
+{
+
+	PrivateData *p = drvthis->private_data;
+	char out[LCD_MAX_WIDTH*LCD_MAX_HEIGHT];
+
+	
+
+	// LCDproc is hard-wired to call _flush on 1/8th sec intervals
+	// since I want to only produce serial traffic on 1 sec intervals, we need to only emit serial chars every 8 calls.
+
+	if (p->refresh_timer > 7) 
+	{
+		int dataEnd;
+		dataEnd = p->height * p->width;
+
+		// Straight-up dump the contents of each line in the framebuffer out the serial port. 
+		// There is NO processing or control chars emitted, just a plain-old newline at the end of the record
+		memcpy(out, p->framebuf, dataEnd);
+		out[dataEnd] = '\0';
+			
+		write(p->fd, out, dataEnd);
+			
+		
+		write(p->fd, "\n", 1);
+		p->refresh_timer = 0;
+
+	}
+	p->refresh_timer++;
+	
+}
+
+
+/**
+ * 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
+reallysimpleserial_string (Driver *drvthis, int x, int y, const char string[])
+{
+	PrivateData *p = drvthis->private_data;
+	int i;
+
+	x--; y--; // Convert 1-based coords to 0-based...
+
+	if ((y < 0) || (y >= p->height))
+                return;
+
+	for (i = 0; (string[i] != '\0') && (x < p->width); i++, x++) {
+		if (x >= 0)	// no write left of left border
+			p->framebuf[(y * p->width) + x] = string[i];
+	}
+}
+
+
+/**
+ * Print a character on the screen at position (x,y).
+ * The upper-left corner is (1,1), the lower-right corner is (p->width, p->height).
+ * \param drvthis  Pointer to driver structure.
+ * \param x        Horizontal character position (column).
+ * \param y        Vertical character position (row).
+ * \param c        Character that gets written.
+ */
+MODULE_EXPORT void
+reallysimpleserial_chr (Driver *drvthis, int x, int y, char c)
+{
+	PrivateData *p = drvthis->private_data;
+
+	y--; x--;
+
+	if ((x >= 0) && (y >= 0) && (x < p->width) && (y < p->height))
+		p->framebuf[(y * p->width) + x] = c;
+}
+
+
+/**
+ * Change the display contrast.
+ * Dumb reallysimpleserial reallysimpleserials do not support this, so we ignore it.
+ * \param drvthis  Pointer to driver structure.
+ * \param promille New contrast value in promille.
+ */
+MODULE_EXPORT void
+reallysimpleserial_set_contrast (Driver *drvthis, int promille)
+{
+	//PrivateData *p = drvthis->private_data;
+
+	debug(RPT_DEBUG, "Contrast: %d", promille);
+}
+
+
+/**
+ * Turn the display backlight on or off.
+ * Dumb reallysimpleserial reallysimpleserials do not support this, so we ignore it.
+ * \param drvthis  Pointer to driver structure.
+ * \param on       New backlight status.
+ */
+MODULE_EXPORT void
+reallysimpleserial_backlight (Driver *drvthis, int on)
+{
+	//PrivateData *p = drvthis->private_data;
+
+	debug(RPT_DEBUG, "Backlight %s", (on) ? "ON" : "OFF");
+}
+
+
+/**
+ * Provide some information about this driver.
+ * \param drvthis  Pointer to driver structure.
+ * \return         Constant string with information.
+ */
+MODULE_EXPORT const char *
+reallysimpleserial_get_info (Driver *drvthis)
+{
+	//PrivateData *p = drvthis->private_data;
+	static char *info_string = "Raw Text mode driver for use as a source for sending data to external hardware";
+
+	return info_string;
+}
\ No newline at end of file
diff -urN -X lcdprocStock/diff_ignore lcdprocStock/server/drivers/reallysimpleserial.h lcdproc/server/drivers/reallysimpleserial.h
--- lcdprocStock/server/drivers/reallysimpleserial.h	1969-12-31 16:00:00.000000000 -0800
+++ lcdproc/server/drivers/reallysimpleserial.h	2014-01-13 13:06:11.142438897 -0800
@@ -0,0 +1,22 @@
+#ifndef LCD_REALLYSIMPLESERIAL_H
+#define LCD_REALLYSIMPLESERIAL_H
+
+#define DEFAULT_DEVICE		"/dev/cuau0"
+
+
+#define DISPLAY_DEFAULT_SIZE "40x4"
+
+MODULE_EXPORT int  reallysimpleserial_init (Driver *drvthis);
+MODULE_EXPORT void reallysimpleserial_close (Driver *drvthis);
+MODULE_EXPORT int  reallysimpleserial_width (Driver *drvthis);
+MODULE_EXPORT int  reallysimpleserial_height (Driver *drvthis);
+MODULE_EXPORT void reallysimpleserial_clear (Driver *drvthis);
+MODULE_EXPORT void reallysimpleserial_flush (Driver *drvthis);
+MODULE_EXPORT void reallysimpleserial_string (Driver *drvthis, int x, int y, const char string[]);
+MODULE_EXPORT void reallysimpleserial_chr (Driver *drvthis, int x, int y, char c);
+MODULE_EXPORT void reallysimpleserial_set_contrast (Driver *drvthis, int promille);
+MODULE_EXPORT void reallysimpleserial_backlight (Driver *drvthis, int on);
+MODULE_EXPORT const char * reallysimpleserial_get_info (Driver *drvthis);
+
+
+#endif
\ No newline at end of file


--------------000104030108060909090303
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
LCDproc mailing list
[email protected]
http://lists.omnipotent.net/mailman/listinfo/lcdproc

--------------000104030108060909090303--