aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2003-08-16 07:31:35 +0000
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2003-08-16 07:31:35 +0000
commit9cfbe91b2263181d7aa51a2c3f9b644539d88cd6 (patch)
treeb96e57eecc9c13dbd925ef913e4fb19a9c39c13e
parent723ce62088b7c06deb4778263c1d6ad019455b8e (diff)
downloadlcd4linux-9cfbe91b2263181d7aa51a2c3f9b644539d88cd6.tar.gz
[lcd4linux @ 2003-08-16 07:31:35 by reinelt]
double buffering in all drivers git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@217 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
-rw-r--r--BeckmannEgle.c84
-rw-r--r--Cwlinux.c71
-rw-r--r--HD44780.c71
-rw-r--r--M50530.c68
-rw-r--r--MatrixOrbital.c109
-rw-r--r--T6963.c7
-rw-r--r--USBLCD.c91
-rw-r--r--parport.c6
8 files changed, 350 insertions, 157 deletions
diff --git a/BeckmannEgle.c b/BeckmannEgle.c
index 48467f4..21504d7 100644
--- a/BeckmannEgle.c
+++ b/BeckmannEgle.c
@@ -1,4 +1,4 @@
-/* $Id: BeckmannEgle.c,v 1.13 2003/07/24 04:48:09 reinelt Exp $
+/* $Id: BeckmannEgle.c,v 1.14 2003/08/16 07:31:35 reinelt Exp $
*
* driver for Beckmann+Egle mini terminals
*
@@ -20,6 +20,9 @@
*
*
* $Log: BeckmannEgle.c,v $
+ * Revision 1.14 2003/08/16 07:31:35 reinelt
+ * double buffering in all drivers
+ *
* Revision 1.13 2003/07/24 04:48:09 reinelt
* 'soft clear' needed for virtual rows
*
@@ -105,7 +108,8 @@ static char *Port=NULL;
static int Device=-1;
static int Type=-1;
-static char Txt[4][40];
+static char *FrameBuffer1=NULL;
+static char *FrameBuffer2=NULL;
static MODEL Model[]= {{ 16, 1, 0 },
{ 16, 2, 1 },
@@ -199,19 +203,15 @@ static void BE_define_char (int ascii, char *buffer)
int BE_clear (int full)
{
- int row, col;
-
- for (row=0; row<Lcd.rows; row++) {
- for (col=0; col<Lcd.cols; col++) {
- Txt[row][col]='\t';
- }
- }
+ memset (FrameBuffer1, ' ', Lcd.rows*Lcd.cols*sizeof(char));
bar_clear();
- if (full)
+ if (full) {
+ memset (FrameBuffer2, ' ', Lcd.rows*Lcd.cols*sizeof(char));
BE_write ("\033&#", 3);
-
+ }
+
return 0;
}
@@ -262,6 +262,14 @@ int BE_init (LCD *Self)
Self->cols=cols;
Lcd=*Self;
+ // Init the framebuffers
+ FrameBuffer1 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ FrameBuffer2 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ if (FrameBuffer1==NULL || FrameBuffer2==NULL) {
+ error ("BeckmannEgle: framebuffer could not be allocated: malloc() failed");
+ return -1;
+ }
+
Device=BE_open();
if (Device==-1) return -1;
@@ -278,10 +286,18 @@ int BE_init (LCD *Self)
return 0;
}
+void BE_goto (int row, int col)
+{
+ char cmd[7]="\033[y;xH";
+ cmd[2]=(char)row;
+ cmd[4]=(char)col;
+ BE_write (cmd, 6);
+}
+
int BE_put (int row, int col, char *text)
{
- char *p=&Txt[row][col];
+ char *p=FrameBuffer1+row*Lcd.cols+col;
char *t=text;
while (*t && col++<=Lcd.cols) {
@@ -299,30 +315,37 @@ int BE_bar (int type, int row, int col, int max, int len1, int len2)
int BE_flush (void)
{
- char buffer[256]="\033[y;xH";
- char *p;
- int c, row, col;
-
+ int row, col, pos1, pos2;
+ int c, equal;
+
bar_process(BE_define_char);
for (row=0; row<Lcd.rows; row++) {
- buffer[2]=row;
for (col=0; col<Lcd.cols; col++) {
c=bar_peek(row, col);
if (c!=-1) {
- Txt[row][col]=(char)c;
+ FrameBuffer1[row*Lcd.cols+col]=(char)c;
}
}
for (col=0; col<Lcd.cols; col++) {
- if (Txt[row][col]=='\t') continue;
- buffer[4]=col;
- for (p=buffer+6; col<Lcd.cols; col++, p++) {
- if (Txt[row][col]=='\t') break;
- *p=Txt[row][col];
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) continue;
+ BE_goto (row, col);
+ for (pos1=col++, pos2=pos1, equal=0; col<Lcd.cols; col++) {
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) {
+ // If we find just one equal byte, we don't break, because this
+ // would require a goto, which takes some bytes, too.
+ if (++equal>5) break;
+ } else {
+ pos2=col;
+ equal=0;
+ }
}
- BE_write (buffer, p-buffer);
+ BE_write (FrameBuffer1+row*Lcd.cols+pos1, pos2-pos1+1);
}
}
+
+ memcpy (FrameBuffer2, FrameBuffer1, Lcd.rows*Lcd.cols*sizeof(char));
+
return 0;
}
@@ -332,6 +355,19 @@ int BE_quit (void)
debug ("closing port %s", Port);
close (Device);
unlock_port(Port);
+
+ info("BeckmannEgle: shutting down.");
+
+ if (FrameBuffer1) {
+ free(FrameBuffer1);
+ FrameBuffer1=NULL;
+ }
+
+ if (FrameBuffer2) {
+ free(FrameBuffer2);
+ FrameBuffer2=NULL;
+ }
+
return 0;
}
diff --git a/Cwlinux.c b/Cwlinux.c
index 6320a72..4866a61 100644
--- a/Cwlinux.c
+++ b/Cwlinux.c
@@ -1,4 +1,4 @@
-/* $Id: Cwlinux.c,v 1.10 2003/08/01 05:15:42 reinelt Exp $
+/* $Id: Cwlinux.c,v 1.11 2003/08/16 07:31:35 reinelt Exp $
*
* driver for Cwlinux serial display modules
*
@@ -20,6 +20,9 @@
*
*
* $Log: Cwlinux.c,v $
+ * Revision 1.11 2003/08/16 07:31:35 reinelt
+ * double buffering in all drivers
+ *
* Revision 1.10 2003/08/01 05:15:42 reinelt
* last cleanups for 0.9.9
*
@@ -81,7 +84,8 @@ static char *Port = NULL;
static speed_t Speed;
static int Device = -1;
-static char Txt[4][20];
+static char *FrameBuffer1=NULL;
+static char *FrameBuffer2=NULL;
static int CW_open(void)
@@ -162,7 +166,7 @@ static int CW_read(char *string, int len)
static void CW_Goto(int row, int col)
{
- char cmd[5]="\376Gxy\375";
+ char cmd[6]="\376Gxy\375";
cmd[2]=(char)col;
cmd[3]=(char)row;
CW_write(cmd,5);
@@ -208,17 +212,12 @@ static void CW1602_define_char (int ascii, char *buffer)
int CW_clear(int full)
{
- int row, col;
-
- for (row = 0; row < Lcd.rows; row++) {
- for (col = 0; col < Lcd.cols; col++) {
- Txt[row][col] = '\t';
- }
- }
+ memset (FrameBuffer1, ' ', Lcd.rows*Lcd.cols*sizeof(char));
bar_clear();
if (full) {
+ memset (FrameBuffer2, ' ', Lcd.rows*Lcd.cols*sizeof(char));
#if 0
CW_write("\376X\375",3);
#else
@@ -271,6 +270,14 @@ int CW_init(LCD * Self)
Lcd = *Self;
+ // Init the framebuffers
+ FrameBuffer1 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ FrameBuffer2 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ if (FrameBuffer1==NULL || FrameBuffer2==NULL) {
+ error ("Cwlinux: framebuffer could not be allocated: malloc() failed");
+ return -1;
+ }
+
if (Port) {
free(Port);
Port = NULL;
@@ -344,7 +351,7 @@ int CW_init(LCD * Self)
int CW_put(int row, int col, char *text)
{
- char *p = &Txt[row][col];
+ char *p=FrameBuffer1+row*Lcd.cols+col;
char *t = text;
while (*t && col++ <= Lcd.cols) {
@@ -362,30 +369,36 @@ int CW_bar(int type, int row, int col, int max, int len1, int len2)
int CW_flush(void)
{
- char buffer[256];
- char *p;
- int c, row, col;
+ int row, col, pos1, pos2;
+ int c, equal;
for (row = 0; row < Lcd.rows; row++) {
for (col = 0; col < Lcd.cols; col++) {
c=bar_peek(row, col);
if (c!=-1) {
if (c!=32) c++; //blank
- Txt[row][col]=(char)c;
+ FrameBuffer1[row*Lcd.cols+col]=(char)c;
}
}
for (col = 0; col < Lcd.cols; col++) {
- if (Txt[row][col] == '\t')
- continue;
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) continue;
CW_Goto(row, col);
- for (p = buffer; col < Lcd.cols; col++, p++) {
- if (Txt[row][col] == '\t')
- break;
- *p = Txt[row][col];
+ for (pos1=col++, pos2=pos1, equal=0; col<Lcd.cols; col++) {
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) {
+ // If we find just one equal byte, we don't break, because this
+ // would require a goto, which takes one byte, too.
+ if (++equal>6) break;
+ } else {
+ pos2=col;
+ equal=0;
+ }
}
- CW_write(buffer, p - buffer);
+ CW_write (FrameBuffer1+row*Lcd.cols+pos1, pos2-pos1+1);
}
}
+
+ memcpy (FrameBuffer2, FrameBuffer1, Lcd.rows*Lcd.cols*sizeof(char));
+
return 0;
}
@@ -404,9 +417,23 @@ int CW1602_flush(void)
int CW_quit(void)
{
+ info("Cwlinux: shutting down.");
+
debug("closing port %s", Port);
close(Device);
unlock_port(Port);
+
+
+ if (FrameBuffer1) {
+ free(FrameBuffer1);
+ FrameBuffer1=NULL;
+ }
+
+ if (FrameBuffer2) {
+ free(FrameBuffer2);
+ FrameBuffer2=NULL;
+ }
+
return (0);
}
diff --git a/HD44780.c b/HD44780.c
index ce54b24..496f922 100644
--- a/HD44780.c
+++ b/HD44780.c
@@ -1,4 +1,4 @@
-/* $Id: HD44780.c,v 1.31 2003/08/15 07:54:07 reinelt Exp $
+/* $Id: HD44780.c,v 1.32 2003/08/16 07:31:35 reinelt Exp $
*
* driver for display modules based on the HD44780 chip
*
@@ -24,6 +24,9 @@
*
*
* $Log: HD44780.c,v $
+ * Revision 1.32 2003/08/16 07:31:35 reinelt
+ * double buffering in all drivers
+ *
* Revision 1.31 2003/08/15 07:54:07 reinelt
* HD44780 4 bit mode implemented
*
@@ -168,6 +171,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include "debug.h"
#include "cfg.h"
@@ -194,10 +198,11 @@
static LCD Lcd;
+static int Bits=0;
+static int GPO=0;
-static char Txt[4][40];
-static int Bits=0;
-static int GPO=0;
+static char *FrameBuffer1=NULL;
+static char *FrameBuffer2=NULL;
static unsigned char SIGNAL_RW;
static unsigned char SIGNAL_RS;
@@ -333,19 +338,13 @@ static void HD_define_char (int ascii, char *buffer)
int HD_clear (int full)
{
- int row, col;
-
- for (row=0; row<Lcd.rows; row++) {
- for (col=0; col<Lcd.cols; col++) {
- Txt[row][col]='\t';
- }
- }
+ memset (FrameBuffer1, ' ', Lcd.rows*Lcd.cols*sizeof(char));
bar_clear();
-
GPO=0;
-
+
if (full) {
+ memset (FrameBuffer2, ' ', Lcd.rows*Lcd.cols*sizeof(char));
HD_command (0x01, 1640); // clear display
HD_setGPO (GPO); // All GPO's off
}
@@ -383,6 +382,14 @@ int HD_init (LCD *Self)
Self->gpos=gpos;
Lcd=*Self;
+ // Init the framebuffers
+ FrameBuffer1 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ FrameBuffer2 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ if (FrameBuffer1==NULL || FrameBuffer2==NULL) {
+ error ("HD44780: framebuffer could not be allocated: malloc() failed");
+ return -1;
+ }
+
s=cfg_get("Bits", "8");
if ((Bits=strtol(s, &e, 0))==0 || *e!='\0' || (Bits!=4 && Bits!=8)) {
error ("HD44780: bad Bits '%s' in %s, should be '4' or '8'", s, cfg_file());
@@ -457,7 +464,7 @@ void HD_goto (int row, int col)
int HD_put (int row, int col, char *text)
{
- char *p=&Txt[row][col];
+ char *p=FrameBuffer1+row*Lcd.cols+col;
char *t=text;
while (*t && col++<=Lcd.cols) {
@@ -489,9 +496,8 @@ int HD_gpo (int num, int val)
int HD_flush (void)
{
- char buffer[256];
- char *p;
- int c, row, col;
+ int row, col, pos1, pos2;
+ int c, equal;
bar_process(HD_define_char);
@@ -499,20 +505,28 @@ int HD_flush (void)
for (col=0; col<Lcd.cols; col++) {
c=bar_peek(row, col);
if (c!=-1) {
- Txt[row][col]=(char)c;
+ FrameBuffer1[row*Lcd.cols+col]=(char)c;
}
}
for (col=0; col<Lcd.cols; col++) {
- if (Txt[row][col]=='\t') continue;
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) continue;
HD_goto (row, col);
- for (p=buffer; col<Lcd.cols; col++, p++) {
- if (Txt[row][col]=='\t') break;
- *p=Txt[row][col];
+ for (pos1=col++, pos2=pos1, equal=0; col<Lcd.cols; col++) {
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) {
+ // If we find just one equal byte, we don't break, because this
+ // would require a goto, which takes one byte, too.
+ if (++equal>2) break;
+ } else {
+ pos2=col;
+ equal=0;
+ }
}
- HD_write (buffer, p-buffer, 40); // 40 usec delay for write
+ HD_write (FrameBuffer1+row*Lcd.cols+pos1, pos2-pos1+1, 40); // 40 usec delay for write
}
}
+ memcpy (FrameBuffer2, FrameBuffer1, Lcd.rows*Lcd.cols*sizeof(char));
+
HD_setGPO(GPO);
return 0;
@@ -522,6 +536,17 @@ int HD_flush (void)
int HD_quit (void)
{
info("HD44780: shutting down.");
+
+ if (FrameBuffer1) {
+ free(FrameBuffer1);
+ FrameBuffer1=NULL;
+ }
+
+ if (FrameBuffer2) {
+ free(FrameBuffer2);
+ FrameBuffer2=NULL;
+ }
+
return parport_close();
}
diff --git a/M50530.c b/M50530.c
index 402e597..f570995 100644
--- a/M50530.c
+++ b/M50530.c
@@ -1,4 +1,4 @@
-/* $Id: M50530.c,v 1.10 2003/08/15 07:54:07 reinelt Exp $
+/* $Id: M50530.c,v 1.11 2003/08/16 07:31:35 reinelt Exp $
*
* driver for display modules based on the M50530 chip
*
@@ -20,6 +20,9 @@
*
*
* $Log: M50530.c,v $
+ * Revision 1.11 2003/08/16 07:31:35 reinelt
+ * double buffering in all drivers
+ *
* Revision 1.10 2003/08/15 07:54:07 reinelt
* HD44780 4 bit mode implemented
*
@@ -81,10 +84,12 @@
#define CHARS 8
static LCD Lcd;
-
-static char Txt[8][40];
static int GPO=0;
+static char *FrameBuffer1=NULL;
+static char *FrameBuffer2=NULL;
+
+
static unsigned char SIGNAL_EX;
static unsigned char SIGNAL_IOC1;
static unsigned char SIGNAL_IOC2;
@@ -153,19 +158,13 @@ static void M5_define_char (int ascii, char *buffer)
int M5_clear (int full)
{
- int row, col;
-
- for (row=0; row<Lcd.rows; row++) {
- for (col=0; col<Lcd.cols; col++) {
- Txt[row][col]='\t';
- }
- }
+ memset (FrameBuffer1, ' ', Lcd.rows*Lcd.cols*sizeof(char));
bar_clear();
-
GPO=0;
if (full) {
+ memset (FrameBuffer2, ' ', Lcd.rows*Lcd.cols*sizeof(char));
M5_command (0x0001, 1250); // clear display
M5_setGPO (GPO); // All GPO's off
}
@@ -205,6 +204,14 @@ int M5_init (LCD *Self)
Self->gpos=gpos;
Lcd=*Self;
+ // Init the framebuffers
+ FrameBuffer1 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ FrameBuffer2 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ if (FrameBuffer1==NULL || FrameBuffer2==NULL) {
+ error ("HD44780: framebuffer could not be allocated: malloc() failed");
+ return -1;
+ }
+
if ((SIGNAL_EX = parport_wire_ctrl ("EX", "STROBE"))==0xff) return -1;
if ((SIGNAL_IOC1 = parport_wire_ctrl ("IOC1", "SELECT"))==0xff) return -1;
if ((SIGNAL_IOC2 = parport_wire_ctrl ("IOC2", "AUTOFD"))==0xff) return -1;
@@ -245,7 +252,7 @@ void M5_goto (int row, int col)
int M5_put (int row, int col, char *text)
{
- char *p=&Txt[row][col];
+ char *p=FrameBuffer1+row*Lcd.cols+col;
char *t=text;
while (*t && col++<=Lcd.cols) {
@@ -277,9 +284,8 @@ int M5_gpo (int num, int val)
int M5_flush (void)
{
- unsigned char buffer[256];
- unsigned char *p;
- int c, row, col;
+ int row, col, pos1, pos2;
+ int c, equal;
bar_process(M5_define_char);
@@ -288,19 +294,27 @@ int M5_flush (void)
c=bar_peek(row, col);
if (c!=-1) {
if (c!=32) c+=248; //blank
- Txt[row][col]=(char)(c);
+ FrameBuffer1[row*Lcd.cols+col]=(char)c;
}
}
for (col=0; col<Lcd.cols; col++) {
- if (Txt[row][col]=='\t') continue;
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) continue;
M5_goto (row, col);
- for (p=buffer; col<Lcd.cols; col++, p++) {
- if (Txt[row][col]=='\t') break;
- *p=Txt[row][col];
+ for (pos1=col++, pos2=pos1, equal=0; col<Lcd.cols; col++) {
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) {
+ // If we find just one equal byte, we don't break, because this
+ // would require a goto, which takes one byte, too.
+ if (++equal>2) break;
+ } else {
+ pos2=col;
+ equal=0;
+ }
}
- M5_write (buffer, p-buffer);
+ M5_write (FrameBuffer1+row*Lcd.cols+pos1, pos2-pos1+1);
}
}
+
+ memcpy (FrameBuffer2, FrameBuffer1, Lcd.rows*Lcd.cols*sizeof(char));
M5_setGPO(GPO);
@@ -310,6 +324,18 @@ int M5_flush (void)
int M5_quit (void)
{
+ info("M50530: shutting down.");
+
+ if (FrameBuffer1) {
+ free(FrameBuffer1);
+ FrameBuffer1=NULL;
+ }
+
+ if (FrameBuffer2) {
+ free(FrameBuffer2);
+ FrameBuffer2=NULL;
+ }
+
return parport_close();
}
diff --git a/MatrixOrbital.c b/MatrixOrbital.c
index 822fec6..7cd32f1 100644
--- a/MatrixOrbital.c
+++ b/MatrixOrbital.c
@@ -1,4 +1,4 @@
-/* $Id: MatrixOrbital.c,v 1.28 2003/07/24 04:48:09 reinelt Exp $
+/* $Id: MatrixOrbital.c,v 1.29 2003/08/16 07:31:35 reinelt Exp $
*
* driver for Matrix Orbital serial display modules
*
@@ -20,6 +20,9 @@
*
*
* $Log: MatrixOrbital.c,v $
+ * Revision 1.29 2003/08/16 07:31:35 reinelt
+ * double buffering in all drivers
+ *
* Revision 1.28 2003/07/24 04:48:09 reinelt
* 'soft clear' needed for virtual rows
*
@@ -170,9 +173,10 @@ static LCD Lcd;
static char *Port=NULL;
static speed_t Speed;
static int Device=-1;
+static int GPO;
-static char Txt[4][40];
-static int GPO;
+static char *FrameBuffer1=NULL;
+static char *FrameBuffer2=NULL;
static int MO_open (void)
@@ -247,31 +251,28 @@ static void MO_define_char (int ascii, char *buffer)
static int MO_clear (int protocol)
{
- int row, col, gpo;
-
- for (row=0; row<Lcd.rows; row++) {
- for (col=0; col<Lcd.cols; col++) {
- Txt[row][col]='\t';
- }
- }
-
+ int gpo;
+
+ memset (FrameBuffer1, ' ', Lcd.rows*Lcd.cols*sizeof(char));
bar_clear();
-
GPO=0;
- switch (protocol) {
- case 1:
- MO_write ("\014", 1); // Clear Screen
- MO_write ("\376V", 2); // GPO off
- break;
- case 2:
- MO_write ("\376\130", 2); // Clear Screen
- for (gpo=1; gpo<=Lcd.gpos; gpo++) {
- char cmd[3]="\376V";
- cmd[2]=(char)gpo;
- MO_write (cmd, 3); // GPO off
+ if (protocol) {
+ memset (FrameBuffer2, ' ', Lcd.rows*Lcd.cols*sizeof(char));
+ switch (protocol) {
+ case 1:
+ MO_write ("\014", 1); // Clear Screen
+ MO_write ("\376V", 2); // GPO off
+ break;
+ case 2:
+ MO_write ("\376\130", 2); // Clear Screen
+ for (gpo=1; gpo<=Lcd.gpos; gpo++) {
+ char cmd[3]="\376V";
+ cmd[2]=(char)gpo;
+ MO_write (cmd, 3); // GPO off
+ }
+ break;
}
- break;
}
return 0;
@@ -295,6 +296,14 @@ static int MO_init (LCD *Self, int protocol)
Lcd=*Self;
+ // Init the framebuffers
+ FrameBuffer1 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ FrameBuffer2 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ if (FrameBuffer1==NULL || FrameBuffer2==NULL) {
+ error ("MatrixOrbital: framebuffer could not be allocated: malloc() failed");
+ return -1;
+ }
+
if (Port) {
free (Port);
Port=NULL;
@@ -359,10 +368,18 @@ int MO_init2 (LCD *Self)
}
+void MO_goto (int row, int col)
+{
+ char cmd[5]="\376Gyx";
+ cmd[2]=(char)col+1;
+ cmd[3]=(char)row+1;
+ MO_write(cmd,4);
+}
+
int MO_put (int row, int col, char *text)
{
- char *p=&Txt[row][col];
+ char *p=FrameBuffer1+row*Lcd.cols+col;
char *t=text;
while (*t && col++<=Lcd.cols) {
@@ -394,30 +411,37 @@ int MO_gpo (int num, int val)
static int MO_flush (int protocol)
{
- char buffer[256]="\376G";
- char *p;
- int c, row, col, gpo;
+ int row, col, pos1, pos2;
+ int c, equal;
+ int gpo;
bar_process(MO_define_char);
for (row=0; row<Lcd.rows; row++) {
- buffer[3]=row+1;
for (col=0; col<Lcd.cols; col++) {
c=bar_peek(row, col);
if (c!=-1) {
- Txt[row][col]=(char)c;
+ FrameBuffer1[row*Lcd.cols+col]=(char)c;
}
}
for (col=0; col<Lcd.cols; col++) {
- if (Txt[row][col]=='\t') continue;
- buffer[2]=col+1;
- for (p=buffer+4; col<Lcd.cols; col++, p++) {
- if (Txt[row][col]=='\t') break;
- *p=Txt[row][col];
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) continue;
+ MO_goto (row, col);
+ for (pos1=col++, pos2=pos1, equal=0; col<Lcd.cols; col++) {
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) {
+ // If we find just one equal byte, we don't break, because this
+ // would require a goto, which takes one byte, too.
+ if (++equal>5) break;
+ } else {
+ pos2=col;
+ equal=0;
+ }
}
- MO_write (buffer, p-buffer);
+ MO_write (FrameBuffer1+row*Lcd.cols+pos1, pos2-pos1+1);
}
}
+
+ memcpy (FrameBuffer2, FrameBuffer1, Lcd.rows*Lcd.cols*sizeof(char));
switch (protocol) {
case 1:
@@ -453,9 +477,22 @@ int MO_flush2 (void)
int MO_quit (void)
{
+ info("MatrixOrbital: shutting down.");
+
debug ("closing port %s", Port);
close (Device);
unlock_port(Port);
+
+ if (FrameBuffer1) {
+ free(FrameBuffer1);
+ FrameBuffer1=NULL;
+ }
+
+ if (FrameBuffer2) {
+ free(FrameBuffer2);
+ FrameBuffer2=NULL;
+ }
+
return (0);
}
diff --git a/T6963.c b/T6963.c
index 20221bf..d096ebf 100644
--- a/T6963.c
+++ b/T6963.c
@@ -1,4 +1,4 @@
-/* $Id: T6963.c,v 1.9 2003/08/15 07:54:07 reinelt Exp $
+/* $Id: T6963.c,v 1.10 2003/08/16 07:31:35 reinelt Exp $
*
* driver for display modules based on the Toshiba T6963 chip
*
@@ -20,6 +20,9 @@
*
*
* $Log: T6963.c,v $
+ * Revision 1.10 2003/08/16 07:31:35 reinelt
+ * double buffering in all drivers
+ *
* Revision 1.9 2003/08/15 07:54:07 reinelt
* HD44780 4 bit mode implemented
*
@@ -397,7 +400,6 @@ int T6_bar (int type, int row, int col, int max, int len1, int len2)
int T6_flush (void)
{
int i, j, e;
- int count=0;
memset(Buffer1,0,Lcd.cols*Lcd.rows*Lcd.yres*sizeof(*Buffer1));
@@ -418,7 +420,6 @@ int T6_flush (void)
}
}
T6_memcpy (j, Buffer1+j, i-j-e+1);
- count+=i-j-e+1;
}
memcpy(Buffer2,Buffer1,Lcd.cols*Lcd.rows*Lcd.yres*sizeof(*Buffer1));
diff --git a/USBLCD.c b/USBLCD.c
index 6d58c61..c9a0986 100644
--- a/USBLCD.c
+++ b/USBLCD.c
@@ -1,4 +1,4 @@
-/* $Id: USBLCD.c,v 1.10 2003/07/24 04:48:09 reinelt Exp $
+/* $Id: USBLCD.c,v 1.11 2003/08/16 07:31:35 reinelt Exp $
*
* Driver for USBLCD ( see http://www.usblcd.de )
* This Driver is based on HD44780.c
@@ -22,6 +22,9 @@
*
*
* $Log: USBLCD.c,v $
+ * Revision 1.11 2003/08/16 07:31:35 reinelt
+ * double buffering in all drivers
+ *
* Revision 1.10 2003/07/24 04:48:09 reinelt
* 'soft clear' needed for virtual rows
*
@@ -94,13 +97,13 @@
#define CHARS 8
static LCD Lcd;
-
-int usblcd_file;
-
static char *Port=NULL;
-static char Txt[4][40];
+static int usblcd_file;
+
+static char *FrameBuffer1=NULL;
+static char *FrameBuffer2=NULL;
-static unsigned char Buffer[1024];
+static unsigned char *Buffer;
static unsigned char *BufPtr;
static void USBLCD_send ()
@@ -195,19 +198,15 @@ static void USBLCD_define_char (int ascii, char *buffer)
int USBLCD_clear (int full)
{
- int row, col;
-
- for (row=0; row<Lcd.rows; row++) {
- for (col=0; col<Lcd.cols; col++) {
- Txt[row][col]='\t';
- }
- }
-
+
+ memset (FrameBuffer1, ' ', Lcd.rows*Lcd.cols*sizeof(char));
bar_clear();
- if (full)
+ if (full) {
+ memset (FrameBuffer2, ' ', Lcd.rows*Lcd.cols*sizeof(char));
USBLCD_command (0x01); // clear display
-
+ }
+
return 0;
}
@@ -248,6 +247,21 @@ int USBLCD_init (LCD *Self)
Self->cols=cols;
Lcd=*Self;
+ // Init the command buffer
+ Buffer = (char*)malloc(1024);
+ if (Buffer==NULL) {
+ error ("USBLCD: coommand buffer could not be allocated: malloc() failed");
+ return -1;
+ }
+
+ // Init the framebuffers
+ FrameBuffer1 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ FrameBuffer2 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char));
+ if (FrameBuffer1==NULL || FrameBuffer2==NULL) {
+ error ("USBLCD: framebuffer could not be allocated: malloc() failed");
+ return -1;
+ }
+
if (USBLCD_open()!=0)
return -1;
@@ -271,7 +285,7 @@ void USBLCD_goto (int row, int col)
int USBLCD_put (int row, int col, char *text)
{
- char *p=&Txt[row][col];
+ char *p=FrameBuffer1+row*Lcd.cols+col;
char *t=text;
while (*t && col++<=Lcd.cols) {
@@ -289,9 +303,8 @@ int USBLCD_bar (int type, int row, int col, int max, int len1, int len2)
int USBLCD_flush (void)
{
- char buffer[256];
- char *p;
- int c, row, col;
+ int row, col, pos1, pos2;
+ int c, equal;
bar_process(USBLCD_define_char);
@@ -299,31 +312,57 @@ int USBLCD_flush (void)
for (col=0; col<Lcd.cols; col++) {
c=bar_peek(row, col);
if (c!=-1) {
- Txt[row][col]=(char)c;
+ FrameBuffer1[row*Lcd.cols+col]=(char)c;
}
}
for (col=0; col<Lcd.cols; col++) {
- if (Txt[row][col]=='\t') continue;
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) continue;
USBLCD_goto (row, col);
- for (p=buffer; col<Lcd.cols; col++, p++) {
- if (Txt[row][col]=='\t') break;
- *p=Txt[row][col];
+ for (pos1=col++, pos2=pos1, equal=0; col<Lcd.cols; col++) {
+ if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) {
+ // If we find just one equal byte, we don't break, because this
+ // would require a goto, which takes one byte, too.
+ if (++equal>2) break;
+ } else {
+ pos2=col;
+ equal=0;
+ }
}
- USBLCD_write (buffer, p-buffer);
+ USBLCD_write (FrameBuffer1+row*Lcd.cols+pos1, pos2-pos1+1);
}
}
USBLCD_send();
+ memcpy (FrameBuffer2, FrameBuffer1, Lcd.rows*Lcd.cols*sizeof(char));
+
return 0;
}
int USBLCD_quit (void)
{
+ info("USBLCD: shutting down.");
USBLCD_send();
+
debug ("closing port %s", Port);
close(usblcd_file);
+
+ if (Buffer) {
+ free(Buffer);
+ Buffer=NULL;
+ }
+
+ if (FrameBuffer1) {
+ free(FrameBuffer1);
+ FrameBuffer1=NULL;
+ }
+
+ if (FrameBuffer2) {
+ free(FrameBuffer2);
+ FrameBuffer2=NULL;
+ }
+
return 0;
}
diff --git a/parport.c b/parport.c
index a1714ed..a5ba3c2 100644
--- a/parport.c
+++ b/parport.c
@@ -1,4 +1,4 @@
-/* $Id: parport.c,v 1.3 2003/08/15 07:54:07 reinelt Exp $
+/* $Id: parport.c,v 1.4 2003/08/16 07:31:35 reinelt Exp $
*
* generic parallel port handling
*
@@ -20,6 +20,9 @@
*
*
* $Log: parport.c,v $
+ * Revision 1.4 2003/08/16 07:31:35 reinelt
+ * double buffering in all drivers
+ *
* Revision 1.3 2003/08/15 07:54:07 reinelt
* HD44780 4 bit mode implemented
*
@@ -288,7 +291,6 @@ unsigned char parport_wire_data (char *name, unsigned char *deflt)
{
unsigned char w;
char wire[256];
- int is_data=0;
char *s;
snprintf (wire, sizeof(wire), "Wire.%s", name);