diff --git a/ChangeLog b/ChangeLog
index 5f9f3ef..a8360bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -17,7 +17,8 @@ v0.5dev (ongoing development)
* Build system: Link LCDd itself with pthread library if available
* lcdproc client: Unbreak build on OpenBSD non-i386 (E. Barrett)
* lcdproc client: Fix core dumps on FreeBSD if started as non-root
- * glcd driver: new connection type 'serdisplib'
+ + glcd driver: new connection type 'serdisplib'
+ + glcd driver: new connection type 'glcd2usb'
v0.5.5
+ sed1330 driver: Add support for HG25504 (L. Lagendijk)
diff --git a/acinclude.m4 b/acinclude.m4
index 03d79cc..6ec6eb5 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -173,6 +173,9 @@ dnl else
if test "$enable_libpng" = yes ; then
GLCD_DRIVERS="$GLCD_DRIVERS glcd-glcd-png.o"
fi
+ if test "$enable_libusb" = yes ; then
+ GLCD_DRIVERS="$GLCD_DRIVERS glcd-glcd-glcd2usb.o"
+ fi
AC_CHECK_HEADERS([serdisplib/serdisp.h],[
AC_CHECK_LIB(serdisp, serdisp_nextdisplaydescription,[
AC_DEFINE(HAVE_SERDISPLIB,[1],[Define to 1 if you have working serdisplib])
diff --git a/docs/lcdproc-user/drivers/glcd.docbook b/docs/lcdproc-user/drivers/glcd.docbook
index c7eb3a0..a52435f 100644
--- a/docs/lcdproc-user/drivers/glcd.docbook
+++ b/docs/lcdproc-user/drivers/glcd.docbook
@@ -25,19 +25,65 @@ system.
Connection type t6963
-TBD
+
+Support for displays using a Toshiba T6863 controller connected to the
+parallel port. Wiring is the same as for the t6963 driver. Refer to
+ for details.
+
+
+If used without FreeType this connection type uses the same font as the
+t6963 driver but draws the characters into the graphic memory of the T6963.
+
+
+You must configure the display for 8x8 font to make this connection type work!
+
Connection type png
-TBD
+
+This connection type writes out the frame buffer into files in /tmp.
+The files are named lcdproc######.png where ######
+is a number starting at 0.
+
+
+As a new file is written on any change to the screen it is best to turn off the
+heartbeat.
+
Connection type serdisplib
-TBD
+
+Use the serdisplib library ()
+for output. This enables use of a number of graphical displays connected to a
+parallel, serial, or USB port. See the serdisplib web page for details,
+especially for available options for your display.
+
+
+Connection type glcd2usb
+
+Support for the glcd2usb device (,
+a graphic LCD to USB converter based on Atmel ATmega16 and the V-USB stack.
+This device features an adjustable backlight and 4 keys. Right now only displays
+with the KS0108 controller are supported.
+
+
+Note that any size setting configured in LCDd.conf is
+ignored as the size reported by the device is used.
+
+
+
+
+
@@ -54,6 +100,7 @@ system.
ConnectionType =
{
t6963 |
+ glcd2usb |
png |
serdisplib
}
diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am
index d3ae447..7de728a 100644
--- a/server/drivers/Makefile.am
+++ b/server/drivers/Makefile.am
@@ -26,7 +26,7 @@ EXTRA_PROGRAMS = bayrad CFontz CFontzPacket curses debug CwLnx ea65 EyeboxOne g1
noinst_LIBRARIES = libLCD.a libbignum.a
g15_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
-glcd_CFLAGS = @FT2_CFLAGS@ @LIBPNG_CFLAGS@ $(AM_CFLAGS)
+glcd_CFLAGS = @FT2_CFLAGS@ @LIBPNG_CFLAGS@ @LIBUSB_CFLAGS@ $(AM_CFLAGS)
hd44780_CFLAGS = @LIBUSB_CFLAGS@ @LIBFTDI_CFLAGS@ $(AM_CFLAGS)
i2500vfd_CFLAGS = @LIBFTDI_CFLAGS@ $(AM_CFLAGS)
IOWarrior_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
@@ -43,7 +43,7 @@ CFontzPacket_LDADD = libLCD.a libbignum.a
curses_LDADD = @LIBCURSES@
CwLnx_LDADD = libLCD.a libbignum.a
g15_LDADD = @LIBG15@
-glcd_LDADD = libLCD.a @GLCD_DRIVERS@ @FT2_LIBS@ @LIBPNG_LIBS@ @LIBSERDISP@
+glcd_LDADD = libLCD.a @GLCD_DRIVERS@ @FT2_LIBS@ @LIBPNG_LIBS@ @LIBSERDISP@ @LIBUSB_LIBS@
glcd_DEPENDENCIES = @GLCD_DRIVERS@ glcd-glcd-render.o
glcdlib_LDADD = @LIBGLCD@
glk_LDADD = libbignum.a
@@ -89,7 +89,7 @@ ea65_SOURCES = lcd.h ea65.h ea65.c report.h
EyeboxOne_SOURCES = lcd.h lcd_lib.h EyeboxOne.c EyeboxOne.h report.h
g15_SOURCES = lcd.h lcd_lib.h g15.h g15-num.c g15.c report.h
glcd_SOURCES = lcd.h report.h glcd_drv.c glcd_drv.h glcd-low.h glcd-drivers.h glcd-render.c glcd-render.h
-EXTRA_glcd_SOURCES = glcd-t6963.c t6963_low.c t6963_low.h glcd-png.c glcd-serdisp.c
+EXTRA_glcd_SOURCES = glcd-t6963.c t6963_low.c t6963_low.h glcd-png.c glcd-serdisp.c glcd-glcd2usb.c glcd-glcd2usb.h
glcdlib_SOURCES = lcd.h lcd_lib.h glcdlib.h glcdlib.c report.h
glk_SOURCES = lcd.h glk.c glk.h glkproto.c glkproto.h report.h
hd44780_SOURCES = lcd.h lcd_lib.h hd44780.h hd44780.c hd44780-drivers.h hd44780-low.h hd44780-charmap.h report.h adv_bignum.h
diff --git a/server/drivers/glcd-drivers.h b/server/drivers/glcd-drivers.h
index 871d6a7..129b1ee 100644
--- a/server/drivers/glcd-drivers.h
+++ b/server/drivers/glcd-drivers.h
@@ -22,12 +22,16 @@ int glcd_png_init(Driver *drvthis);
#ifdef HAVE_SERDISPLIB
int glcd_serdisp_init(Driver *drvthis);
#endif
+#ifdef HAVE_LIBUSB
+int glcd2usb_init(Driver *drvthis);
+#endif
/* symbolic names for connection types */
#define GLCD_CT_UNKNOWN 0
#define GLCD_CT_T6963 1
#define GLCD_CT_PNG 2
#define GLCD_CT_SERDISP 3
+#define GLCD_CT_GLCD2USB 4
/** Structure linking symbolic names to initialization routines */
typedef struct ConnectionMapping {
@@ -51,6 +55,9 @@ static const ConnectionMapping connectionMapping[] = {
#endif
#ifdef HAVE_SERDISPLIB
{"serdisplib", GLCD_CT_SERDISP, glcd_serdisp_init},
+#endif
+#ifdef HAVE_LIBUSB
+ {"glcd2usb", GLCD_CT_GLCD2USB, glcd2usb_init},
#endif
/* default, end of structure element (do not delete) */
{NULL, GLCD_CT_UNKNOWN, NULL}
diff --git a/server/drivers/glcd-glcd2usb.c b/server/drivers/glcd-glcd2usb.c
new file mode 100644
index 0000000..43efbfa
--- /dev/null
+++ b/server/drivers/glcd-glcd2usb.c
@@ -0,0 +1,476 @@
+/** \file server/drivers/glcd-glcd2usb.c
+ * Driver for the glcd2usb device by Till Harbaum, a graphic lcd display
+ * interface based on AVR USB driver. Based on his driver for lcd4linux.
+ *
+ * \note This connection type uses the screen size as reported by the glcd2usb
+ * device. Any size configured in LCDd.conf will be ignored.
+ * \note The glcd2usb with KS108 firmware uses a vertival (aka paged) frame
+ * buffer layout. Other layouts are not supported by this driver.
+ *
+ * \todo Keypad input
+ */
+
+/*-
+ * Copyright (c) 2007 Till Harbaum
+ * 2011 Markus Dolze
+ *
+ * This file is released under the GNU General Public License. Refer to the
+ * COPYING file distributed with this package.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include "lcd.h"
+#include "report.h"
+#include "glcd-low.h"
+#include "glcd-glcd2usb.h"
+
+/* USB Vendor and Product ID used for glcd2usb device */
+#define GLCD2USB_VID 0x1c40
+#define GLCD2USB_PID 0x0525
+
+/* Some useful sortcuts */
+#define PAGES (p->framebuf.px_height / 8)
+#define PAGED_SIZE (p->framebuf.px_width * PAGES)
+
+/** Data local to the glcd2usb connection type */
+typedef struct glcd_glcd2usb_data {
+ usb_dev_handle *device;
+ unsigned char *paged_buffer; /**< frame buffer in paged format */
+ unsigned char *dirty_buffer; /**< buffer indicating changed bytes */
+ union {
+ unsigned char bytes[132];
+ /** when reading this buffer can be accessed as structure */
+ display_info_t display_info;
+ } tx_buffer; /**< buffer to accumulate bytes to be sent */
+} CT_glcd2usb_data;
+
+
+/*-------------------------- USB HID IMPLEMENTATION -----------------------*/
+
+/*
+ * Note: The glcd2usb device implements a HID device. My first try to use
+ * libhid failed, because glcd2usb uses report descriptors that totally confuse
+ * libhid's parser. Therefor we need to roll our own. The code below has been
+ * copied from the lcd4linux implementation of this driver.
+ */
+
+/* Error codes */
+#define USB_ERROR_NONE 0
+#define USB_ERROR_ACCESS 1
+#define USB_ERROR_NOTFOUND 2
+#define USB_ERROR_BUSY 16
+#define USB_ERROR_IO 5
+
+/* HID report types */
+#define USB_HID_REPORT_TYPE_INPUT 1
+#define USB_HID_REPORT_TYPE_OUTPUT 2
+#define USB_HID_REPORT_TYPE_FEATURE 3
+
+/* USB request types */
+#define USBRQ_HID_GET_REPORT 0x01
+#define USBRQ_HID_SET_REPORT 0x09
+
+/**
+ * Sends a 'set report' request to the default control end point of glcd2usb
+ * device. At most 128 bytes may be sent (plus 4 additional control bytes).
+ *
+ * \param device USB device handle of the device to talk to
+ * \param reportType A HID report type
+ * \param buffer Pointer to data to write
+ * \param len Amount of data that shall be written
+ * \return 0 on success, USB_ERROR_IO otherwise
+ */
+static int
+usbSetReport(usb_dev_handle * 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) {
+ const int allowed_lengths[] = {4 + 4, 8 + 4, 16 + 4, 32 + 4, 64 + 4, 128 + 4};
+ int i = 0;
+
+ if (len > 128 + 4)
+ fprintf(stderr, "%d bytes usb report is too long \n", 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)
+ fprintf(stderr, "Error sending message: %s", usb_strerror());
+ return USB_ERROR_IO;
+ }
+ return 0;
+}
+
+
+/**
+ * Sends a 'get report' request to the default control end point of glcd2usb
+ * device. The amout of data read is stored in parameter len.
+ *
+ * \param device USB device handle of the device to talk to
+ * \param reportType A HID report type (input / output / feature)
+ * \param reportNumber The ReportID to be read
+ * \param buffer Pointer to buffer to read the data into. The buffer MUST
+ * be allocated beforehand and be at least of 'len' size.
+ * \param len Pointer to an integer with the number of bytes to read
+ * at most. Upon return, this hold the number of bytes
+ * actually read or -1 if an error occured.
+ * \return 0 on success, USB_ERROR_IO otherwise
+ */
+static int
+usbGetReport(usb_dev_handle * 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) {
+ fprintf(stderr, "Error sending message: %s", usb_strerror());
+ return USB_ERROR_IO;
+ }
+ return 0;
+}
+
+
+/**
+ * Converts an error code into a user readable string.
+ * \param errCode The error code
+ * \return Pointer to error message
+ */
+static 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;
+ }
+ /* NOTREACHED */
+ return NULL;
+}
+
+/*------------------- Connection type functions below ---------------------*/
+
+/**
+ * API: Close device descriptors and free resources
+ */
+void
+glcd2usb_close(PrivateData *p)
+{
+ if (p->ct_data != NULL) {
+ CT_glcd2usb_data *ctd = (CT_glcd2usb_data *) p->ct_data;
+
+ if (ctd->device != 0)
+ usb_close(ctd->device);
+ if (ctd->paged_buffer != NULL)
+ free(ctd->paged_buffer);
+ if (ctd->dirty_buffer != NULL)
+ free(ctd->dirty_buffer);
+ free(ctd);
+ }
+}
+
+
+/**
+ * API: Set the backlight brightness
+ */
+void
+glcd2usb_backlight(PrivateData *p, int state)
+{
+ int err = 0;
+ CT_glcd2usb_data *ctd = (CT_glcd2usb_data *) p->ct_data;
+
+ ctd->tx_buffer.bytes[0] = GLCD2USB_RID_SET_BL;
+ ctd->tx_buffer.bytes[1] = (state == BACKLIGHT_ON) ? p->brightness : p->offbrightness;
+
+ if ((err = usbSetReport(ctd->device, USB_HID_REPORT_TYPE_FEATURE, ctd->tx_buffer.bytes, 2)) != 0) {
+ p->glcd_functions->drv_report(RPT_ERR, "Error freeing display: %s\n", usbErrorMessage(err));
+ }
+}
+
+
+/**
+ * API: Transfer an image to the glcd2usb device. This function and its update
+ * algorithm are copied from the LCD4Linux driver as it does its job well.
+ */
+void
+glcd2usb_blit(PrivateData *p)
+{
+ CT_glcd2usb_data *ctd = (CT_glcd2usb_data *) p->ct_data;
+ int c, r;
+ int i, j;
+ int err;
+
+ p->glcd_functions->drv_debug(RPT_DEBUG, "glcd2usb_blit: starting");
+
+ /* Reset the dirty buffer */
+ memset(ctd->dirty_buffer, 0x00, PAGED_SIZE);
+
+ /*
+ * Step 1: Convert the linear frame buffer format of the glcd driver
+ * into the paged format of the glcd2usb device. Compare newly
+ * written data with what was stored previously and set the dirty
+ * buffer.
+ */
+ for (r = 0; r < p->framebuf.px_height; r++) {
+ int position, bit;
+ unsigned char tmp;
+ for (c = 0; c < p->framebuf.px_width; c++) {
+ position = (r / 8) * p->framebuf.px_width + c;
+ bit = r % 8;
+
+ tmp = ctd->paged_buffer[position];
+
+ if (fb_get_pixel(&(p->framebuf), c, r) == FB_BLACK)
+ ctd->paged_buffer[position] |= 1 << bit;
+ else
+ ctd->paged_buffer[position] &= ~(1 << bit);
+
+ if (ctd->paged_buffer[position] != tmp)
+ ctd->dirty_buffer[position] = 1;
+ }
+ }
+
+ /*
+ * Step 2: Short gaps of unchanged bytes in fact increase the
+ * communication overhead. So we eliminate them here.
+ */
+ for (j = -1, i = 0; i < PAGED_SIZE; i++) {
+ if (ctd->dirty_buffer[i] && j >= 0 && i - j <= 4) {
+ /* found a clean gap <= 4 bytes: mark it dirty */
+ for (r = j; r < i; r++)
+ ctd->dirty_buffer[r] = 1;
+ }
+
+ /* if this is dirty, drop the saved position */
+ if (ctd->dirty_buffer[i])
+ j = -1;
+
+ /* save position of this clean entry if no position saved yet */
+ if (!ctd->dirty_buffer[i] && j < 0)
+ j = i;
+ }
+
+ /* Step 3: Send the changes. */
+ ctd->tx_buffer.bytes[0] = 0;
+ for (i = 0; i < PAGED_SIZE; i++) {
+ if (ctd->dirty_buffer[i]) {
+ /* Start a new packet */
+ if (!ctd->tx_buffer.bytes[0]) {
+ ctd->tx_buffer.bytes[0] = GLCD2USB_RID_WRITE;
+ ctd->tx_buffer.bytes[1] = i % 256;
+ ctd->tx_buffer.bytes[2] = i / 256;
+ ctd->tx_buffer.bytes[3] = 0; /* length */
+ }
+ /* Append the dirty byte and increase size */
+ ctd->tx_buffer.bytes[4 + ctd->tx_buffer.bytes[3]++] = ctd->paged_buffer[i];
+ }
+
+ /*
+ * Send the data if we hit a clean byte, are at the end of
+ * the frame or reached the maximum payload for a write
+ * request.
+ */
+ if (!ctd->dirty_buffer[i] || i == PAGED_SIZE - 1 || ctd->tx_buffer.bytes[3] == 128) {
+ /* Only write if there IS something to be written */
+ if (ctd->tx_buffer.bytes[0] == GLCD2USB_RID_WRITE && ctd->tx_buffer.bytes[3] > 0) {
+ err = usbSetReport(ctd->device, USB_HID_REPORT_TYPE_FEATURE,
+ ctd->tx_buffer.bytes, ctd->tx_buffer.bytes[3] + 4);
+ if (err)
+ p->glcd_functions->drv_report(RPT_ERR, "glcd2usb_blit: error in transfer");
+ /* Start a new packet the next time */
+ ctd->tx_buffer.bytes[0] = 0;
+ }
+ }
+ }
+}
+
+
+/**
+ * API: Initialize glcd2usb connection type.
+ */
+int
+glcd2usb_init(Driver *drvthis)
+{
+ PrivateData *p = (PrivateData *)drvthis->private_data;
+ CT_glcd2usb_data *ctd;
+
+ static int didUsbInit = 0;
+ struct usb_bus *bus;
+ struct usb_device *dev;
+ usb_dev_handle *handle = NULL;
+ int err = 0;
+ int rval, retries = 3;
+ int len;
+
+ /* Set up connection type low-level functions */
+ p->glcd_functions->blit = glcd2usb_blit;
+ p->glcd_functions->close = glcd2usb_close;
+ p->glcd_functions->set_backlight = glcd2usb_backlight;
+
+ /* Allocate memory structures */
+ ctd = (CT_glcd2usb_data *) calloc(1, sizeof(CT_glcd2usb_data));
+ if (ctd == NULL) {
+ report(RPT_ERR, "%s/glcd2usb: error allocating connection data", drvthis->name);
+ return -1;
+ }
+ p->ct_data = ctd;
+
+ ctd->paged_buffer = malloc(PAGED_SIZE);
+ if (ctd->paged_buffer == NULL) {
+ report(RPT_ERR, "%s/glcd2usb: cannot allocate memory", drvthis->name);
+ goto err_out;
+ }
+ memset(ctd->paged_buffer, 0x00, PAGED_SIZE);
+
+ ctd->dirty_buffer = malloc(PAGED_SIZE);
+ if (ctd->dirty_buffer == NULL) {
+ report(RPT_ERR, "%s/glcd2usb: cannot allocate memory", drvthis->name);
+ goto err_out;
+ }
+
+ /*
+ * Try to find and open a device. Only the first device found will be
+ * recognized.
+ */
+ if (!didUsbInit) {
+ usb_init();
+ didUsbInit = 1;
+ }
+
+ usb_find_busses();
+ usb_find_devices();
+
+ for (bus = usb_get_busses(); bus != NULL; bus = bus->next) {
+ for (dev = bus->devices; dev != NULL; dev = dev->next) {
+
+ if (dev->descriptor.idVendor == GLCD2USB_VID
+ && dev->descriptor.idProduct == GLCD2USB_PID) {
+
+ handle = usb_open(dev);
+ if (!handle) {
+ report(RPT_WARNING, "%s/glcd2usb: cannot open USB device: %s",
+ drvthis->name, usb_strerror());
+ continue;
+ }
+ else {
+ goto found_dev;
+ }
+ }
+ }
+ }
+
+found_dev:
+ if (handle) {
+ debug(RPT_DEBUG, "%s/glcd2usb: opening device succeeded", drvthis->name);
+ }
+ else {
+ report(RPT_ERR, "%s/glcd2usb: no GLCD2USB device found", drvthis->name);
+ goto err_out;
+ }
+
+ if (usb_set_configuration(handle, 1))
+ report(RPT_WARNING, "%s/glcd2usb: could not set configuration: %s",
+ drvthis->name, 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) {
+ report(RPT_WARNING, "%s/glcd2usb: could not detach kernel HID driver: %s",
+ drvthis->name, usb_strerror());
+ }
+#endif
+ }
+ if (rval != 0)
+ report(RPT_WARNING, "%s/glcd2usb: could not claim interface", drvthis->name);
+
+ /*
+ * Continue anyway, even if we could not claim the interface. Control
+ * transfers should still work.
+ */
+ ctd->device = handle;
+
+ /* Query device */
+ memset(&(ctd->tx_buffer), 0, sizeof(ctd->tx_buffer));
+ len = sizeof(display_info_t);
+
+ if ((err = usbGetReport(ctd->device, USB_HID_REPORT_TYPE_FEATURE, GLCD2USB_RID_GET_INFO, ctd->tx_buffer.bytes, &len)) != 0) {
+ report(RPT_ERR, "%s/glcd2usb: query display parameters: %s",
+ drvthis->name, usbErrorMessage(err));
+ goto err_out;
+ }
+
+ if (len < (int)sizeof(ctd->tx_buffer.display_info)) {
+ report(RPT_ERR, "%s/glcd2usb: incomplete display info report (%d instead of %d)",
+ drvthis->name, len, (int)sizeof(ctd->tx_buffer.display_info));
+ goto err_out;
+ }
+
+ if (!(ctd->tx_buffer.display_info.flags & FLAG_VERTICAL_UNITS)) {
+ report(RPT_ERR, "%s/glcd2usb: unsupported display layout", drvthis->name);
+ goto err_out;
+ }
+
+ if (ctd->tx_buffer.display_info.width > GLCD_MAX_WIDTH
+ || ctd->tx_buffer.display_info.width <= 0
+ || ctd->tx_buffer.display_info.height > GLCD_MAX_HEIGHT
+ || ctd->tx_buffer.display_info.height <= 0) {
+ report(RPT_ERR, "%s/glcd2usb: display size out of range: %dx%d",
+ drvthis->name, ctd->tx_buffer.display_info.width,
+ ctd->tx_buffer.display_info.height);
+ goto err_out;
+ }
+ else {
+ p->framebuf.px_width = ctd->tx_buffer.display_info.width;
+ p->framebuf.px_height = ctd->tx_buffer.display_info.height;
+ report(RPT_INFO, "%s/glcd2usb: using display size %dx%d", drvthis->name,
+ ctd->tx_buffer.display_info.width, ctd->tx_buffer.display_info.height);
+ }
+
+ /* Allocate the display (turn off the 'screensaver') */
+ ctd->tx_buffer.bytes[0] = GLCD2USB_RID_SET_ALLOC;
+ ctd->tx_buffer.bytes[1] = 1;
+ if ((err = usbSetReport(ctd->device, USB_HID_REPORT_TYPE_FEATURE, ctd->tx_buffer.bytes, 2)) != 0) {
+ report(RPT_ERR, "%s/glcd2usb: Error allocating display: %s",
+ drvthis->name, usbErrorMessage(err));
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ glcd2usb_close(p);
+ return -1;
+}
diff --git a/server/drivers/glcd-glcd2usb.h b/server/drivers/glcd-glcd2usb.h
new file mode 100644
index 0000000..55377a8
--- /dev/null
+++ b/server/drivers/glcd-glcd2usb.h
@@ -0,0 +1,34 @@
+/** \file server/drivers/glcd-glcd2usb.h
+ * glcd2usb interface definitions (flags, report IDs and data structures).
+ */
+
+#ifndef GLCD2USB_H
+#define GLCD2USB_H
+
+#define FLAG_SIX_BIT (1<<0)
+#define FLAG_VERTICAL_UNITS (1<<1)
+#define FLAG_BOTTOM_START (1<<2)
+#define FLAG_VERTICAL_INC (1<<3)
+#define FLAG_BACKLIGHT (1<<4)
+
+#define GLCD2USB_RID_GET_INFO 1 /**< get display info */
+#define GLCD2USB_RID_SET_ALLOC 2 /**< allocate/free display */
+#define GLCD2USB_RID_GET_BUTTONS 3 /**< get state of the four buttons */
+#define GLCD2USB_RID_SET_BL 4 /**< set backlight brightness */
+#define GLCD2USB_RID_GET_IR 5 /**< get last ir message (unused) */
+#define GLCD2USB_RID_WRITE 8 /**< write some bitmap data to the display */
+#define GLCD2USB_RID_WRITE_4 (GLCD2USB_RID_WRITE+0)
+#define GLCD2USB_RID_WRITE_8 (GLCD2USB_RID_WRITE+1)
+#define GLCD2USB_RID_WRITE_16 (GLCD2USB_RID_WRITE+2)
+#define GLCD2USB_RID_WRITE_32 (GLCD2USB_RID_WRITE+3)
+#define GLCD2USB_RID_WRITE_64 (GLCD2USB_RID_WRITE+4)
+#define GLCD2USB_RID_WRITE_128 (GLCD2USB_RID_WRITE+5)
+
+typedef struct {
+ unsigned char report_id;
+ char name[32];
+ unsigned short width, height;
+ unsigned char flags;
+} __attribute__((packed)) display_info_t;
+
+#endif
diff --git a/server/drivers/glcd-render.c b/server/drivers/glcd-render.c
index 156ee70..1c30186 100644
--- a/server/drivers/glcd-render.c
+++ b/server/drivers/glcd-render.c
@@ -59,6 +59,8 @@ glcd_render_init(Driver *drvthis)
p->cellwidth = GLCD_DEFAULT_CELLWIDTH;
p->cellheight = GLCD_DEFAULT_CELLHEIGHT;
+ debug(RPT_DEBUG, "%s: render_init()", drvthis->name);
+
#ifdef HAVE_FT2
int rc;
const char *tmp;
@@ -66,8 +68,6 @@ glcd_render_init(Driver *drvthis)
RenderConfig *rconf;
int w, h;
- debug(RPT_INFO, "%s: render_init: Freetype", drvthis->name);
-
/* Allocate memory structures */
rconf = (RenderConfig *) calloc(1, sizeof(RenderConfig));
if (rconf == NULL) {
@@ -81,6 +81,8 @@ glcd_render_init(Driver *drvthis)
/* Only configure FreeType if enabled */
if (p->use_ft2) {
+ debug(RPT_INFO, "%s: render_init: Using FreeType", drvthis->name);
+
/* get font from config file */
tmp = drvthis->config_get_string(drvthis->name, "normal_font", 0, NULL);
if (tmp == NULL) {