diff options
author | michael <michael@3ae390bd-cb1e-0410-b409-cd5a39f66f1f> | 2009-02-28 06:19:46 +0000 |
---|---|---|
committer | michael <michael@3ae390bd-cb1e-0410-b409-cd5a39f66f1f> | 2009-02-28 06:19:46 +0000 |
commit | 915154c4eb39dfa4a593d946c3a443a1812cc4ff (patch) | |
tree | 600763f1c4a85bda3d0f35b3c0ea666d34882422 | |
parent | 64522a267dccb2f0dc71d186b084c8c462a28f65 (diff) | |
download | lcd4linux-915154c4eb39dfa4a593d946c3a443a1812cc4ff.tar.gz |
GLCD2USB driver from Till Harbaum
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@987 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
Diffstat (limited to '')
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | config.h.in | 3 | ||||
-rwxr-xr-x | configure | 34 | ||||
-rw-r--r-- | drivers.m4 | 27 | ||||
-rw-r--r-- | drv.c | 4 | ||||
-rw-r--r-- | drv_GLCD2USB.c | 562 | ||||
-rw-r--r-- | lcd4linux.conf.sample | 10 |
8 files changed, 629 insertions, 14 deletions
diff --git a/Makefile.am b/Makefile.am index 1b589d6..8e08f3b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -75,6 +75,7 @@ drv_Cwlinux.c \ drv_D4D.c \ drv_EA232graphic.c \ drv_G15.c \ +drv_GLCD2USB.c \ drv_HD44780.c \ drv_Image.c \ drv_IRLCD.c \ diff --git a/Makefile.in b/Makefile.in index e0d576c..87feaf1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -274,6 +274,7 @@ drv_Cwlinux.c \ drv_D4D.c \ drv_EA232graphic.c \ drv_G15.c \ +drv_GLCD2USB.c \ drv_HD44780.c \ drv_Image.c \ drv_IRLCD.c \ @@ -463,6 +464,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_D4D.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_EA232graphic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_G15.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_GLCD2USB.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_HD44780.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_IRLCD.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_Image.Po@am__quote@ diff --git a/config.h.in b/config.h.in index 6ec9872..cdc6c93 100644 --- a/config.h.in +++ b/config.h.in @@ -449,6 +449,9 @@ /* GD library */ #undef WITH_GD +/* GLCD2USB driver */ +#undef WITH_GLCD2USB + /* HD44780 driver */ #undef WITH_HD44780 @@ -1343,11 +1343,12 @@ Optional Packages: (try 'all,\!<driver>' if your shell complains...) possible drivers are: BeckmannEgle, BWCT, CrystalFontz, Curses, Cwlinux, D4D, - G15, HD44780, IRLCD, LCD2USB LCDLinux, LCDTerm, LPH7508, - LUIse, M50530, MatrixOrbital, MilfordInstruments, Noritake, - NULL, PNG, PPM, Pertelian, PHAnderson, picoLCD, picoLCDGraphic, - RouterBoard, Sample, serdisplib, SimpleLCD, st2205, T6963, Trefon, - ULA200, USBLCD, USBHUB, WincorNixdorf, X11 + G15, GLCD2USB, HD44780, IRLCD, LCD2USB, LCDLinux, LCDTerm, + LPH7508, LUIse, M50530, MatrixOrbital, MilfordInstruments, + Noritake, NULL, PNG, PPM, Pertelian, PHAnderson, picoLCD, + picoLCDGraphic, RouterBoard, Sample, serdisplib, SimpleLCD, + st2205, T6963, Trefon, ULA200, USBLCD, USBHUB, WincorNixdorf + X11 --with-plugins=<list> choose which plugins to compile. type --with-plugins=list for a list of avaible plugins @@ -4447,7 +4448,7 @@ echo "${ECHO_T}Please note that some screen refreshs may fail" >&6; } echo $ECHO_N "checking for ncurses version... $ECHO_C" >&6; } ncurses_version=unknown cat > conftest.$ac_ext <<EOF -#line 4450 "configure" +#line 4451 "configure" #include "confdefs.h" #ifdef RENAMED_NCURSES #include <curses.h> @@ -7694,6 +7695,7 @@ for driver in $drivers; do D4D="yes" EA232graphic="yes" G15="yes" + GLCD2USB="yes" HD44780="yes" IRLCD="yes" LCD2USB="yes" @@ -7750,6 +7752,9 @@ for driver in $drivers; do G15) G15=$val ;; + GLCD2USB) + GLCD2USB=$val + ;; HD44780) HD44780=$val ;; @@ -7987,6 +7992,23 @@ echo "$as_me: WARNING: usb.h not found: G15 driver disabled" >&2;} fi fi +if test "$GLCD2USB" = "yes"; then + if test "$has_usb" = "true"; then + GRAPHIC="yes" + KEYPAD="yes" + DRIVERS="$DRIVERS drv_GLCD2USB.o" + LIBUSB="yes" + +cat >>confdefs.h <<\_ACEOF +#define WITH_GLCD2USB 1 +_ACEOF + + else + { echo "$as_me:$LINENO: WARNING: usb.h not found: GLCD2USB driver disabled" >&5 +echo "$as_me: WARNING: usb.h not found: GLCD2USB driver disabled" >&2;} + fi +fi + if test "$HD44780" = "yes"; then TEXT="yes" PARPORT="yes" @@ -33,11 +33,12 @@ AC_ARG_WITH( [ (try 'all,\!<driver>' if your shell complains...)] [ possible drivers are:] [ BeckmannEgle, BWCT, CrystalFontz, Curses, Cwlinux, D4D,] - [ G15, HD44780, IRLCD, LCD2USB LCDLinux, LCDTerm, LPH7508,] - [ LUIse, M50530, MatrixOrbital, MilfordInstruments, Noritake,] - [ NULL, PNG, PPM, Pertelian, PHAnderson, picoLCD, picoLCDGraphic,] - [ RouterBoard, Sample, serdisplib, SimpleLCD, st2205, T6963, Trefon,] - [ ULA200, USBLCD, USBHUB, WincorNixdorf, X11], + [ G15, GLCD2USB, HD44780, IRLCD, LCD2USB, LCDLinux, LCDTerm,] + [ LPH7508, LUIse, M50530, MatrixOrbital, MilfordInstruments,] + [ Noritake, NULL, PNG, PPM, Pertelian, PHAnderson, picoLCD,] + [ picoLCDGraphic, RouterBoard, Sample, serdisplib, SimpleLCD,] + [ st2205, T6963, Trefon, ULA200, USBLCD, USBHUB, WincorNixdorf] + [ X11], drivers=$withval, drivers=all ) @@ -66,6 +67,7 @@ for driver in $drivers; do D4D="yes" EA232graphic="yes" G15="yes" + GLCD2USB="yes" HD44780="yes" IRLCD="yes" LCD2USB="yes" @@ -122,6 +124,9 @@ for driver in $drivers; do G15) G15=$val ;; + GLCD2USB) + GLCD2USB=$val + ;; HD44780) HD44780=$val ;; @@ -321,6 +326,18 @@ if test "$G15" = "yes"; then fi fi +if test "$GLCD2USB" = "yes"; then + if test "$has_usb" = "true"; then + GRAPHIC="yes" + KEYPAD="yes" + DRIVERS="$DRIVERS drv_GLCD2USB.o" + LIBUSB="yes" + AC_DEFINE(WITH_GLCD2USB,1,[GLCD2USB driver]) + else + AC_MSG_WARN(usb.h not found: GLCD2USB driver disabled) + fi +fi + if test "$HD44780" = "yes"; then TEXT="yes" PARPORT="yes" @@ -55,6 +55,7 @@ extern DRIVER drv_Cwlinux; extern DRIVER drv_D4D; extern DRIVER drv_EA232graphic; extern DRIVER drv_G15; +extern DRIVER drv_GLCD2USB; extern DRIVER drv_HD44780; extern DRIVER drv_Image; extern DRIVER drv_IRLCD; @@ -117,6 +118,9 @@ DRIVER *Driver[] = { #ifdef WITH_G15 &drv_G15, #endif +#ifdef WITH_GLCD2USB + &drv_GLCD2USB, +#endif #ifdef WITH_HD44780 &drv_HD44780, #endif diff --git a/drv_GLCD2USB.c b/drv_GLCD2USB.c new file mode 100644 index 0000000..38a6b31 --- /dev/null +++ b/drv_GLCD2USB.c @@ -0,0 +1,562 @@ +/* $Id$ + * $URL$ + * + * GLCD2USB driver for LCD4Linux + * (see http://www.harbaum.org/till/glcd2usb for hardware) + * + * Copyright (C) 2007 Till Harbaum <till@harbaum.org> + * + * 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. + * + */ + +/* + * + * exported fuctions: + * + * struct DRIVER drv_GLCD2USB + * + */ + +/* + * Options: + */ + +#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/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 "widget_keypad.h" +#include "drv.h" +#include "drv_generic_graphic.h" +#include "drv_generic_keypad.h" + +#define usbDevice usb_dev_handle /* use libusb's device structure */ +#include "usbcalls.h" + +#include "glcd2usb.h" + +/* ------------------------------------------------------------------------- */ + +#define USBRQ_HID_GET_REPORT 0x01 +#define USBRQ_HID_SET_REPORT 0x09 + +usbDevice_t *dev = NULL; + +/* USB message buffer */ +static union { + unsigned char bytes[132]; + display_info_t display_info; +} buffer; + +/* ------------------------------------------------------------------------- */ + + +#define IDENT_VENDOR_NUM 0x0403 +#define IDENT_VENDOR_STRING "www.harbaum.org/till/glcd2usb" +#define IDENT_PRODUCT_NUM 0xc634 +#define IDENT_PRODUCT_STRING "GLCD2USB" + +static char Name[] = IDENT_PRODUCT_STRING; + +/* ------------------------------------------------------------------------- */ + +static int usbGetString(usb_dev_handle * dev, int index, char *buf, int buflen) +{ + char buffer[256]; + int rval, i; + + if ((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, + (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 1000)) < 0) + return rval; + + /* not a string */ + if (buffer[1] != USB_DT_STRING) + return 0; + + /* string would have been longer than buffer is */ + if ((unsigned char) buffer[0] < rval) + rval = (unsigned char) buffer[0]; + + /* 16 bit unicode -> 8 bit ascii */ + rval /= 2; + + /* lossy conversion to ISO Latin1 */ + for (i = 1; i < rval; i++) { + if (i > buflen) /* destination buffer overflow */ + break; + + buf[i - 1] = buffer[2 * i]; + + if (buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ + buf[i - 1] = '?'; + } + + /* terminate string */ + buf[i - 1] = 0; + + return i - 1; +} + +/* ------------------------------------------------------------------------- */ + +int usbOpenDevice(usbDevice_t ** device, int vendor, char *vendorName, int product, char *productName) +{ + struct usb_bus *bus; + struct usb_device *dev; + usb_dev_handle *handle = NULL; + int errorCode = USB_ERROR_NOTFOUND; + static int didUsbInit = 0; + + if (!didUsbInit) { + usb_init(); + didUsbInit = 1; + } + + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_get_busses(); bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) { + char string[256]; + int len; + handle = usb_open(dev); /* we need to open the device in order to query strings */ + if (!handle) { + errorCode = USB_ERROR_ACCESS; + error("%s Warning: cannot open USB device: %s", Name, usb_strerror()); + continue; + } + if (vendorName == NULL && productName == NULL) { /* name does not matter */ + break; + } + /* now check whether the names match: */ + len = usbGetString(handle, dev->descriptor.iManufacturer, string, sizeof(string)); + if (len < 0) { + errorCode = USB_ERROR_IO; + error("%s: Cannot query manufacturer for device: %s", Name, usb_strerror()); + } else { + errorCode = USB_ERROR_NOTFOUND; + if (strcmp(string, vendorName) == 0) { + len = usbGetString(handle, dev->descriptor.iProduct, string, sizeof(string)); + if (len < 0) { + errorCode = USB_ERROR_IO; + fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); + } else { + errorCode = USB_ERROR_NOTFOUND; + if (strcmp(string, productName) == 0) + break; + } + } + } + usb_close(handle); + handle = NULL; + } + } + if (handle) + break; + } + + if (handle != NULL) { + int rval, retries = 3; + if (usb_set_configuration(handle, 1)) { + fprintf(stderr, "Warning: could not set configuration: %s\n", usb_strerror()); + } + /* now try to claim the interface and detach the kernel HID driver on + * linux and other operating systems which support the call. + */ + while ((rval = usb_claim_interface(handle, 0)) != 0 && retries-- > 0) { +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP + if (usb_detach_kernel_driver_np(handle, 0) < 0) { + fprintf(stderr, "Warning: could not detach kernel HID driver: %s\n", usb_strerror()); + } +#endif + } +#ifndef __APPLE__ + if (rval != 0) + fprintf(stderr, "Warning: could not claim interface\n"); +#endif + /* Continue anyway, even if we could not claim the interface. Control transfers + * should still work. + */ + errorCode = 0; + *device = handle; + } + return errorCode; +} + +/* ------------------------------------------------------------------------- */ + +void usbCloseDevice(usbDevice_t * device) +{ + if (device != NULL) + usb_close(device); +} + +/* ------------------------------------------------------------------------- */ + +int usbSetReport(usbDevice_t * device, int reportType, unsigned char *buffer, int len) +{ + int bytesSent; + + /* the write command needs some tweaking regarding allowed report lengths */ + if (buffer[0] == GLCD2USB_RID_WRITE) { + int i = 0, allowed_lengths[] = { 4 + 4, 8 + 4, 16 + 4, 32 + 4, 64 + 4, 128 + 4 }; + + if (len > 128 + 4) + error("%s: %d bytes usb report is too long \n", Name, len); + + while (allowed_lengths[i] != (128 + 4) && allowed_lengths[i] < len) + i++; + + len = allowed_lengths[i]; + buffer[0] = GLCD2USB_RID_WRITE + i; + } + + bytesSent = usb_control_msg(device, USB_TYPE_CLASS | USB_RECIP_INTERFACE | + USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT, + reportType << 8 | buffer[0], 0, (char *) buffer, len, 1000); + if (bytesSent != len) { + if (bytesSent < 0) + error("%s: Error sending message: %s", Name, usb_strerror()); + return USB_ERROR_IO; + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +int usbGetReport(usbDevice_t * device, int reportType, int reportNumber, unsigned char *buffer, int *len) +{ + *len = usb_control_msg(device, USB_TYPE_CLASS | USB_RECIP_INTERFACE | + USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT, + reportType << 8 | reportNumber, 0, (char *) buffer, *len, 1000); + if (*len < 0) { + error("%s: Error sending message: %s", Name, usb_strerror()); + return USB_ERROR_IO; + } + return 0; +} + +char *usbErrorMessage(int errCode) +{ + static char buffer[80]; + + switch (errCode) { + case USB_ERROR_ACCESS: + return "Access to device denied"; + case USB_ERROR_NOTFOUND: + return "The specified device was not found"; + case USB_ERROR_BUSY: + return "The device is used by another application"; + case USB_ERROR_IO: + return "Communication error with device"; + default: + sprintf(buffer, "Unknown USB error %d", errCode); + return buffer; + } + return NULL; /* not reached */ +} + +static char *video_buffer = NULL; +static char *dirty_buffer = NULL; + +static void drv_GLCD2USB_blit(const int row, const int col, const int height, const int width) +{ + int r, c, err, i, j; + + /* update offscreen buffer */ + for (r = row; r < row + height; r++) { + for (c = col; c < col + width; c++) { + int x, y, bit; + + /* these assignments are display layout dependent */ + x = c; + y = r / 8; + bit = r % 8; + + i = video_buffer[x + DCOLS * y]; + + if (drv_generic_graphic_black(r, c)) + video_buffer[x + DCOLS * y] |= 1 << bit; + else + video_buffer[x + DCOLS * y] &= ~(1 << bit); + + if (video_buffer[x + DCOLS * y] != i) + dirty_buffer[x + DCOLS * y] |= 1 << bit; + } + } + +#if 0 + /* display what's in the buffer (for debugging) */ + for (r = 0; r < DROWS; r++) { + for (c = 0; c < DCOLS; c++) { + if (video_buffer[c + DCOLS * (r / 8)] & (1 << (r % 8))) + putchar('#'); + else + putchar(' '); + } + putchar('\n'); + } +#endif + + /* short gaps of unchanged bytes in fact increase the communication */ + /* overhead. so we eliminate them here */ + for (j = -1, i = 0; i < DROWS * DCOLS / 8; i++) { + if (dirty_buffer[i] && j >= 0 && i - j <= 4) { + /* found a clean gap <= 4 bytes: mark it dirty */ + for (r = j; r < i; r++) + dirty_buffer[r] = 1; + } + + /* if this is dirty, drop the saved position */ + if (dirty_buffer[i]) + j = -1; + + /* save position of this clean entry if there's no position saved yet */ + if (!dirty_buffer[i] && j < 0) + j = i; + } + + /* and do the actual data transmission */ + buffer.bytes[0] = 0; + for (i = 0; i < DROWS * DCOLS / 8; i++) { + if (dirty_buffer[i]) { + /* starting a new run? */ + if (!buffer.bytes[0]) { + buffer.bytes[0] = GLCD2USB_RID_WRITE; + buffer.bytes[1] = i % 256; // offset + buffer.bytes[2] = i / 256; + buffer.bytes[3] = 0; // length + } + buffer.bytes[4 + buffer.bytes[3]++] = video_buffer[i]; + } + + /* this part of the buffer is not dirty or we are at end */ + /* of buffer or the buffer is fill: send data then */ + if ((!dirty_buffer[i]) || (i == DROWS * DCOLS / 8 - 1) || (buffer.bytes[3] == 128)) { + /* is there data to be sent in the buffer? */ + if (buffer.bytes[0] && buffer.bytes[3]) { + if ((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, buffer.bytes[3] + 4)) != 0) + error("%s: Error sending display contents: %s", Name, usbErrorMessage(err)); + + buffer.bytes[0] = 0; + } + } + + /* this entry isn't dirty anymore */ + dirty_buffer[i] = 0; + } +} + +static int drv_GLCD2USB_start(const char *section) +{ + char *s; + int err = 0, len; + + if (sscanf(s = cfg_get(section, "font", "6x8"), "%dx%d", &XRES, &YRES) != 2 || XRES < 1 || YRES < 1) { + error("%s: bad %s.Font '%s' from %s", Name, section, s, cfg_source()); + free(s); + return -1; + } + free(s); + + if ((err = usbOpenDevice(&dev, IDENT_VENDOR_NUM, IDENT_VENDOR_STRING, + IDENT_PRODUCT_NUM, IDENT_PRODUCT_STRING)) != 0) { + error("%s: opening GLCD2USB device: %s", Name, usbErrorMessage(err)); + return -1; + } + + info("%s: Found device", Name); + + /* query display parameters */ + memset(&buffer, 0, sizeof(buffer)); + + len = sizeof(display_info_t); + if ((err = usbGetReport(dev, USB_HID_REPORT_TYPE_FEATURE, GLCD2USB_RID_GET_INFO, buffer.bytes, &len)) != 0) { + + error("%s: query display parameters: %s", Name, usbErrorMessage(err)); + usbCloseDevice(dev); + return -1; + } + + if (len < (int) sizeof(buffer.display_info)) { + error("%s: Not enough bytes in display info report (%d instead of %d)", + Name, len, (int) sizeof(buffer.display_info)); + usbCloseDevice(dev); + return -1; + } + + info("%s: display name = %s", Name, buffer.display_info.name); + info("%s: display resolution = %d * %d", Name, buffer.display_info.width, buffer.display_info.height); + info("%s: display flags: %x", Name, buffer.display_info.flags); + + /* TODO: check for supported features */ + + + /* save display size */ + DCOLS = buffer.display_info.width; + DROWS = buffer.display_info.height; + + /* allocate a offscreen buffer */ + video_buffer = malloc(DCOLS * DROWS / 8); + dirty_buffer = malloc(DCOLS * DROWS / 8); + memset(video_buffer, 0, DCOLS * DROWS / 8); + memset(dirty_buffer, 0, DCOLS * DROWS / 8); + + /* get access to display */ + buffer.bytes[0] = GLCD2USB_RID_SET_ALLOC; + buffer.bytes[1] = 1; /* 1=alloc, 0=free */ + if ((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, 2)) != 0) { + error("%s: Error allocating display: %s", Name, usbErrorMessage(err)); + usbCloseDevice(dev); + return -1; + } + + return 0; +} + + + +/****************************************/ +/*** plugins ***/ +/****************************************/ + +/* none at the moment... */ + + +/****************************************/ +/*** widget callbacks ***/ +/****************************************/ + + +/* using drv_generic_graphic_draw(W) */ +/* using drv_generic_graphic_icon_draw(W) */ +/* using drv_generic_graphic_bar_draw(W) */ + + +/****************************************/ +/*** exported functions ***/ +/****************************************/ + + +/* list models */ +int drv_GLCD2USB_list(void) +{ + printf("generic"); + return 0; +} + +static int drv_GLCD2USB_keypad(const int num) +{ + int val = 0; +#if 0 + /* check for key press event */ + if (num & 0x80) + val = WIDGET_KEY_PRESSED; + else + val = WIDGET_KEY_RELEASED; + + if ((num & 0x7f) == 0) + val += WIDGET_KEY_UP; + + if ((num & 0x7f) == 1) + val += WIDGET_KEY_DOWN; +#endif + return val; +} + +/* initialize driver & display */ +int drv_GLCD2USB_init(const char *section, const __attribute__ ((unused)) + int quiet) +{ + int ret; + + info("%s: %s", Name, "$Rev$"); + + /* real worker functions */ + drv_generic_graphic_real_blit = drv_GLCD2USB_blit; + drv_generic_keypad_real_press = drv_GLCD2USB_keypad; + + /* start display */ + if ((ret = drv_GLCD2USB_start(section)) != 0) + return ret; + + /* initialize generic graphic driver */ + if ((ret = drv_generic_graphic_init(section, Name)) != 0) + return ret; + + /* register plugins */ + /* none at the moment... */ + + + return 0; +} + + +/* close driver & display */ +int drv_GLCD2USB_quit(const __attribute__ ((unused)) + int quiet) +{ + int err; + + info("%s: shutting down.", Name); + drv_generic_graphic_quit(); + + /* release access to display */ + + buffer.bytes[0] = GLCD2USB_RID_SET_ALLOC; + buffer.bytes[1] = 0; /* 1=alloc, 0=free */ + if ((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, 2)) != 0) { + error("%s Error freeing display: %s", Name, usbErrorMessage(err)); + } + + /* clean up */ + if (dev != NULL) + usbCloseDevice(dev); + + if (video_buffer != NULL) { + free(video_buffer); + free(dirty_buffer); + } + + return (0); +} + + +DRIVER drv_GLCD2USB = { + .name = Name, + .list = drv_GLCD2USB_list, + .init = drv_GLCD2USB_init, + .quit = drv_GLCD2USB_quit, +}; diff --git a/lcd4linux.conf.sample b/lcd4linux.conf.sample index 3426450..090e3a7 100644 --- a/lcd4linux.conf.sample +++ b/lcd4linux.conf.sample @@ -55,6 +55,9 @@ Display LCD2USB { Icons 1 } +Display GLCD2USB { + Driver 'GLCD2USB' +} Display LCD2041 { Driver 'MatrixOrbital' @@ -1237,15 +1240,16 @@ Layout Debug { #Display 'LPH7508-serdisplib' #Display 'LPH7508' #Display 'ctinclud' -Display 'picoLCD' +#Display 'picoLCD' +Display 'GLCD2USB' #Layout 'Default' -#Layout 'TestLayer' +Layout 'TestLayer' #Layout 'TestImage' #Layout 'L8x2' #Layout 'L16x1' #Layout 'L16x2' -Layout 'L20x2' +#Layout 'L20x2' #Layout 'L40x2' #Layout 'Test' #Layout 'Test2' |