]> git.webhop.me Git - lcd4linux.git/commitdiff
[lcd4linux @ 2003-08-16 07:31:35 by reinelt]
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Sat, 16 Aug 2003 07:31:35 +0000 (07:31 +0000)
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Sat, 16 Aug 2003 07:31:35 +0000 (07:31 +0000)
double buffering in all drivers

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@217 3ae390bd-cb1e-0410-b409-cd5a39f66f1f

BeckmannEgle.c
Cwlinux.c
HD44780.c
M50530.c
MatrixOrbital.c
T6963.c
USBLCD.c
parport.c

index 48467f401e82971e369374a092b86592b1f60e3a..21504d77a0d8e1e29c82b2da2e17ea5355ade107 100644 (file)
@@ -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;
 }
 
index 6320a724af7bd54000e6ebf6f4425fe1117f8525..4866a61205760fc74ba9c69f9385e16cb06b72f9 100644 (file)
--- 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);
 }
 
index ce54b24cac6885a4ca647f91bbdf5648ebc5f6a7..496f922636a1d1dc03027b395444837c1c5cbcc8 100644 (file)
--- 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
  *
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 
 #include "debug.h"
 #include "cfg.h"
 
 
 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();
 }
 
index 402e59794c1e62c58528a168c63586181d689774..f5709952af10b1d5e93cbd6917019942fbe70c37 100644 (file)
--- 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
  *
 #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();
 }
 
index 822fec60c8f5a2a8f992307dd0a9bd2f7b875dd9..7cd32f1a33981927965d340b7748d965a6842a4a 100644 (file)
@@ -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 20221bf2b46fc9ab5b0c0c76a7e95b6a13cdf706..d096ebf1b2de5a378c420b09bc47f6d8bf80390f 100644 (file)
--- 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));
index 6d58c61ad85a48d51d1001dee2fdcd155aaca971..c9a098677cd793e34c459e654432cfe6b1900aa6 100644 (file)
--- 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
  *
 #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;
 }
 
index a1714ede05c05da72836b20b58eb65cdbc98580e..a5ba3c2e7ed3131a8f55463c9a9fca1d4ade4a36 100644 (file)
--- 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);