From 3588180b37d5a1c1c5e5fdefe93162bd76d5a20d Mon Sep 17 00:00:00 2001
From: reinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Date: Fri, 24 Sep 2004 21:41:00 +0000
Subject: [lcd4linux @ 2004-09-24 21:40:52 by reinelt] new driver for the BWCT
 USB LCD interface board.

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@492 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
---
 Makefile.am           |   1 +
 Makefile.in           |   4 +-
 config.h.in           |   6 +
 configure             | 181 ++++++++++++++++++++++-
 configure.in          |   3 +
 drivers.m4            |  23 ++-
 drv.c                 |   9 +-
 drv_BWCT.c            | 402 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drv_USBLCD.c          |  15 +-
 lcd4linux.c           |  10 +-
 lcd4linux.conf.sample |  14 +-
 plugin_exec.c         |   7 +-
 12 files changed, 656 insertions(+), 19 deletions(-)
 create mode 100644 drv_BWCT.c

diff --git a/Makefile.am b/Makefile.am
index 19e08dd..9124e00 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -58,6 +58,7 @@ drv_generic_serial.h        \
 drv_generic_parport.c       \
 drv_generic_parport.h       \
 drv_BeckmannEgle.c          \
+drv_BWCT.c                  \
 drv_Crystalfontz.c          \
 drv_Curses.c                \
 drv_Cwlinux.c               \
diff --git a/Makefile.in b/Makefile.in
index fc3a78c..e9b85b6 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -99,7 +99,7 @@ lcd4linux_SOURCES =  lcd4linux.c                 cfg.c         cfg.h         deb
 
 #liblcd4linux_la_SOURCES =
 
-EXTRA_lcd4linux_SOURCES =  drv_generic_text.c          drv_generic_text.h          drv_generic_graphic.c       drv_generic_graphic.h       drv_generic_serial.c        drv_generic_serial.h        drv_generic_parport.c       drv_generic_parport.h       drv_BeckmannEgle.c          drv_Crystalfontz.c          drv_Curses.c                drv_Cwlinux.c               drv_HD44780.c               drv_Image.c                 drv_M50530.c                drv_MatrixOrbital.c         drv_MilfordInstruments.c    drv_NULL.c                  drv_RouterBoard.c           drv_T6963.c                 drv_USBLCD.c                drv_X11.c                                               font_6x8.h                                              plugin_apm.c                plugin_cpuinfo.c            plugin_diskstats.c          plugin_dvb.c                plugin_exec.c               plugin_i2c_sensors.c        plugin_imon.c               plugin_isdn.c               plugin_loadavg.c            plugin_meminfo.c            plugin_mysql.c              plugin_netdev.c             plugin_pop3.c               plugin_ppp.c                plugin_proc_stat.c          plugin_seti.c               plugin_uname.c              plugin_uptime.c             plugin_wireless.c           plugin_xmms.c
+EXTRA_lcd4linux_SOURCES =  drv_generic_text.c          drv_generic_text.h          drv_generic_graphic.c       drv_generic_graphic.h       drv_generic_serial.c        drv_generic_serial.h        drv_generic_parport.c       drv_generic_parport.h       drv_BeckmannEgle.c          drv_BWCT.c                  drv_Crystalfontz.c          drv_Curses.c                drv_Cwlinux.c               drv_HD44780.c               drv_Image.c                 drv_M50530.c                drv_MatrixOrbital.c         drv_MilfordInstruments.c    drv_NULL.c                  drv_RouterBoard.c           drv_T6963.c                 drv_USBLCD.c                drv_X11.c                                               font_6x8.h                                              plugin_apm.c                plugin_cpuinfo.c            plugin_diskstats.c          plugin_dvb.c                plugin_exec.c               plugin_i2c_sensors.c        plugin_imon.c               plugin_isdn.c               plugin_loadavg.c            plugin_meminfo.c            plugin_mysql.c              plugin_netdev.c             plugin_pop3.c               plugin_ppp.c                plugin_proc_stat.c          plugin_seti.c               plugin_uname.c              plugin_uptime.c             plugin_wireless.c           plugin_xmms.c
 
 
 EXTRA_DIST =  lcd4linux.conf.sample       lcd4kde.conf                lcd4linux.kdelnk            lcd4linux.xpm               lcd4linux.lsm               curses.m4                   AUTHORS                     CREDITS                     FAQ                         NEWS                        TODO                        README                      README.Drivers              README.Plugins              README.KDE                  plugin_sample.c
