diff options
Diffstat (limited to 'abs/extra-testing')
| -rw-r--r-- | abs/extra-testing/lcdproc/PKGBUILD | 29 | ||||
| -rwxr-xr-x | abs/extra-testing/lcdproc/lcdd | 38 | ||||
| -rw-r--r-- | abs/extra-testing/lcdproc/lcdproc-add-serdisplib | 1353 | 
3 files changed, 1420 insertions, 0 deletions
| diff --git a/abs/extra-testing/lcdproc/PKGBUILD b/abs/extra-testing/lcdproc/PKGBUILD new file mode 100644 index 0000000..6619eb9 --- /dev/null +++ b/abs/extra-testing/lcdproc/PKGBUILD @@ -0,0 +1,29 @@ +# Contributor: Bernhard Walle <bernhard.walle@gmx.de> +pkgname=lcdproc +pkgver=0.5.2 +pkgrel=0 +pkgdesc="LCDproc is a utility to drive one or more LCD (and LCD-like) devices attached to a host." +url="http://lcdproc.omnipotent.net/" +license="GPL" +depends=(libusb serdisplib libftdi autoconf automake lirc libnxml libmrss pkgconfig) +backup=(etc/LCDd.conf) +arch=(i686 x86_64) +source=(http://switch.dl.sourceforge.net/sourceforge/$pkgname/$pkgname-$pkgver.tar.gz +        lcdd +        lcdproc-add-serdisplib +        ) +md5sums=('860f192d061d87dda6512b11b79daac2' +         '56f52dcccd6e129a9cf84cd1a0452d56' +         '274322642740ad323c43ec5d324519d4') + +build() { +  cd $startdir/src/$pkgname-$pkgver +  patch -p1 < ../lcdproc-add-serdisplib +  autoreconf +  ./configure --prefix=/usr --sysconfdir=/etc --enable-libusb --enable-lcdproc-menus --enable-stat-smbfs --enable-drivers=all +  make +  make DESTDIR=$startdir/pkg install +  sed -e "s/server\/drivers\//\/usr\/lib\/lcdproc\//g" LCDd.conf > $startdir/pkg/etc/LCDd.conf +  mkdir -p $startdir/pkg/etc/rc.d +  install -m 755 $startdir/src/lcdd $startdir/pkg/etc/rc.d +} diff --git a/abs/extra-testing/lcdproc/lcdd b/abs/extra-testing/lcdproc/lcdd new file mode 100755 index 0000000..a124c00 --- /dev/null +++ b/abs/extra-testing/lcdproc/lcdd @@ -0,0 +1,38 @@ +#!/bin/bash + +. /etc/rc.conf +. /etc/rc.d/functions + +PID=`pidof -o %PPID /usr/sbin/LCDd` +case "$1" in +  start) +    stat_busy "Starting LCDd daemon" +    [ -z "$PID" ] && /usr/sbin/LCDd -c /etc/LCDd.conf +    if [ $? -gt 0 ]; then +      stat_fail +    else +      echo $PID > /var/run/lcdd.pid +      add_daemon lcdd +      stat_done +    fi +    ;; +  stop) +    stat_busy "Stopping LCDd daemon" +    [ ! -z "$PID" ]  && kill $PID &> /dev/null +    if [ $? -gt 0 ]; then +      stat_fail +    else +      rm /var/run/lcdd.pid +      rm_daemon lcdd +      stat_done +    fi +    ;; +  restart) +    $0 stop +    sleep 1 +    $0 start +    ;; +  *) +    echo "usage: $0 {start|stop|restart}"   +esac +exit 0 diff --git a/abs/extra-testing/lcdproc/lcdproc-add-serdisplib b/abs/extra-testing/lcdproc/lcdproc-add-serdisplib new file mode 100644 index 0000000..48d239a --- /dev/null +++ b/abs/extra-testing/lcdproc/lcdproc-add-serdisplib @@ -0,0 +1,1353 @@ +[PATCH] Add serdisplib driver + +This patch adds a serdisplib driver for the serdisplib library +(http://serdisplib.sf.net) that is used for low-level accessing of dot-matrix +devices (i.e. such displays that are drived by pixel and not by characters +unlike HD44780, for example). + +I know there's already glcdlib. But that approach has several disadvantages: + +  o Unnecessary library dependencies. +  o Complicated installation, i.e. you have to edit two configuration files. +  o Too much redraws. In fact, that was the reason for me to write this +    driver because my ctinclud display (http://www.ct-maeusekino.de) was quite +    unusable with the glcdlib driver. The problem is simply that lcdproc +    redraws the whole screen each second and it's the task of the driver +    to not to redraw it in reality. The problem is now that the glcdproc +    driver only has the view of characters, and cannot decide which pixels it +    actually has to redraw. And graphlcd which has the per-pixel view doesn't +    do that "caching" and simply redraws all. Of course, that _can_ +    be changed in graphlcd, but I'm sure that leads to endless discussions and +    because I didn't like the glcdlib -> graphlcd -> serdisplib approach +    anyway, I decided to write that driver. + +Some important design decisions: + + o The driver is split into lcdgraphic.c and serdisplib.c. All function that +   do the character -> pixel "rendering" are split out into lcdgraphic.c, +   so it would be possible to write another low-level driver that uses that +   function. However, in normal cases it makes more sense to add that part to +   serdisplib. + o It only requires FreeType (http://freetype.sf.net) for font rendering. +   That's no new real dependency because in almost all cases, graphlcd was +   compiled with FreeType support. + o Only mono space fonts are supported. + o The driver implements symbols (arrow, etc.) using Unicode characters of the +   font. (The recommended font is Andale Mono which is available for free +   from http://corefonts.sf.net) + o Works on i686 and x86_64. + +Please review. The patch is against 0.5.2. If you consider to add this into +CVS, I'll provide documentation. And this time, I'll provide the documentation +in time unlike with the ula200 driver. ;-) + + +Signed-off-by: Bernhard Walle <bernhard.walle@gmx.de> + +--- + LCDd.conf                   |   28 ++ + acinclude.m4                |   27 +- + server/drivers/Makefile.am  |    5  + server/drivers/lcdgraphic.c |  590 ++++++++++++++++++++++++++++++++++++++++++++ + server/drivers/lcdgraphic.h |  195 ++++++++++++++ + server/drivers/serdisplib.c |  379 ++++++++++++++++++++++++++++ + 6 files changed, 1220 insertions(+), 4 deletions(-) + +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -10,13 +10,13 @@ AC_ARG_ENABLE(drivers, + 	[                    irman,joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,] + 	[                    mtc_s16209x,MtxOrb,NoritakeVFD,picolcd,pyramid,sed1330] + 	[                    sed1520,serialPOS,serialVFD,sli,stv5730,svga,t6963,text,] +-	[                    tyan,ula200,xosd] ++	[                    tyan,ula200,serdisplib,xosd] + 	[                  'all' compiles all drivers;] + 	[                  'all,!xxx,!yyy' de-selects previously selected drivers], + 	drivers="$enableval", + 	drivers=[bayrad,CFontz,CFontz633,curses,CwLnx,glk,lb216,lcdm001,MtxOrb,pyramid,text]) +  +-allDrivers=[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,mtc_s16209x,MtxOrb,NoritakeVFD,picolcd,pyramid,sed1330,sed1520,serialPOS,serialVFD,sli,stv5730,svga,t6963,text,tyan,ula200,xosd] ++allDrivers=[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,mtc_s16209x,MtxOrb,NoritakeVFD,picolcd,pyramid,sed1330,sed1520,serialPOS,serialVFD,sli,stv5730,svga,t6963,text,tyan,ula200,serdisplib,xosd] +  + drivers=`echo $drivers | sed -e 's/,/ /g'` +  +@@ -383,6 +383,29 @@ dnl			else + 				AC_MSG_WARN([The ula200 driver needs ftdi.h and usb.h]) + 			]) + 			;; ++                serdisplib) ++                        LIBFREETYPE_CFLAGS=`pkg-config --cflags freetype2` ++                        LIBFREETYPE_LIBS=`pkg-config --libs freetype2` ++                        if test x"$LIBFREETYPE_CFLAGS" = "x" ; then ++                                AC_MSG_WARN([The serdisplib driver needs freetype2]) ++                        fi ++ ++                        AC_CHECK_HEADERS([serdisplib/serdisp.h],[ ++                                AC_CHECK_LIB(serdisp, serdisp_nextdisplaydescription,[ ++                                        LIBSERDISP="-lserdisp" ++                                        DRIVERS="$DRIVERS serdisplib${SO}" ++                                        actdrivers=["$actdrivers serdisplib"] ++                                ],[ ++                                        AC_MSG_WARN([The serdisplib driver needs serdisplib]) ++                                ]) ++                        ],[ ++                                AC_MSG_WARN([The serdisplib driver needs serdislib/serdisp.h]) ++                        ]) ++ ++                        AC_SUBST(LIBFREETYPE_CFLAGS) ++                        AC_SUBST(LIBFREETYPE_LIBS) ++                        AC_SUBST(LIBSERDISP) ++                        ;; + 		xosd) + 			AC_CHECK_HEADERS([xosd.h],[ + 				AC_CHECK_LIB(xosd, main,[ +--- a/server/drivers/Makefile.am ++++ b/server/drivers/Makefile.am +@@ -19,12 +19,13 @@ AM_LDFLAGS = @LDSHARED@ + #LIBS = +  + pkglib_PROGRAMS = @DRIVERS@ +-EXTRA_PROGRAMS = bayrad CFontz CFontz633 CFontzPacket curses CwLnx ea65 EyeboxOne g15 glcdlib glk hd44780 icp_a106 imon IOWarrior irman joy lb216 lcdm001 lcterm lirc MD8800 ms6931 mtc_s16209x MtxOrb NoritakeVFD picolcd pyramid sed1330 sed1520 serialPOS serialVFD stv5730 svga t6963 text tyan sli ula200 xosd ++EXTRA_PROGRAMS = bayrad CFontz CFontz633 CFontzPacket curses CwLnx ea65 EyeboxOne g15 glcdlib glk hd44780 icp_a106 imon IOWarrior irman joy lb216 lcdm001 lcterm lirc MD8800 ms6931 mtc_s16209x MtxOrb NoritakeVFD picolcd pyramid sed1330 sed1520 serialPOS serialVFD stv5730 svga t6963 text tyan sli ula200 serdisplib xosd + noinst_LIBRARIES = libLCD.a libbignum.a +  + IOWarrior_CFLAGS =   @libusb_cflags@ $(AM_CFLAGS) + hd44780_CFLAGS =     @libusb_cflags@ $(AM_CFLAGS) + g15_CFLAGS =         @libusb_cflags@ $(AM_CFLAGS) ++serdisplib_CFLAGS =  @LIBFREETYPE_CFLAGS@ $(AM_CFLAGS) +  + CFontz_LDADD =       libLCD.a libbignum.a + CFontz633_LDADD =    libLCD.a libbignum.a +@@ -53,6 +54,7 @@ svga_LDADD =         @LIBSVGA@ + t6963_LDADD =        libLCD.a + tyan_LDADD =         libLCD.a libbignum.a + ula200_LDADD =       libLCD.a @LIBFTDI@ ++serdisplib_LDADD =   libLCD.a @LIBSERDISP@ @LIBFREETYPE_LIBS@ + sli_LDADD =          libLCD.a + xosd_LDADD =         @LIBXOSD@ +  +@@ -99,6 +101,7 @@ t6963_SOURCES =      lcd.h lcd_lib.h t69 + text_SOURCES =       lcd.h text.h text.c report.h + tyan_SOURCES =       lcd.h lcd_lib.h tyan_lcdm.h tyan_lcdm.c report.h adv_bignum.h + ula200_SOURCES =     lcd.h lcd_lib.h ula200.h ula200.c report.h ++serdisplib_SOURCES = lcd.h serdisplib.h serdisplib.c lcdgraphic.c lcdgraphic.h + sli_SOURCES =        lcd.h lcd_lib.h wirz-sli.h wirz-sli.c report.h + xosd_SOURCES =       lcd.h xosdlib_drv.c xosdlib_drv.h report.h +  +--- /dev/null ++++ b/server/drivers/lcdgraphic.c +@@ -0,0 +1,590 @@ ++// Description: ++ ++/*  Copyright (C) 2007 Bernhard Walle <bernhard.walle@gmx.de> ++ ++    This program 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 of the License, or ++    any later version. ++ ++    This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ ++ ++#include <stdlib.h> ++#include <stdio.h> ++#include <unistd.h> ++#include <termios.h> ++#include <fcntl.h> ++#include <string.h> ++#include <errno.h> ++#include <limits.h> ++#include <syslog.h> ++#include <stdint.h> ++ ++#include "lcdgraphic.h" ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Defines ++ ++#undef report ++#define lcdgr_report    lcdgr->drv->report ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Returns the value of a pixel in the new_buffer buffer. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// @param x         the x location of the pixel ++// @param y         the y location of the pixel ++// ++// @return the value of the pixel ++// ++static inline int get_pixel_new(struct lcdgraphic *lcdgr, int x, int y) ++{ ++    if (x >= lcdgr->width || y >= lcdgr->height) ++        return -1; ++    else ++        return lcdgr->new_buffer[lcdgr->width * y + x]; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Returns the value of a pixel in the disp_buffer buffer. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// @param x         the x location of the pixel ++// @param y         the y location of the pixel ++// ++// @return the value of the pixel ++// ++static inline int get_pixel_disp(struct lcdgraphic *lcdgr, int x, int y) ++{ ++    if (x >= lcdgr->width || y >= lcdgr->height) ++        return -1; ++    else ++        return lcdgr->disp_buffer[lcdgr->width * y + x]; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Sets the value of a pixel in the new_buffer buffer. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// @param x         the x location of the pixel ++// @param y         the y location of the pixel ++// @param value     the value to which the buffer should be set ++// ++static void set_pixel_new(struct lcdgraphic *lcdgr, int x, int y, int value) ++{ ++    if (x < lcdgr->width && y < lcdgr->height) ++        lcdgr->new_buffer[lcdgr->width * y + x] = value; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Sets the value of a pixel in the disp_buffer buffer. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// @param x         the x location of the pixel ++// @param y         the y location of the pixel ++// @param value     the value to which the buffer should be set ++// ++static void set_pixel_disp(struct lcdgraphic *lcdgr, int x, int y, int value) ++{ ++    if (x < lcdgr->width && y < lcdgr->height) ++        lcdgr->disp_buffer[lcdgr->width * y + x] = value; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Maps a lcdproc icon to a unicode code for an icon. ++// ++// @param icon      the lcdproc icon constant ++// ++// @return Unicode value ++// ++static int icon2unicode(int icon) ++{ ++    switch (icon) { ++        case ICON_BLOCK_FILLED: ++            return UNICODE_BLOCK_FILLED; ++        case ICON_HEART_FILLED: ++            return UNICODE_HEART_FILLED; ++        case ICON_HEART_OPEN: ++            return UNICODE_HEART_OPEN; ++        case ICON_ARROW_UP: ++            return UNICODE_ARROW_UP; ++        case ICON_ARROW_DOWN: ++            return UNICODE_ARROW_DOWN; ++        case ICON_ARROW_LEFT: ++            return UNICODE_ARROW_LEFT; ++        case ICON_ARROW_RIGHT: ++            return UNICODE_ARROW_RIGHT; ++        case ICON_SELECTOR_AT_LEFT: ++            return UNICODE_SELECTOR_AT_LEFT; ++        case ICON_SELECTOR_AT_RIGHT: ++            return UNICODE_SELECTOR_AT_RIGHT; ++        case ICON_ELLIPSIS: ++            return UNICODE_ELLIPSIS; ++        default: ++            return -1; ++    } ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Initialises the instance ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure (not initialised, ++//                  only allocated ++// @param settings  a pointer to a settings structure, for a description of the ++//                  members, see above ++// @param functions a pointer to the functions structure, for a description of ++//                  the members, see above ++// ++// @return          0 on success, != 0 on failure ++// ++int lcdgraphic_init(struct lcdgraphic              *lcdgr, ++                    struct lcdgraphic_settings     *settings, ++                    struct lcdgraphic_functions    *functions) ++{ ++    int ret; ++ ++    // check the arguments ++    if (!lcdgr || !functions || !settings) { ++        lcdgr_report(RPT_ERR, "lcdgraphic_init: one of the arguments is NULL"); ++        return -EINVAL; ++    } ++ ++    // check functions ++    if (!functions->setpixel || !functions->clear || !functions->flush) { ++        lcdgr_report(RPT_ERR, "lcdgraphic_init: all functions must be valid"); ++        return -EINVAL; ++    } ++ ++    // validation ++    if (settings->cwidth == 0 || settings->cheight == 0) { ++        lcdgr_report(RPT_ERR, "lcdgraphic_init: cwidth / cheight is 0"); ++        return -EINVAL; ++    } ++ ++    // zero all first ++    memset(lcdgr, 0, sizeof(struct lcdgraphic)); ++ ++    // assign some members ++    lcdgr->width = settings->width; ++    lcdgr->height = settings->height; ++    lcdgr->cwidth = settings->cwidth; ++    lcdgr->cheight = settings->cheight; ++    lcdgr->bwidth = settings->bheight; ++    lcdgr->drv = settings->drv; ++    strncpy(lcdgr->normal_font, settings->normal_font, PATH_MAX); ++    lcdgr->normal_font[PATH_MAX-1] = 0; ++    lcdgr->funcs = *functions; ++    lcdgr->all_dirty = 1; ++ ++    // calculate some stuff ++    lcdgr->num_pixels = lcdgr->width * lcdgr->height; ++    lcdgr->xchars = (lcdgr->width - 2*lcdgr->bwidth) / lcdgr->cwidth; ++    lcdgr->ychars = (lcdgr->height - 2*lcdgr->bheight) / lcdgr->cheight; ++ ++    // initialise freetype ++    ret = FT_Init_FreeType(&lcdgr->ft_library); ++    if (ret != 0) { ++        lcdgr_report(RPT_ERR, "Freetype initialisation failed"); ++        goto out; ++    } ++ ++    // load the font face for freetype ++    ret = FT_New_Face(lcdgr->ft_library, lcdgr->normal_font, 0, ++            &lcdgr->ft_normal_font); ++    if (ret != 0) { ++        lcdgr_report(RPT_ERR, "Freetype creation of font '%s' failed", ++                lcdgr->normal_font); ++        goto out; ++    } ++ ++    // allocate the buffers ++    lcdgr->disp_buffer = (int *)malloc(sizeof(int) * lcdgr->num_pixels); ++    if (!lcdgr->disp_buffer) { ++        lcdgr_report(RPT_ERR, "lcdgraphic_init: malloc of disp_buffer failed"); ++        ret = -ENOMEM; ++        goto out; ++    } ++ ++    lcdgr->new_buffer = (int *)malloc(sizeof(int) * lcdgr->num_pixels); ++    if (!lcdgr->new_buffer) { ++        lcdgr_report(RPT_ERR, "lcdgraphic_init: malloc of new_buffer failed"); ++        ret = -ENOMEM; ++        goto out; ++    } ++ ++    // clear buffers initially ++    memset(lcdgr->new_buffer, 0, sizeof(int) * lcdgr->num_pixels); ++    memset(lcdgr->disp_buffer, 0, sizeof(int) * lcdgr->num_pixels); ++ ++    return 0; ++ ++out: ++    if (lcdgr->ft_normal_font) ++        FT_Done_Face(lcdgr->ft_normal_font); ++    if (lcdgr->ft_library) ++        FT_Done_FreeType(lcdgr->ft_library); ++    if (lcdgr->new_buffer) ++        free(lcdgr->new_buffer); ++    if (lcdgr->disp_buffer) ++        free(lcdgr->disp_buffer); ++ ++    return ret; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Destroys the instance ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// ++void lcdgraphic_destroy(struct lcdgraphic *lcdgr) ++{ ++    if (!lcdgr) { ++        lcdgr_report(RPT_ERR, "lcdgraphic_destroy: lcdgr == NULL"); ++        return; ++    } ++ ++    if (lcdgr->ft_normal_font) ++        FT_Done_Face(lcdgr->ft_normal_font); ++    if (lcdgr->ft_library) ++        FT_Done_FreeType(lcdgr->ft_library); ++ ++    free(lcdgr->disp_buffer); ++    free(lcdgr->new_buffer); ++ ++    // allow multiple calls of that function ++    lcdgr->disp_buffer = NULL; ++    lcdgr->new_buffer = NULL; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Returns the number of characters in one line. This function can be used ++// inside the width callback of the display driver. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// ++// @return the number of characters in a line ++// ++int lcdgraphic_width(struct lcdgraphic *lcdgr) ++{ ++    if (!lcdgr) { ++        lcdgr_report(RPT_ERR, "lcdgraphic_destroy: lcdgr == NULL"); ++        return -1; ++    } ++ ++    return lcdgr->xchars; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Returns the number of lines. This function can be used inside the height ++// callback of the display driver. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// ++// @return the number lines ++// ++int lcdgraphic_height(struct lcdgraphic *lcdgr) ++{ ++    if (!lcdgr) { ++        lcdgr_report(RPT_ERR, "lcdgraphic_destroy: lcdgr == NULL"); ++        return -1; ++    } ++ ++    return lcdgr->ychars; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Clears the buffer. Doesn't draw anything. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// ++void lcdgraphic_clear(struct lcdgraphic *lcdgr) ++{ ++    if (!lcdgr) { ++        lcdgr_report(RPT_ERR, "lcdgraphic_destroy: lcdgr == NULL"); ++        return; ++    } ++ ++    memset(lcdgr->new_buffer, 0, sizeof(int) * lcdgr->num_pixels); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Draws a string into the display buffer. This calls lcdgraphic_draw_char() ++// internally. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// @param x         the column (position in characters!) where the character ++//                  should be drawn ++// @param y         the line (position in characters!) where the character ++//                  should be drawn ++// @param str       the string that should be drawn ++// ++void lcdgraphic_draw_string(struct lcdgraphic *lcdgr, int x, int y, char *str) ++{ ++    int i; ++    int num_chars = strlen(str); ++ ++    // check string length ++    if (x + num_chars > lcdgr->xchars) { ++        lcdgr_report(RPT_WARNING, "lcdgraphic_draw_string: %dx%d - %s too long", ++                x, y, str); ++        return; ++    } ++ ++    for (i = 0; i < num_chars; i++) ++        lcdgraphic_draw_char(lcdgr, x + i, y, str[i]); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Draws a Unicode character into the display buffer. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// @param x         the column (position in characters!) where the character ++//                  should be drawn ++// @param y         the line (position in characters!) where the character ++//                  should be drawn ++// @param c         the character that should be drawn (unicode code) ++// @param scale     for big numbers -- the number of cells that the rendered ++//                  string should occupy ++// @param width     the width in characters ++// ++static int lcdgraphic_draw_char_unicode(struct lcdgraphic *lcdgr, ++                                        int               x, ++                                        int               y, ++                                        int               c, ++                                        int               scale, ++                                        int               width) ++{ ++    static int      last_font_size = -1; ++    int             xoffset, yoffset; // in pixel ++    int             err; ++    FT_Bitmap       *bitmap; ++    unsigned char   *bitmap_buf; ++    int             col, row; ++    FT_GlyphSlot    glyph; ++    FT_Face         face; ++    int             cwidth, cheight; ++    int             font_size; ++ ++    face = lcdgr->ft_normal_font; ++    xoffset = lcdgr->bwidth + x*lcdgr->cwidth; ++    yoffset = lcdgr->bheight + y*lcdgr->cheight; ++ ++    // set the font size ++    font_size = lcdgr->cheight * scale; ++    if (last_font_size != font_size) { ++        err = FT_Set_Pixel_Sizes(lcdgr->ft_normal_font, font_size, font_size); ++        if (err != 0) { ++            lcdgr_report(RPT_ERR, "Failed to set pixel size (%dx%x)", ++                    lcdgr->cwidth * scale, lcdgr->cheight * scale); ++            return -1; ++        } ++ ++        last_font_size = font_size; ++    } ++ ++    // load the glyph and render it ++    err = FT_Load_Char(lcdgr->ft_normal_font, c, ++            FT_LOAD_RENDER | FT_LOAD_MONOCHROME); ++    if (err != 0) { ++        lcdgr_report(RPT_WARNING, "lcdgraphic_draw_char: loading char " ++                "'%c' (%d) failed", c, c); ++ ++        return -1; ++    } ++ ++    // clear the rectangle first ++    cwidth = lcdgr->cwidth * width; ++    cheight = lcdgr->cheight * scale; ++    for (col = 0; col < cwidth; col++) ++        for (row = 0; row < cheight; row++) ++            set_pixel_new(lcdgr, xoffset + col, yoffset + row, 0); ++ ++    // set some data elements for convenience ++    glyph = lcdgr->ft_normal_font->glyph; ++    bitmap = &glyph->bitmap; ++    bitmap_buf = bitmap->buffer; ++ ++    // and now copy the pixels ++    for (row = 0; row < bitmap->rows; row++) { ++        for (col = 0; col < bitmap->width; col++) { ++            int bitmap_left = glyph->bitmap_left; ++ ++            if (scale != width) ++                bitmap_left = (cwidth - bitmap->width)/2; ++ ++            set_pixel_new(lcdgr, xoffset + col + bitmap_left, ++                    yoffset + row + lcdgr->cheight + (face->size->metrics.descender >> 6) ++                    - glyph->bitmap_top, ++                    bitmap_buf[col/8] >> (7 - (col % 8)) & 1); ++        } ++        bitmap_buf += bitmap->pitch; ++    } ++ ++    return 0; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Draws a character into the display buffer. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// @param x         the column (position in characters!) where the character ++//                  should be drawn ++// @param y         the line (position in characters!) where the character ++//                  should be drawn ++// @param c         the character that should be drawn ++// ++void lcdgraphic_draw_char(struct lcdgraphic *lcdgr, int x, int y, char c) ++{ ++    if (lcdgraphic_draw_char_unicode(lcdgr, x, y, c & 0xff, 1, 1) != 0) ++        lcdgraphic_draw_char_unicode(lcdgr, x, y, '?', 1, 1); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Draws a big number into the display buffer. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// @param x         the x position ++// @param num       the actual number ++// ++void lcdgraphic_draw_num(struct lcdgraphic *lcdgr, int x, int num) ++{ ++    int y; ++    const int BIG_HEIGHT = 3; ++ ++    if (num < 0 || num > 10) { ++        lcdgr_report(RPT_WARNING, "lcdgraphic_draw_num: num out of range (%d)", num); ++        return; ++    } ++ ++    y = lcdgr->ychars - (lcdgr->ychars - BIG_HEIGHT + 1)/2; ++    if (num == 10) ++        lcdgraphic_draw_char_unicode(lcdgr, x, y, ':', BIG_HEIGHT, 1); ++    else ++        lcdgraphic_draw_char_unicode(lcdgr, x, y, '0' + num, BIG_HEIGHT, BIG_HEIGHT); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Draws an icon (which standard lcdproc icon syntax) ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// @param x         the x position of the icon ++// @param y         the y position of the icon ++// @param icon      the icon constant ++// ++// @return 0 on success, -1 on failure (i.e. the core replaces the icon by a ++//         suitable character ++// ++int lcdgraphic_icon(struct lcdgraphic *lcdgr, int x, int y, int icon) ++{ ++    int unicode; ++ ++    unicode = icon2unicode(icon); ++    if (unicode > 0) ++        return lcdgraphic_draw_char_unicode(lcdgr, x, y, unicode, 1, 1); ++    else ++        return -1; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Draws a horizontal bar ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// @param x         the x position of the bar ++// @param y         the y position of the bar ++// @param len       the maximum length ++// @param promille  the current state ++// @param options ++// ++void lcdgraphic_hbar(struct lcdgraphic  *lcdgr, ++                     int                x, ++                     int                y, ++                     int                len, ++                     int                promille, ++                     int                options) ++{ ++    int startx, midx, endx, starty, endy; ++    int col, row; ++ ++    /* calculate positions */ ++    startx = lcdgr->bwidth + x*lcdgr->cwidth; ++    midx   = startx + promille * (len*lcdgr->cwidth) / 1000; ++    endx   = startx + len*lcdgr->cwidth; ++    starty = lcdgr->bheight + y*lcdgr->cheight; ++    endy   = starty + lcdgr->cheight - 1;  /* don't draw the last line */ ++ ++    for (col = startx; col < endx; col++) ++        for (row = starty; row < endy; row++) ++                set_pixel_new(lcdgr, col, row, col < midx); ++} ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Draws a vertical bar ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// @param x         the x position of the bar ++// @param y         the y position of the bar ++// @param len       the maximum length ++// @param promille  the current state ++// @param options ++// ++void lcdgraphic_vbar(struct lcdgraphic  *lcdgr, ++                     int                x, ++                     int                y, ++                     int                len, ++                     int                promille, ++                     int                options) ++{ ++    int startx, endx, starty, midy, endy; ++    int col, row; ++ ++    /* calculation positions */ ++    startx = lcdgr->bwidth + x*lcdgr->cwidth; ++    endx   = startx + lcdgr->cwidth - 1; /* don't draw the last column */ ++    starty = lcdgr->bheight + (y + 1)*lcdgr->cheight - 1; ++    midy   = starty - promille * (len*lcdgr->cheight) / 1000; ++    endy   = starty - len*lcdgr->cheight; ++ ++    for (col = startx; col < endx; col++) ++        for (row = starty; row > endy; row--) ++            set_pixel_new(lcdgr, col, row, row > midy); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Flushes the output to the display. Uses the provided callback functions ++// of the underlying display. ++// ++// @param lcdgr     a pointer to a valid lcdgraphic structure ++// ++void lcdgraphic_flush(struct lcdgraphic *lcdgr) ++{ ++    int x, y; ++ ++    if (lcdgr->all_dirty) ++        lcdgr->funcs.clear(lcdgr->drv); ++ ++    for (y = 0; y < lcdgr->height; y++) { ++        for (x = 0; x < lcdgr->width; x++) { ++            int val = get_pixel_new(lcdgr, x, y); ++ ++            if (lcdgr->all_dirty || ++                    (val != get_pixel_disp(lcdgr, x, y)) ) { ++                lcdgr->funcs.setpixel(lcdgr->drv, x, y, val); ++                set_pixel_disp(lcdgr, x, y, val); ++            } ++        } ++    } ++ ++    lcdgr->funcs.flush(lcdgr->drv); ++    lcdgr->all_dirty = 0; ++} ++ ++// vimx: set sw=4 ts=4 et: +--- /dev/null ++++ b/server/drivers/lcdgraphic.h +@@ -0,0 +1,195 @@ ++// Description: ++ ++/*  Copyright (C) 2007 Bernhard Walle <bernhard.walle@gmx.de> ++ ++    This program 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 of the License, or ++    any later version. ++ ++    This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ ++ ++#ifndef LCDGRAPHIC_H ++#define LCDGRAPHIC_H ++ ++#include <stdlib.h> ++#include <stdio.h> ++#include <unistd.h> ++#include <termios.h> ++#include <fcntl.h> ++#include <string.h> ++#include <errno.h> ++#include <syslog.h> ++#include <iconv.h> ++ ++#ifdef HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++#include <ft2build.h> ++#include FT_FREETYPE_H ++ ++#include <serdisplib/serdisp.h> ++ ++ ++#include "lcd.h" ++#include "report.h" ++#include "timing.h" ++ ++/////////////////////////////////////////////////////////////////////////////// ++// constants ++// ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Unicode characters ++// ++ ++#define UNICODE_BLOCK_FILLED        0x2588 ++#define UNICODE_HEART_OPEN		    0x2661 ++#define UNICODE_HEART_FILLED	    0x2665 ++#define UNICODE_ARROW_UP		    0x2191 ++#define UNICODE_ARROW_DOWN  	    0x2193 ++#define UNICODE_ARROW_LEFT  	    0x2190 ++#define UNICODE_ARROW_RIGHT         0x2192 ++#define UNICODE_CHECKBOX_OFF        -1          /* -1 == not implemented */ ++#define UNICODE_CHECKBOX_ON         -1 ++#define UNICODE_CHECKBOX_GRAY       -1 ++#define UNICODE_SELECTOR_AT_LEFT    -1 ++#define UNICODE_SELECTOR_AT_RIGHT   -1 ++#define UNICODE_ELLIPSIS            -1 ++ ++/////////////////////////////////////////////////////////////////////////////// ++// These are callback functions that the low level driver must provide ++// ++struct lcdgraphic_functions { ++ ++    // sets the colour of a pixel ++    void (*setpixel)(Driver *drvthis, int x, int y, int pixel); ++ ++    // clears the whole display ++    void (*clear)(Driver *drvthis); ++ ++    // flushes the display ++    void (*flush)(Driver *drvthis); ++}; ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// That structure should be passed by the user, while struct lcdgraphic is ++// entirely private to the library ++struct lcdgraphic_settings { ++ ++    // the width and the height (in number of pixels) of the display ++	int width, height; ++ ++    // the width and the height of one character ++    int cwidth, cheight; ++ ++    // defines unused area on the display (border width / border height) ++    int bwidth, bheight; ++ ++    // that's the cookie that is passed to the callback functions ++    // it's also used for reporting errors ++    Driver *drv; ++ ++    // font file used for normal characters (TTF, must be monospaced) ++    char normal_font[PATH_MAX]; ++}; ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Private structure for drivers that use the functions of that library. ++// Don't access the members by hand here. ++// ++struct lcdgraphic { ++ ++    // --- public members from the structure above ----- ++ ++    // the width and the height (in number of pixels) of the display ++	int width, height; ++ ++    // the width and the height of one character ++    int cwidth, cheight; ++ ++    // defines unused area on the display (border width / border height) ++    int bwidth, bheight; ++ ++    // that's the cookie that is passed to the callback functions ++    // it's also used for reporting errors ++    Driver *drv; ++ ++    // font file used for normal characters (TTF, must be monospaced) ++    char normal_font[PATH_MAX]; ++ ++    // a set of callback functions ++    struct lcdgraphic_functions funcs; ++ ++    // --- private members ----- ++ ++    // the framebuffer that's actually displayed ++    int *disp_buffer; ++ ++    // the buffer that shows the contents of the next update but wasn't ++    // flushed yet ++    int *new_buffer; ++ ++    // (calculated) convenience value because we need that often ++    int num_pixels; ++ ++    // (calculated) number of characters in both directions ++    int xchars, ychars; ++ ++    // all buffers are dirty, i.e. update all ++    int all_dirty; ++ ++    // freetype library handle ++    FT_Library ft_library; ++ ++    // handle for the normal font ++    FT_Face ft_normal_font; ++ ++    // handle for charset convertions ++    iconv_t iconv_handle; ++}; ++ ++// Forward declarations for 'clients' ++ ++int lcdgraphic_init(struct lcdgraphic              *lcdgr, ++                    struct lcdgraphic_settings     *settings, ++                    struct lcdgraphic_functions    *functions); ++ ++int lcdgraphic_width(struct lcdgraphic *lcdgr); ++int lcdgraphic_height(struct lcdgraphic *lcdgr); ++void lcdgraphic_destroy(struct lcdgraphic *lcdgr); ++void lcdgraphic_clear(struct lcdgraphic *lcdgr); ++void lcdgraphic_flush(struct lcdgraphic *lcdgr); ++void lcdgraphic_draw_string(struct lcdgraphic *lcdgr, int x, int y, char *str); ++void lcdgraphic_draw_char(struct lcdgraphic *lcdgr, int x, int y, char c); ++void lcdgraphic_draw_num(struct lcdgraphic *lcdgr, int x, int num); ++int lcdgraphic_icon(struct lcdgraphic *lcdgr, int x, int y, int icon); ++ ++void lcdgraphic_hbar(struct lcdgraphic  *lcdgr, ++                     int                x, ++                     int                y, ++                     int                len, ++                     int                promille, ++                     int                options); ++ ++void lcdgraphic_vbar(struct lcdgraphic  *lcdgr, ++                     int                x, ++                     int                y, ++                     int                len, ++                     int                promille, ++                     int                options); ++ ++#endif /* LCDGRAPHIC_H */ ++ ++// vim: set sw=4 ts=4 et: +--- /dev/null ++++ b/server/drivers/serdisplib.c +@@ -0,0 +1,379 @@ ++// Description: ++ ++/*  Copyright (C) 2007 Bernhard Walle <bernhard.walle@gmx.de> ++ ++    This program 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 of the License, or ++    any later version. ++ ++    This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ ++ ++#include <stdlib.h> ++#include <stdio.h> ++#include <unistd.h> ++#include <termios.h> ++#include <fcntl.h> ++#include <string.h> ++#include <errno.h> ++#include <limits.h> ++#include <syslog.h> ++ ++#include <serdisplib/serdisp.h> ++ ++#ifdef HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++#include "lcd.h" ++#include "report.h" ++#include "timing.h" ++#include "lcdgraphic.h" ++ ++/* Vars for the server core */ ++MODULE_EXPORT char *api_version = API_VERSION; ++MODULE_EXPORT int stay_in_foreground = 0; ++MODULE_EXPORT int supports_multiple = 1; ++MODULE_EXPORT char *symbol_prefix = "serdisplib_"; ++ ++/////////////////////////////////////////////////////////////////////////////// ++// constants ++// ++#define SERDISPLIB_MAX_DISPLAYNAME      32 ++#define SERDISPLIB_MAX_DEVICENAME       PATH_MAX ++ ++/////////////////////////////////////////////////////////////////////////////// ++// private data types ++// ++typedef struct { ++ ++    // the name of the display driver in serdisplib, e.g. 'ctinclud' ++    char display_name[SERDISPLIB_MAX_DISPLAYNAME]; ++ ++    // the name of the device in serdisplib, e.g. /dev/parport0 ++    char display_device[SERDISPLIB_MAX_DEVICENAME]; ++ ++    // the serdisplib connection handle ++    serdisp_CONN_t* serdisplib_conn; ++ ++    // the serdisplib handle ++    serdisp_t *serdisplib; ++ ++    // invert the display ++    int invert; ++ ++    // the lcdgraphic handle ++    struct lcdgraphic *lcdgraphic; ++ ++} PrivateData; ++ ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Callback functions ++// ++ ++static void callback_setpixel(Driver *drvthis, int x, int y, int pixel) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    serdisp_setcolour(p->serdisplib, x, y, pixel ? SD_COL_BLACK : SD_COL_WHITE); ++} ++ ++static void callback_clear(Driver *drvthis) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    serdisp_clearbuffer(p->serdisplib); ++} ++ ++static void callback_flush(Driver *drvthis) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    serdisp_update(p->serdisplib); ++} ++ ++struct lcdgraphic_functions lcdgraphic_functions = { ++    .setpixel       = callback_setpixel, ++    .clear          = callback_clear, ++    .flush          = callback_flush ++}; ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Init the driver and display ++// ++MODULE_EXPORT int ++serdisplib_init(Driver *drvthis) ++{ ++    PrivateData *p; ++    int ret; ++    struct lcdgraphic_settings settings; ++    const char *s; ++ ++    // Alocate and store private data ++    p = (PrivateData *) malloc(sizeof(PrivateData)); ++    if (!p) ++        return -1; ++    if (drvthis->store_private_ptr(drvthis, p)) ++        return -1; ++    memset(p, 0, sizeof(PrivateData)); ++ ++    // get the display name ++    s = drvthis->config_get_string(drvthis->name, "display_name", 0, NULL); ++    if (!s) { ++        report(RPT_ERR, "You must specify display_name in configuration"); ++        goto out; ++    } ++    strncpy(p->display_name, s, SERDISPLIB_MAX_DISPLAYNAME); ++    p->display_name[SERDISPLIB_MAX_DISPLAYNAME-1] = 0; ++ ++    // get the display device ++    s = drvthis->config_get_string(drvthis->name, "display_device", 0, NULL); ++    if (!s) { ++        report(RPT_ERR, "You must specify display_device in configuration"); ++        goto out; ++    } ++    strncpy(p->display_device, s, SERDISPLIB_MAX_DEVICENAME); ++    p->display_device[SERDISPLIB_MAX_DEVICENAME-1] = 0; ++ ++    // get the normal font ++    s = drvthis->config_get_string(drvthis->name, "normal_font", 0, NULL); ++    if (!s) { ++        report(RPT_ERR, "You must specify normal_font in configuration"); ++        goto out; ++    } ++    strncpy(settings.normal_font, s, PATH_MAX); ++    settings.normal_font[PATH_MAX-1] = 0; ++ ++    // character size ++    s = drvthis->config_get_string(drvthis->name, "char_size", 0, "6x10"); ++    if (!s) { ++        report(RPT_ERR, "Could not retrieve char_size from configuration"); ++        goto out; ++    } ++    if (sscanf(s, "%dx%d", &settings.cwidth, &settings.cheight) != 2) { ++        report(RPT_ERR, "Could not scan '%s' correctly", s); ++        goto out; ++    } ++ ++    // border size ++    s = drvthis->config_get_string(drvthis->name, "border_size", 0, "0x0"); ++    if (!s) { ++        report(RPT_ERR, "Could not retrieve border size from configuration"); ++        goto out; ++    } ++    if (sscanf(s, "%dx%d", &settings.bwidth, &settings.bheight) != 2) { ++        report(RPT_ERR, "Could not scan '%s' correctly", s); ++        goto out; ++    } ++ ++    // invert ++    p->invert = drvthis->config_get_bool(drvthis->name, "invert", 0, 1); ++ ++ ++    /* End of config file parsing */ ++ ++    // opening the output device */ ++    p->serdisplib_conn = SDCONN_open(p->display_device); ++    if (!p->serdisplib_conn) { ++        report(RPT_ERR, "Could not open %s: %s", p->display_device, ++                sd_geterrormsg()); ++        goto out; ++    } ++ ++    // opening and initialising the display ++    p->serdisplib = serdisp_init(p->serdisplib_conn, p->display_name, ""); ++    if (!p->serdisplib) { ++        report(RPT_ERR, "Error opening display %s: %s\n", p->display_name, ++                sd_geterrormsg()); ++        goto out; ++    } ++ ++    // invert settings ++    serdisp_setoption(p->serdisplib, "INVERT", p->invert ++            ? SD_OPTION_YES : SD_OPTION_NO); ++ ++    // allocate lcdgraphic handle ++    p->lcdgraphic = (struct lcdgraphic *)malloc(sizeof(struct lcdgraphic)); ++    if (!p->lcdgraphic) { ++        report(RPT_ERR, "Not enough memory to allocate struct lcdgraphic"); ++        goto out; ++    } ++ ++    // register at the lcdgraphic backend ++    settings.width = serdisp_getwidth(p->serdisplib); ++    settings.height = serdisp_getheight(p->serdisplib); ++    settings.drv = drvthis; ++ ++    ret = lcdgraphic_init(p->lcdgraphic, &settings, &lcdgraphic_functions); ++    if (ret != 0) { ++        report(RPT_ERR, "Error registering at lcdgraphic subsystem"); ++        goto out; ++    } ++ ++    return 0; ++ ++out: ++    if (p->serdisplib_conn && !p->serdisplib) ++        SDCONN_close(p->serdisplib_conn); ++    if (p->serdisplib) ++        serdisp_quit(p->serdisplib); ++    drvthis->store_private_ptr(drvthis, NULL); ++    free(p); ++ ++    return -1; ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Clean-up ++// ++MODULE_EXPORT void ++serdisplib_close(Driver *drvthis) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    if (p) { ++        if (p->serdisplib) ++            serdisp_quit(p->serdisplib); ++        if (p->lcdgraphic) ++            lcdgraphic_destroy(p->lcdgraphic); ++    } ++    drvthis->store_private_ptr(drvthis, NULL); ++    free(p); ++} ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Returns the display width ++// ++MODULE_EXPORT int ++serdisplib_width (Driver *drvthis) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    return lcdgraphic_width(p->lcdgraphic); ++} ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Returns the display height ++// ++MODULE_EXPORT int ++serdisplib_height (Driver *drvthis) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    return lcdgraphic_height(p->lcdgraphic); ++} ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Clear the framebuffer ++// ++MODULE_EXPORT void ++serdisplib_clear (Driver *drvthis) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    lcdgraphic_clear(p->lcdgraphic); ++} ++ ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Place a character in the framebuffer ++// ++MODULE_EXPORT void ++serdisplib_chr (Driver *drvthis, int x, int y, char ch) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    lcdgraphic_draw_char(p->lcdgraphic, x - 1, y - 1, ch); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Place a string in the framebuffer ++// ++MODULE_EXPORT void ++serdisplib_string (Driver *drvthis, int x, int y, char *s) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    lcdgraphic_draw_string(p->lcdgraphic, x - 1, y - 1, s); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Place a big number in the framebuffer ++// ++MODULE_EXPORT void ++serdisplib_num (Driver *drvthis, int x, int num) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    lcdgraphic_draw_num(p->lcdgraphic, x - 1, num); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Sets the backlight on or off ++// ++MODULE_EXPORT void ++serdisplib_backlight (Driver *drvthis, int on) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    serdisp_setoption(p->serdisplib, "BACKLIGHT", on ? SD_OPTION_YES : SD_OPTION_NO); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Flush the framebuffer to the display ++// ++MODULE_EXPORT void ++serdisplib_flush(Driver *drvthis) ++{ ++	PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    lcdgraphic_flush(p->lcdgraphic); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Set default icon into a userdef char ++// ++MODULE_EXPORT int ++serdisplib_icon(Driver *drvthis, int x, int y, int icon) ++{ ++    PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    return lcdgraphic_icon(p->lcdgraphic, x - 1, y - 1, icon); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Draws a horizontal bar ++// ++MODULE_EXPORT void ++serdisplib_hbar(Driver *drvthis, int x, int y, int len, int promille, int options) ++{ ++    PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    lcdgraphic_hbar(p->lcdgraphic, x - 1, y - 1, len, promille, options); ++} ++ ++/////////////////////////////////////////////////////////////////////////////// ++// Draws a vertical bar ++// ++MODULE_EXPORT void ++serdisplib_vbar(Driver *drvthis, int x, int y, int len, int promille, int options) ++{ ++    PrivateData *p = (PrivateData *) drvthis->private_data; ++ ++    lcdgraphic_vbar(p->lcdgraphic, x - 1, y - 1, len, promille, options); ++} ++ ++ ++// vim: set sw=4 ts=4 et: +--- a/LCDd.conf ++++ b/LCDd.conf +@@ -40,7 +40,8 @@ + #   EyeboxOne, g15, glcdlib, glk, hd44780, icp_a106, imon, IOWarrior, + #   irman, joy, lb216, lcdm001, lcterm, lirc, MD8800, ms6931, mtc_s16209x, + #   MtxOrb, NoritakeVFD, picolcd, pyramid, sed1330, sed1520, serialPOS, +-#   serialVFD, sli, stv5730, svga, t6963, text, tyan, ula200, xosd ++#   serialVFD, sli, stv5730, svga, t6963, text, tyan, ula200, serdisplib, ++#   xosd + Driver=curses +  + # Tells the driver to bind to the given interface +@@ -931,6 +932,31 @@ Size=20x4 + # KeyMap_E=Enter + # KeyMap_F=Escape +  ++## serdisplib meta-driver for dot-matrix displays ## ++[serdisplib] ++ ++# the underlying serdisplib driver, e.g. ctinclud ++display_name=ctinclud ++ ++# the display device, e.g. serraw:/dev/ttyS0, parport:/dev/parport0 ++# or USB:07c0/1501 (vendor ID, device ID) ++display_device=USB:07c0/1501 ++ ++# the font which is used for rendering, this font must be monospace ++# and should contain some special Unicode characters like arrows ++# (Andale Mono is recommended and can be fetched at ++# http://corefonts.sf.net or from a Windows installation) ++normal_font=/usr/share/fonts/truetype/andalemo.ttf ++ ++# invert the display (black => white, white => black) ++invert=0 ++ ++# the size of one characters, the number of characters is calculated ++# automatically from this and from border_size (see below) ++char_size=6x10 ++ ++# size of the border around the drawing area ++border_size=0 +  +  + ## Wirz SLI LCD driver ## | 