@@ -137,7 +137,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
 GZIP_ENV = --best
-DEP_FILES =  .deps/cfg.P .deps/debug.P .deps/drv.P \
+DEP_FILES =  .deps/cfg.P .deps/debug.P .deps/drv.P .deps/drv_BWCT.P \
 .deps/drv_BeckmannEgle.P .deps/drv_Crystalfontz.P .deps/drv_Curses.P \
 .deps/drv_Cwlinux.P .deps/drv_HD44780.P .deps/drv_Image.P \
 .deps/drv_M50530.P .deps/drv_MatrixOrbital.P \
diff --git a/config.h.in b/config.h.in
index 1672e68..a81154c 100644
--- a/config.h.in
+++ b/config.h.in
@@ -184,6 +184,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the <usb.h> header file. */
+#undef HAVE_USB_H
+
 /* Define to 1 if you have the `vfork' function. */
 #undef HAVE_VFORK
 
@@ -311,6 +314,9 @@
 /* Beckmann&Egle driver */
 #undef WITH_BECKMANNEGLE
 
+/* BWCT driver */
+#undef WITH_BWCT
+
 /* Crystalfontz driver */
 #undef WITH_CRYSTALFONTZ
 
diff --git a/configure b/configure
index 68fadef..387bec7 100755
--- a/configure
+++ b/configure
@@ -867,9 +867,9 @@ Optional Packages:
                           drivers may be excluded with 'all,!<driver>',
                           (try 'all,\!<driver>' if your shell complains...)
                           possible drivers are:
-                          BeckmannEgle, CrystalFontz, Curses, Cwlinux, HD44780,
-                          M50530, MatrixOrbital, MilfordInstruments, NULL
-                          PNG, PPM, RouterBoard, T6963, USBLCD, X11
+                          BeckmannEgle, BWCT, CrystalFontz, Curses, Cwlinux,
+                          HD44780, M50530, MatrixOrbital, MilfordInstruments,
+                          NULL, PNG, PPM, RouterBoard, T6963, USBLCD, X11
   --with-plugins=<list>   choose which plugins to compile.
                           type --with-plugins=list for a list
                           of avaible plugins
@@ -5217,6 +5217,159 @@ fi
 done
 
 
+# check for usb.h
+
+for ac_header in usb.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to reinelt@eunet.at ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ has_usb=true
+else
+  has_usb=false
+fi
+
+done
+
+
 # drivers
 # Drivers conf part
 
@@ -5249,6 +5402,7 @@ for driver in $drivers; do
    case "$driver" in
       all)
          BECKMANNEGLE="yes"
+         BWCT="yes"
          CRYSTALFONTZ="yes"
          CURSES="yes"
          CWLINUX="yes"
@@ -5267,6 +5421,9 @@ for driver in $drivers; do
       BeckmannEgle)
          BECKMANNEGLE=$val
          ;;
+      BWCT)
+         BWCT=$val
+         ;;
       CrystalFontz)
          CRYSTALFONTZ=$val
          ;;
@@ -5327,6 +5484,8 @@ GRAPHIC="no"
 IMAGE="no"
 
 if test "$BECKMANNEGLE" = "yes"; then
+   TEXT="yes"
+   SERIAL="yes"
    DRIVERS="$DRIVERS drv_BeckmannEgle.o"
 
 cat >>confdefs.h <<\_ACEOF
@@ -5335,6 +5494,22 @@ _ACEOF
 
 fi
 
+if test "$BWCT" = "yes"; then
+   if test "$has_usb" = "true"; then
+      TEXT="yes"
+      DRIVERS="$DRIVERS drv_BWCT.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_BWCT 1
+_ACEOF
+
+      DRVLIBS="$DRVLIBS -lusb"
+   else
+      { echo "$as_me:$LINENO: WARNING: usb.h not found: BWCT driver disabled" >&5
+echo "$as_me: WARNING: usb.h not found: BWCT driver disabled" >&2;}
+   fi
+fi
+
 if test "$CRYSTALFONTZ" = "yes"; then
    TEXT="yes"
    SERIAL="yes"
diff --git a/configure.in b/configure.in
index 5acef64..bbfdc6c 100644
--- a/configure.in
+++ b/configure.in
@@ -28,6 +28,9 @@ AC_PATH_XTRA
 # check for gd.h
 AC_CHECK_HEADERS(gd/gd.h gd.h, [has_gd=true], [has_gd=false])
 
+# check for usb.h
+AC_CHECK_HEADERS(usb.h, [has_usb=true], [has_usb=false])
+
 # drivers
 sinclude(drivers.m4)
 
diff --git a/drivers.m4 b/drivers.m4
index 561ad8b..664ff5c 100644
--- a/drivers.m4
+++ b/drivers.m4
@@ -9,9 +9,9 @@ AC_ARG_WITH(
   [                        drivers may be excluded with 'all,!<driver>',]	
   [                        (try 'all,\!<driver>' if your shell complains...)]	
   [                        possible drivers are:]	
-  [                        BeckmannEgle, CrystalFontz, Curses, Cwlinux, HD44780,]
-  [                        M50530, MatrixOrbital, MilfordInstruments, NULL]
-  [                        PNG, PPM, RouterBoard, T6963, USBLCD, X11],
+  [                        BeckmannEgle, BWCT, CrystalFontz, Curses, Cwlinux,]
+  [                        HD44780, M50530, MatrixOrbital, MilfordInstruments,]
+  [                        NULL, PNG, PPM, RouterBoard, T6963, USBLCD, X11],
   drivers=$withval, 
   drivers=all
 )
@@ -33,6 +33,7 @@ for driver in $drivers; do
    case "$driver" in
       all)
          BECKMANNEGLE="yes"
+         BWCT="yes"
          CRYSTALFONTZ="yes"
          CURSES="yes"
          CWLINUX="yes"
@@ -51,6 +52,9 @@ for driver in $drivers; do
       BeckmannEgle)
          BECKMANNEGLE=$val
          ;;
+      BWCT)
+         BWCT=$val
+         ;;
       CrystalFontz)
          CRYSTALFONTZ=$val
          ;;
@@ -108,10 +112,23 @@ GRAPHIC="no"
 IMAGE="no"
 
 if test "$BECKMANNEGLE" = "yes"; then
+   TEXT="yes"
+   SERIAL="yes"
    DRIVERS="$DRIVERS drv_BeckmannEgle.o"
    AC_DEFINE(WITH_BECKMANNEGLE,1,[Beckmann&Egle driver])
 fi
 
+if test "$BWCT" = "yes"; then
+   if test "$has_usb" = "true"; then
+      TEXT="yes"
+      DRIVERS="$DRIVERS drv_BWCT.o"
+      AC_DEFINE(WITH_BWCT,1,[BWCT driver])
+      DRVLIBS="$DRVLIBS -lusb"
+   else
+      AC_MSG_WARN(usb.h not found: BWCT driver disabled)
+   fi
+fi
+
 if test "$CRYSTALFONTZ" = "yes"; then
    TEXT="yes"
    SERIAL="yes"
diff --git a/drv.c b/drv.c
index 1bd4bac..c843e51 100644
--- a/drv.c
+++ b/drv.c
@@ -1,4 +1,4 @@
-/* $Id: drv.c,v 1.22 2004/08/29 13:03:41 reinelt Exp $
+/* $Id: drv.c,v 1.23 2004/09/24 21:41:00 reinelt Exp $
  *
  * new framework for display drivers
  *
@@ -23,6 +23,9 @@
  *
  *
  * $Log: drv.c,v $
+ * Revision 1.23  2004/09/24 21:41:00  reinelt
+ * new driver for the BWCT USB LCD interface board.
+ *
  * Revision 1.22  2004/08/29 13:03:41  reinelt
  *
  * added RouterBoard driver
@@ -168,6 +171,7 @@
 #include "drv.h"
 
 extern DRIVER drv_BeckmannEgle;
+extern DRIVER drv_BWCT;
 extern DRIVER drv_Crystalfontz;
 extern DRIVER drv_Curses;
 extern DRIVER drv_Cwlinux;
@@ -192,6 +196,9 @@ DRIVER *Driver[] = {
 #ifdef WITH_BECKMANNEGLE
   &drv_BeckmannEgle,
 #endif
+#ifdef WITH_BWCT
+  &drv_BWCT,
+#endif
 #ifdef WITH_CRYSTALFONTZ
   &drv_Crystalfontz,
 #endif
diff --git a/drv_BWCT.c b/drv_BWCT.c
new file mode 100644
index 0000000..6bf2617
--- /dev/null
+++ b/drv_BWCT.c
@@ -0,0 +1,402 @@
+/* $Id: drv_BWCT.c,v 1.1 2004/09/24 21:41:00 reinelt Exp $
+ *
+ * new style driver for BWCT USB LCD displays
+ *
+ * Copyright 1999-2004 Michael Reinelt <reinelt@eunet.at>
+ * Copyright 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
+ *
+ * This file is part of LCD4Linux.
+ *
+ * LCD4Linux 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, or (at your option)
+ * any later version.
+ *
+ * LCD4Linux 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * $Log: drv_BWCT.c,v $
+ * Revision 1.1  2004/09/24 21:41:00  reinelt
+ * new driver for the BWCT USB LCD interface board.
+ *
+ */
+
+/* 
+ *
+ * exported fuctions:
+ *
+ * struct DRIVER drv_BWCT
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+
+#include <usb.h>
+
+#include "debug.h"
+#include "cfg.h"
+#include "qprintf.h"
+#include "plugin.h"
+#include "widget.h"
+#include "widget_text.h"
+#include "widget_icon.h"
+#include "widget_bar.h"
+#include "drv.h"
+#include "drv_generic_text.h"
+
+
+#define LCD_USB_VENDOR 0x03da
+#define LCD_USB_DEVICE 0x0002
+
+#define LCD_RESET    1
+#define LCD_CMD      2
+#define LCD_DATA     3
+#define LCD_CONTRAST 4
+
+
+static char Name[]="BWCT";
+
+static usb_dev_handle *lcd;
+static int interface;
+
+extern int usb_debug;
+extern int got_signal;
+
+
+/****************************************/
+/***  hardware dependant functions    ***/
+/****************************************/
+
+static int drv_BW_open (void)
+{
+  struct usb_bus *busses, *bus;
+  struct usb_device *dev;
+  
+  lcd = NULL;
+
+  info ("%s: scanning USB for BWCT LCD...", Name);
+
+  usb_debug = 0;
+  
+  usb_init();
+  usb_find_busses();
+  usb_find_devices();
+  busses = usb_get_busses();
+
+  for (bus = busses; bus; bus = bus->next) {
+    for (dev = bus->devices; dev; dev = dev->next) {
+      if (dev->descriptor.idVendor != LCD_USB_VENDOR) continue;
+      /* Loop through all of the configurations */
+      int c;
+      for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
+	int i;
+	for (i = 0; i < dev->config[c].bNumInterfaces; i++) {
+	  int a;
+	  for (a = 0; a < dev->config[c].interface[i].num_altsetting; a++) {
+	    if ((dev->descriptor.idProduct == LCD_USB_DEVICE) ||
+		((dev->config[c].interface[i].altsetting[a].bInterfaceClass == 0xff) && 
+		 (dev->config[c].interface[i].altsetting[a].bInterfaceSubClass == 0x01))) {
+	      info ("%s: found BWCT USB LCD on bus %s device %s", Name, bus->dirname, dev->filename);
+	      interface = i;
+	      lcd = usb_open(dev);
+	      if (usb_claim_interface(lcd, interface) < 0) {
+		error ("%s: usb_claim_interface() failed!", Name);
+		return -1;
+	      }
+	      return 0;
+	    }
+	  }
+	}
+      }
+    }
+  }
+  return -1;
+}
+
+
+static int drv_BW_close (void) 
+{
+  usb_release_interface(lcd, interface);
+  usb_close(lcd);
+
+  return 0;
+}
+
+
+static int drv_BW_send (int request, int value)
+{
+  static int errors = 0;
+  
+  if (errors > 20) return -1;
+  
+  if (usb_control_msg(lcd, USB_TYPE_VENDOR, request, value, interface, NULL, 0, 1000) < 0) {
+    error("%s: USB request failed!", Name);
+    if (++errors > 20) {
+      error("%s: too many USB errors, aborting.", Name);
+      got_signal = -1;
+    }
+    return -1;
+  }
+  errors = 0;
+  return 0;
+}
+
+
+static void drv_BW_command (const unsigned char cmd)
+{
+  drv_BW_send (LCD_CMD, cmd);
+}
+
+
+static void drv_BW_clear (void)
+{
+  drv_BW_command (0x01); /* clear display */
+  drv_BW_command (0x03); /* return home */
+}
+
+
+static void drv_BW_write (const int row, const int col, const char *data, int len)
+{
+  int pos;
+  
+  /* 16x4 Displays use a slightly different layout */
+  if (DCOLS==16 && DROWS==4) {
+    pos = (row%2)*64+(row/2)*16+col;
+  } else {  
+    pos = (row%2)*64+(row/2)*20+col;
+  }
+
+  drv_BW_command (0x80|pos);
+  
+  while (len--) {
+    drv_BW_send (LCD_DATA, *data++);
+  }
+}
+
+static void drv_BW_defchar (const int ascii, const unsigned char *matrix)
+{
+  int i;
+  
+  drv_BW_command (0x40|8*ascii);
+
+  for (i = 0; i < 8; i++) {
+    drv_BW_send (LCD_DATA, *matrix++ & 0x1f);
+  }
+}
+
+
+static int drv_BW_contrast (int contrast)
+{
+  if (contrast <   0) contrast =   0;
+  if (contrast > 255) contrast = 255;
+
+  drv_BW_send (LCD_CONTRAST, contrast);
+
+  return contrast;
+}
+
+  
+static int drv_BW_start (const char *section, const int quiet)
+{
+  int contrast;
+  int rows=-1, cols=-1;
+  char *s;
+
+  s=cfg_get(section, "Size", NULL);
+  if (s==NULL || *s=='\0') {
+    error ("%s: no '%s.Size' entry from %s", Name, section, cfg_source());
+    return -1;
+  }
+  if (sscanf(s,"%dx%d",&cols,&rows)!=2 || rows<1 || cols<1) {
+    error ("%s: bad %s.Size '%s' from %s", Name, section, s, cfg_source());
+    free (s);
+    return -1;
+  }
+  
+  DROWS = rows;
+  DCOLS = cols;
+  
+  if (drv_BW_open() < 0) {
+    error ("%s: could not find a BWCT USB LCD", Name);
+    return -1;
+  }
+
+  /* reset */
+  drv_BW_send (LCD_RESET, 0);
+
+  /* initialize display */
+  drv_BW_command (0x29); /* 8 Bit mode, 1/16 duty cycle, 5x8 font */
+  drv_BW_command (0x08); /* Display off, cursor off, blink off */
+  drv_BW_command (0x0c); /* Display on, cursor off, blink off */
+  drv_BW_command (0x06); /* curser moves to right, no shift */
+
+
+  if (cfg_number(section, "Contrast", 0, 0, 100, &contrast) > 0) {
+    drv_BW_contrast(contrast);
+  }
+
+  drv_BW_clear();        /* clear display */
+  
+  if (!quiet) {
+    char buffer[40];
+    qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS);
+    if (drv_generic_text_greet (buffer, "www.bwct.de")) {
+      sleep (3);
+      drv_BW_clear();
+    }
+  }
+    
+  return 0;
+}
+
+
+/****************************************/
+/***            plugins               ***/
+/****************************************/
+
+static void plugin_contrast (RESULT *result, RESULT *arg1)
+{
+  double contrast;
+  
+  contrast = drv_BW_contrast(R2N(arg1));
+  SetResult(&result, R_NUMBER, &contrast); 
+}
+
+
+/****************************************/
+/***        widget callbacks          ***/
+/****************************************/
+
+
+/* using drv_generic_text_draw(W) */
+/* using drv_generic_text_icon_draw(W) */
+/* using drv_generic_text_bar_draw(W) */
+
+
+/****************************************/
+/***        exported functions        ***/
+/****************************************/
+
+
+/* list models */
+int drv_BW_list (void)
+{
+  printf ("generic");
+  return 0;
+}
+
+
+/* initialize driver & display */
+int drv_BW_init (const char *section, const int quiet)
+{
+  WIDGET_CLASS wc;
+  int asc255bug;
+  int ret;  
+  
+  /* display preferences */
+  XRES  = 5;      /* pixel width of one char  */
+  YRES  = 8;      /* pixel height of one char  */
+  CHARS = 8;      /* number of user-defineable characters */
+  CHAR0 = 0;      /* ASCII of first user-defineable char */
+  GOTO_COST = 2;  /* number of bytes a goto command requires */
+  
+  /* real worker functions */
+  drv_generic_text_real_write   = drv_BW_write;
+  drv_generic_text_real_defchar = drv_BW_defchar;
+
+
+  /* start display */
+  if ((ret=drv_BW_start (section, quiet))!=0)
+    return ret;
+  
+  /* initialize generic text driver */
+  if ((ret=drv_generic_text_init(section, Name))!=0)
+    return ret;
+
+  /* initialize generic icon driver */
+  if ((ret=drv_generic_text_icon_init())!=0)
+    return ret;
+  
+  /* initialize generic bar driver */
+  if ((ret=drv_generic_text_bar_init(0))!=0)
+    return ret;
+  
+  /* add fixed chars to the bar driver */
+  /* most displays have a full block on ascii 255, but some have kind of  */
+  /* an 'inverted P'. If you specify 'asc255bug 1 in the config, this */
+  /* char will not be used, but rendered by the bar driver */
+  cfg_number(section, "asc255bug", 0, 0, 1, &asc255bug);
+  drv_generic_text_bar_add_segment (  0,  0,255, 32); /* ASCII  32 = blank */
+  if (!asc255bug) 
+    drv_generic_text_bar_add_segment (255,255,255,255); /* ASCII 255 = block */
+  
+  /* register text widget */
+  wc=Widget_Text;
+  wc.draw=drv_generic_text_draw;
+  widget_register(&wc);
+  
+  /* register icon widget */
+  wc=Widget_Icon;
+  wc.draw=drv_generic_text_icon_draw;
+  widget_register(&wc);
+  
+  /* register bar widget */
+  wc=Widget_Bar;
+  wc.draw=drv_generic_text_bar_draw;
+  widget_register(&wc);
+  
+  /* register plugins */
+  AddFunction ("LCD::contrast", 1, plugin_contrast);
+
+  return 0;
+}
+
+
+/* close driver & display */
+int drv_BW_quit (const int quiet)
+{
+
+  info("%s: shutting down.", Name);
+  
+  drv_generic_text_quit();
+  
+  /* clear display */
+  drv_BW_clear();
+  
+  /* say goodbye... */
+  if (!quiet) {
+    drv_generic_text_greet ("goodbye!", NULL);
+  }
+  
+  debug ("closing USB connection");
+  drv_BW_close();
+  
+  return (0);
+}
+
+
+DRIVER drv_BWCT = {
+  name: Name,
+  list: drv_BW_list,
+  init: drv_BW_init,
+  quit: drv_BW_quit, 
+};
+
+
diff --git a/drv_USBLCD.c b/drv_USBLCD.c
index 88f5d47..20209cd 100644
--- a/drv_USBLCD.c
+++ b/drv_USBLCD.c
@@ -1,4 +1,4 @@
-/* $Id: drv_USBLCD.c,v 1.15 2004/06/26 12:04:59 reinelt Exp $
+/* $Id: drv_USBLCD.c,v 1.16 2004/09/24 21:41:00 reinelt Exp $
  *
  * new style driver for USBLCD displays
  *
@@ -26,6 +26,9 @@
  *
  *
  * $Log: drv_USBLCD.c,v $
+ * Revision 1.16  2004/09/24 21:41:00  reinelt
+ * new driver for the BWCT USB LCD interface board.
+ *
  * Revision 1.15  2004/06/26 12:04:59  reinelt
  *
  * uh-oh... the last CVS log message messed up things a lot...
@@ -187,7 +190,15 @@ static void drv_UL_clear (void)
 
 static void drv_UL_write (const int row, const int col, const char *data, int len)
 {
-  int pos = (row%2)*64 + (row/2)*20 + col;
+  int pos;
+  
+  /* 16x4 Displays use a slightly different layout */
+  if (DCOLS==16 && DROWS==4) {
+    pos = (row%2)*64+(row/2)*16+col;
+  } else {  
+    pos = (row%2)*64+(row/2)*20+col;
+  }
+
   drv_UL_command (0x80|pos);
 
   while (len--) {
diff --git a/lcd4linux.c b/lcd4linux.c
index 4b92032..0eed8c0 100644
--- a/lcd4linux.c
+++ b/lcd4linux.c
@@ -1,4 +1,4 @@
-/* $Id: lcd4linux.c,v 1.74 2004/06/26 12:04:59 reinelt Exp $
+/* $Id: lcd4linux.c,v 1.75 2004/09/24 21:41:00 reinelt Exp $
  *
  * LCD4Linux
  *
@@ -23,6 +23,9 @@
  *
  *
  * $Log: lcd4linux.c,v $
+ * Revision 1.75  2004/09/24 21:41:00  reinelt
+ * new driver for the BWCT USB LCD interface board.
+ *
  * Revision 1.74  2004/06/26 12:04:59  reinelt
  *
  * uh-oh... the last CVS log message messed up things a lot...
@@ -384,11 +387,10 @@
 static char *release   = "LCD4Linux " VERSION;
 static char *copyright = "Copyright 1999-2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>";
 static char **my_argv;
-static int got_signal=0;
-
-int tick, tack;
 extern char* output;
 
+int got_signal=0;
+
 
 static void usage(void)
 {
diff --git a/lcd4linux.conf.sample b/lcd4linux.conf.sample
index 644a780..9d9acfe 100644
--- a/lcd4linux.conf.sample
+++ b/lcd4linux.conf.sample
@@ -137,6 +137,15 @@ Display USBLCD {
 }
 
 
+Display BWCT {
+    Driver 'BWCT'
+    Size '16x2'
+    Contrast 30
+    asc255bug 1
+    Icons 1
+}
+
+
 Display T6963-240x64 {
     Driver 'T6963'
     Port '/dev/parports/0'
@@ -655,8 +664,8 @@ Layout testMySQL {
 #Display 'MI240'
 #Display 'CW12232'
 #Display 'HD44780-20x4'
-#Display  'SC1602D'
-Display 'LCM-162'
+#Display 'SC1602D'
+#Display 'LCM-162'
 #Display 'CF631'
 #Display 'CF632'
 #Display 'CF633'
@@ -666,6 +675,7 @@ Display 'LCM-162'
 #Display 'T6963-240x64'
 #Display 'XWindow'
 #Display 'USBLCD'
+Display 'BWCT'
 #Display 'Image'
 
 #Layout  'Default'
diff --git a/plugin_exec.c b/plugin_exec.c
index e099433..78850a9 100644
--- a/plugin_exec.c
+++ b/plugin_exec.c
@@ -1,4 +1,4 @@
-/* $Id: plugin_exec.c,v 1.6 2004/06/26 12:05:00 reinelt Exp $
+/* $Id: plugin_exec.c,v 1.7 2004/09/24 21:41:00 reinelt Exp $
  *
  * plugin for external processes
  *
@@ -27,6 +27,9 @@
  *
  *
  * $Log: plugin_exec.c,v $
+ * Revision 1.7  2004/09/24 21:41:00  reinelt
+ * new driver for the BWCT USB LCD interface board.
+ *
  * Revision 1.6  2004/06/26 12:05:00  reinelt
  *
  * uh-oh... the last CVS log message messed up things a lot...
@@ -81,7 +84,7 @@
 
 
 #define NUM_THREADS 16
-#define SHM_SIZE 256
+#define SHM_SIZE 4096
 
 typedef struct {
   int   delay;
-- 
cgit v1.2.3