glcd driver updates:
1. Remove connection type header files and put prototypes locally and in glcd-drivers.h. Don't fall into the pitfall of too many header files again. 2. Create a separate frame buffer structure (this allows easier re-use of the frame buffer functions). 3. Add a function to retrieve pixel values from framebuffer. 4. Add the 'serdisplib' connection type. 5. Support display width that are not a multiple of 8 (e.g. 122x32).
This commit is contained in:
@@ -401,6 +401,21 @@ ConnectionType=t6963
|
|||||||
# legal: yes, no]
|
# legal: yes, no]
|
||||||
#delayBus=no
|
#delayBus=no
|
||||||
|
|
||||||
|
# serdisplib: Name of the underlying serdisplib driver, e.g. ctinclud. See
|
||||||
|
# serdisplib documentation for details.
|
||||||
|
serdisp_name=t6963
|
||||||
|
|
||||||
|
# serdisplib: The display device to use, e.g. serraw:/dev/ttyS0,
|
||||||
|
# parport:/dev/parport0 or USB:07c0/1501.
|
||||||
|
serdisp_device=/dev/ppi0
|
||||||
|
|
||||||
|
# serdisplib: Options string to pass to serdisplib during initialization. Use
|
||||||
|
# this to set any display related options (e.g. wiring). The display size is
|
||||||
|
# always set based on the Size configured above! By default, no options are
|
||||||
|
# set.
|
||||||
|
# Important: The value must be quoted as it contains equal signs!
|
||||||
|
#serdisp_options="INVERT=1"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## glcdlib meta driver for graphical LCDs ##
|
## glcdlib meta driver for graphical LCDs ##
|
||||||
|
|||||||
@@ -173,6 +173,16 @@ dnl else
|
|||||||
if test "$enable_libpng" = yes ; then
|
if test "$enable_libpng" = yes ; then
|
||||||
GLCD_DRIVERS="$GLCD_DRIVERS glcd-glcd-png.o"
|
GLCD_DRIVERS="$GLCD_DRIVERS glcd-glcd-png.o"
|
||||||
fi
|
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])
|
||||||
|
LIBSERDISP="-lserdisp"
|
||||||
|
GLCD_DRIVERS="$GLCD_DRIVERS glcd-glcd-serdisp.o"
|
||||||
|
],[
|
||||||
|
AC_MSG_WARN([serdisp library not working])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
AC_SUBST(LIBSERDISP)
|
||||||
DRIVERS="$DRIVERS glcd${SO}"
|
DRIVERS="$DRIVERS glcd${SO}"
|
||||||
actdrivers=["$actdrivers glcd"]
|
actdrivers=["$actdrivers glcd"]
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ CFontzPacket_LDADD = libLCD.a libbignum.a
|
|||||||
curses_LDADD = @LIBCURSES@
|
curses_LDADD = @LIBCURSES@
|
||||||
CwLnx_LDADD = libLCD.a libbignum.a
|
CwLnx_LDADD = libLCD.a libbignum.a
|
||||||
g15_LDADD = @LIBG15@
|
g15_LDADD = @LIBG15@
|
||||||
glcd_LDADD = libLCD.a @GLCD_DRIVERS@ @FT2_LIBS@ @LIBPNG_LIBS@
|
glcd_LDADD = libLCD.a @GLCD_DRIVERS@ @FT2_LIBS@ @LIBPNG_LIBS@ @LIBSERDISP@
|
||||||
glcd_DEPENDENCIES = @GLCD_DRIVERS@ glcd-glcd-render.o
|
glcd_DEPENDENCIES = @GLCD_DRIVERS@ glcd-glcd-render.o
|
||||||
glcdlib_LDADD = @LIBGLCD@
|
glcdlib_LDADD = @LIBGLCD@
|
||||||
glk_LDADD = libbignum.a
|
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
|
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
|
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
|
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 glcd-t6963.h t6963_low.c t6963_low.h glcd-png.c glcd-png.h
|
EXTRA_glcd_SOURCES = glcd-t6963.c t6963_low.c t6963_low.h glcd-png.c glcd-serdisp.c
|
||||||
glcdlib_SOURCES = lcd.h lcd_lib.h glcdlib.h glcdlib.c report.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
|
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
|
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
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/** \file server/drivers/glcd-drivers.h
|
/** \file server/drivers/glcd-drivers.h
|
||||||
* Connection type registry for glcd driver.
|
* Connection type registry for glcd driver.
|
||||||
*
|
*
|
||||||
* File file contains includes and pointers to the connection type's init()
|
* File file contains prototypes and pointers to the connection type's init()
|
||||||
* function.
|
* function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -12,18 +12,22 @@
|
|||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Include connection type header below */
|
/* Include prototypes for initialization functions below */
|
||||||
#ifdef HAVE_PCSTYLE_LPT_CONTROL
|
#ifdef HAVE_PCSTYLE_LPT_CONTROL
|
||||||
# include "glcd-t6963.h"
|
int glcd_t6963_init(Driver *drvthis);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBPNG
|
#ifdef HAVE_LIBPNG
|
||||||
# include "glcd-png.h"
|
int glcd_png_init(Driver *drvthis);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SERDISPLIB
|
||||||
|
int glcd_serdisp_init(Driver *drvthis);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* symbolic names for connection types */
|
/* symbolic names for connection types */
|
||||||
#define GLCD_CT_UNKNOWN 0
|
#define GLCD_CT_UNKNOWN 0
|
||||||
#define GLCD_CT_T6963 1
|
#define GLCD_CT_T6963 1
|
||||||
#define GLCD_CT_PNG 2
|
#define GLCD_CT_PNG 2
|
||||||
|
#define GLCD_CT_SERDISP 3
|
||||||
|
|
||||||
/** Structure linking symbolic names to initialization routines */
|
/** Structure linking symbolic names to initialization routines */
|
||||||
typedef struct ConnectionMapping {
|
typedef struct ConnectionMapping {
|
||||||
@@ -44,6 +48,9 @@ static const ConnectionMapping connectionMapping[] = {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBPNG
|
#ifdef HAVE_LIBPNG
|
||||||
{"png", GLCD_CT_PNG, glcd_png_init},
|
{"png", GLCD_CT_PNG, glcd_png_init},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SERDISPLIB
|
||||||
|
{"serdisplib", GLCD_CT_SERDISP, glcd_serdisp_init},
|
||||||
#endif
|
#endif
|
||||||
/* default, end of structure element (do not delete) */
|
/* default, end of structure element (do not delete) */
|
||||||
{NULL, GLCD_CT_UNKNOWN, NULL}
|
{NULL, GLCD_CT_UNKNOWN, NULL}
|
||||||
|
|||||||
+45
-11
@@ -17,11 +17,17 @@
|
|||||||
#define GLCD_DEFAULT_BRIGHTNESS 800
|
#define GLCD_DEFAULT_BRIGHTNESS 800
|
||||||
#define GLCD_DEFAULT_OFFBRIGHTNESS 100
|
#define GLCD_DEFAULT_OFFBRIGHTNESS 100
|
||||||
|
|
||||||
|
/** The framebuffer and its properties */
|
||||||
|
struct glcd_framebuf {
|
||||||
|
unsigned char *data; /**< frame buffer */
|
||||||
|
int px_width; /**< display width in dots */
|
||||||
|
int px_height; /**< display height in dots */
|
||||||
|
int bytesPerLine; /**< number of bytes per pixel row */
|
||||||
|
};
|
||||||
|
|
||||||
/** private data for the \c glcd driver */
|
/** private data for the \c glcd driver */
|
||||||
typedef struct glcd_private_data {
|
typedef struct glcd_private_data {
|
||||||
unsigned char *framebuf; /**< frame buffer */
|
struct glcd_framebuf framebuf; /**< the main framebuffer */
|
||||||
int px_width; /**< display width in dots */
|
|
||||||
int px_height; /**< display height in dots */
|
|
||||||
int cellwidth; /**< character cell width */
|
int cellwidth; /**< character cell width */
|
||||||
int cellheight; /**< character cell height */
|
int cellheight; /**< character cell height */
|
||||||
int width; /**< display width in characters */
|
int width; /**< display width in characters */
|
||||||
@@ -61,8 +67,10 @@ typedef struct hwDependentFns {
|
|||||||
|
|
||||||
/* ================== Framebuffer functions and macros =================== */
|
/* ================== Framebuffer functions and macros =================== */
|
||||||
|
|
||||||
#define BYTES_PER_LINE (p->px_width / 8)
|
#define BYTES_PER_LINE (p->framebuf.bytesPerLine)
|
||||||
#define FB_BYTES_TOTAL (p->px_height * BYTES_PER_LINE)
|
#define FB_BYTES_TOTAL (p->framebuf.px_height * BYTES_PER_LINE)
|
||||||
|
#define FB_BLACK 1
|
||||||
|
#define FB_WHITE 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw one pixel into the framebuffer using 1bpp (black and white). This
|
* Draw one pixel into the framebuffer using 1bpp (black and white). This
|
||||||
@@ -75,21 +83,47 @@ typedef struct hwDependentFns {
|
|||||||
* \param color Pixel color: 1 = set (black), 0 = not set (blank/white)
|
* \param color Pixel color: 1 = set (black), 0 = not set (blank/white)
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
fb_draw_pixel(PrivateData *p, int x, int y, int color)
|
fb_draw_pixel(struct glcd_framebuf *fb, int x, int y, int color)
|
||||||
{
|
{
|
||||||
unsigned int pos; /* Byte within the framebuffer */
|
unsigned int pos; /* Byte within the framebuffer */
|
||||||
unsigned char bit; /* Bit within the framebuffer byte */
|
unsigned char bit; /* Bit within the framebuffer byte */
|
||||||
|
|
||||||
if (x < 0 || x >= p->px_width || y < 0 || y >= p->px_height)
|
if (x < 0 || x >= fb->px_width || y < 0 || y >= fb->px_height)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pos = y * BYTES_PER_LINE + (x / 8);
|
pos = y * fb->bytesPerLine + (x / 8);
|
||||||
bit = 0x80 >> (x % 8);
|
bit = 0x80 >> (x % 8);
|
||||||
|
|
||||||
if (color == 1)
|
if (color == FB_BLACK)
|
||||||
p->framebuf[pos] |= bit;
|
fb->data[pos] |= bit;
|
||||||
else
|
else
|
||||||
p->framebuf[pos] &= ~bit;
|
fb->data[pos] &= ~bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get color value of one pixel from the framebuffer.
|
||||||
|
*
|
||||||
|
* \param p Pointer to driver's private data.
|
||||||
|
* \param x X-position
|
||||||
|
* \param y Y-position
|
||||||
|
* \return Pixel color: 1 = set (black), 0 = not set (blank/white)
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
fb_get_pixel(struct glcd_framebuf *fb, int x, int y)
|
||||||
|
{
|
||||||
|
unsigned int pos;
|
||||||
|
unsigned char bit;
|
||||||
|
|
||||||
|
if (x < 0 || x >= fb->px_width || y < 0 || y >= fb->px_height)
|
||||||
|
return FB_WHITE;
|
||||||
|
|
||||||
|
pos = y * fb->bytesPerLine + (x / 8);
|
||||||
|
bit = 0x80 >> (x % 8);
|
||||||
|
|
||||||
|
if (fb->data[pos] & bit)
|
||||||
|
return FB_BLACK;
|
||||||
|
else
|
||||||
|
return FB_WHITE;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -27,7 +27,10 @@
|
|||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
#include "glcd-low.h"
|
#include "glcd-low.h"
|
||||||
#include "glcd-png.h"
|
|
||||||
|
/* Prototypes */
|
||||||
|
void glcd_png_blit(PrivateData *p);
|
||||||
|
void glcd_png_close(PrivateData *p);
|
||||||
|
|
||||||
/** Private data for the PNG connection type */
|
/** Private data for the PNG connection type */
|
||||||
typedef struct glcd_png_data {
|
typedef struct glcd_png_data {
|
||||||
@@ -89,7 +92,7 @@ glcd_png_blit(PrivateData *p)
|
|||||||
png_bytep row_pointer;
|
png_bytep row_pointer;
|
||||||
|
|
||||||
/* Check if framebufer has changed. If not there's nothing to do */
|
/* Check if framebufer has changed. If not there's nothing to do */
|
||||||
if (memcmp(p->framebuf, ct_data->backingstore, FB_BYTES_TOTAL) == 0)
|
if (memcmp(p->framebuf.data, ct_data->backingstore, FB_BYTES_TOTAL) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
snprintf(filename, sizeof(filename), "/tmp/lcdproc%06d.png", num++);
|
snprintf(filename, sizeof(filename), "/tmp/lcdproc%06d.png", num++);
|
||||||
@@ -120,7 +123,7 @@ glcd_png_blit(PrivateData *p)
|
|||||||
|
|
||||||
png_init_io(png_ptr, fp);
|
png_init_io(png_ptr, fp);
|
||||||
|
|
||||||
png_set_IHDR(png_ptr, info_ptr, p->px_width, p->px_height,
|
png_set_IHDR(png_ptr, info_ptr, p->framebuf.px_width, p->framebuf.px_height,
|
||||||
1, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
|
1, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
|
||||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||||
png_set_invert_mono(png_ptr);
|
png_set_invert_mono(png_ptr);
|
||||||
@@ -128,8 +131,8 @@ glcd_png_blit(PrivateData *p)
|
|||||||
png_write_info(png_ptr, info_ptr);
|
png_write_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
/* Write the image row by row */
|
/* Write the image row by row */
|
||||||
row_pointer = p->framebuf;
|
row_pointer = p->framebuf.data;
|
||||||
for (row = 0; row < p->px_height; row++) {
|
for (row = 0; row < p->framebuf.px_height; row++) {
|
||||||
png_write_row(png_ptr, row_pointer);
|
png_write_row(png_ptr, row_pointer);
|
||||||
row_pointer += BYTES_PER_LINE;
|
row_pointer += BYTES_PER_LINE;
|
||||||
}
|
}
|
||||||
@@ -139,7 +142,7 @@ glcd_png_blit(PrivateData *p)
|
|||||||
fp = NULL;
|
fp = NULL;
|
||||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
|
||||||
memcpy(ct_data->backingstore, p->framebuf, FB_BYTES_TOTAL);
|
memcpy(ct_data->backingstore, p->framebuf.data, FB_BYTES_TOTAL);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#ifndef GLCD_PNG_H
|
|
||||||
#define GLCD_PNG_H
|
|
||||||
|
|
||||||
int glcd_png_init(Driver *drvthis);
|
|
||||||
void glcd_png_blit(PrivateData *p);
|
|
||||||
void glcd_png_close(PrivateData *p);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -64,7 +64,7 @@ glcd_render_init(Driver *drvthis)
|
|||||||
RenderConfig *rconf;
|
RenderConfig *rconf;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
debug(RPT_INFO, "%s(): Freetype", __FUNCTION__);
|
debug(RPT_INFO, "%s: render_init: Freetype", drvthis->name);
|
||||||
|
|
||||||
/* Allocate memory structures */
|
/* Allocate memory structures */
|
||||||
rconf = (RenderConfig *) calloc(1, sizeof(RenderConfig));
|
rconf = (RenderConfig *) calloc(1, sizeof(RenderConfig));
|
||||||
@@ -117,11 +117,10 @@ glcd_render_init(Driver *drvthis)
|
|||||||
}
|
}
|
||||||
p->cellwidth = w;
|
p->cellwidth = w;
|
||||||
p->cellheight = h;
|
p->cellheight = h;
|
||||||
debug(RPT_INFO, "%s: using cellsize %dx%d", drvthis->name, p->cellwidth, p->cellheight);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
debug(RPT_INFO, "%s: using cellsize %dx%d", drvthis->name, p->cellwidth, p->cellheight);
|
||||||
|
|
||||||
debug(RPT_INFO, "%s() successful", __FUNCTION__);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef HAVE_FT2
|
#ifdef HAVE_FT2
|
||||||
@@ -233,7 +232,7 @@ glcd_render_char_unicode(Driver *drvthis, int x, int y, int c, int yscale, int x
|
|||||||
for (row = 0; row < r_height; row++, py++) {
|
for (row = 0; row < r_height; row++, py++) {
|
||||||
px = x * p->cellwidth;
|
px = x * p->cellwidth;
|
||||||
for (col = 0; col < r_width; col++, px++) {
|
for (col = 0; col < r_width; col++, px++) {
|
||||||
fb_draw_pixel(p, px, py, 0);
|
fb_draw_pixel(&(p->framebuf), px, py, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +254,7 @@ glcd_render_char_unicode(Driver *drvthis, int x, int y, int c, int yscale, int x
|
|||||||
px += (r_width - bitmap->width)/2;
|
px += (r_width - bitmap->width)/2;
|
||||||
|
|
||||||
for (col = 0; (col < bitmap->width) && (col < r_width); col++) {
|
for (col = 0; (col < bitmap->width) && (col < r_width); col++) {
|
||||||
fb_draw_pixel(p, px, py, bitmap_buf[col / 8] >> (7 - (col % 8)) & 1);
|
fb_draw_pixel(&(p->framebuf), px, py, bitmap_buf[col / 8] >> (7 - (col % 8)) & 1);
|
||||||
px++;
|
px++;
|
||||||
}
|
}
|
||||||
bitmap_buf += bitmap->pitch;
|
bitmap_buf += bitmap->pitch;
|
||||||
@@ -303,9 +302,9 @@ glcd_render_char(Driver *drvthis, int x, int y, unsigned char c)
|
|||||||
*/
|
*/
|
||||||
for (font_x = GLCD_FONT_WIDTH; font_x >= 0; font_x--) {
|
for (font_x = GLCD_FONT_WIDTH; font_x >= 0; font_x--) {
|
||||||
if (glcd_iso8859_1[c][font_y] & (1 << font_x))
|
if (glcd_iso8859_1[c][font_y] & (1 << font_x))
|
||||||
fb_draw_pixel(p, px, py, 1);
|
fb_draw_pixel(&(p->framebuf), px, py, 1);
|
||||||
else
|
else
|
||||||
fb_draw_pixel(p, px, py, 0);
|
fb_draw_pixel(&(p->framebuf), px, py, 0);
|
||||||
px++;
|
px++;
|
||||||
}
|
}
|
||||||
py++;
|
py++;
|
||||||
@@ -409,7 +408,7 @@ glcd_render_bignum(Driver *drvthis, int x, int num)
|
|||||||
int c, z; /* Column and byte within font definition */
|
int c, z; /* Column and byte within font definition */
|
||||||
int px, py; /* Pixel coordinates within the frame buffer */
|
int px, py; /* Pixel coordinates within the frame buffer */
|
||||||
|
|
||||||
if (p->px_height < chr_hgt_NUM)
|
if (p->framebuf.px_height < chr_hgt_NUM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
x--;
|
x--;
|
||||||
@@ -417,13 +416,13 @@ glcd_render_bignum(Driver *drvthis, int x, int num)
|
|||||||
px = x * p->cellwidth;
|
px = x * p->cellwidth;
|
||||||
for (c = 0; c < widtbl_NUM[num]; c++) {
|
for (c = 0; c < widtbl_NUM[num]; c++) {
|
||||||
/* center vertically */
|
/* center vertically */
|
||||||
py = (p->px_height - chr_hgt_NUM) / 2;
|
py = (p->framebuf.px_height - chr_hgt_NUM) / 2;
|
||||||
for (z = 0; z < chr_hgt_NUM; z++) {
|
for (z = 0; z < chr_hgt_NUM; z++) {
|
||||||
/* Test if pixel bit is set and draw it */
|
/* Test if pixel bit is set and draw it */
|
||||||
if (chrtbl_NUM[num][c * 3 + z / 8] & (1 << (z % 8)))
|
if (chrtbl_NUM[num][c * 3 + z / 8] & (1 << (z % 8)))
|
||||||
fb_draw_pixel(p, px, py, 1);
|
fb_draw_pixel(&(p->framebuf), px, py, 1);
|
||||||
else
|
else
|
||||||
fb_draw_pixel(p, px, py, 0);
|
fb_draw_pixel(&(p->framebuf), px, py, 0);
|
||||||
py++;
|
py++;
|
||||||
}
|
}
|
||||||
px++;
|
px++;
|
||||||
|
|||||||
@@ -0,0 +1,217 @@
|
|||||||
|
/** \file server/drivers/glcd-serdisp.c
|
||||||
|
* Connection type using serdisplib for output (bridge driver).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2010 Bernhard Walle <bernhard@bwalle.de>
|
||||||
|
* 2011 Markus Dolze <bsdfan@nurfuerspam.de>
|
||||||
|
*
|
||||||
|
* This file is released under the GNU General Public License. Refer to the
|
||||||
|
* COPYING file distributed with this package.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <serdisplib/serdisp.h>
|
||||||
|
|
||||||
|
#include "lcd.h"
|
||||||
|
#include "report.h"
|
||||||
|
#include "glcd-low.h"
|
||||||
|
|
||||||
|
#define SERDISPLIB_MAX_DISPLAYNAME 32
|
||||||
|
#define SERDISPLIB_MAX_DEVICENAME PATH_MAX
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
void glcd_serdisp_blit(PrivateData *p);
|
||||||
|
void glcd_serdisp_close(PrivateData *p);
|
||||||
|
void glcd_serdisp_backlight(PrivateData *p, int state);
|
||||||
|
|
||||||
|
/** Private data for the serdisplib connection type */
|
||||||
|
typedef struct glcd_serdisp_data {
|
||||||
|
/** 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 *disp;
|
||||||
|
|
||||||
|
/** framebuffer for incremental updates */
|
||||||
|
struct glcd_framebuf bsbuf;
|
||||||
|
} CT_serdisp_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API: Initialize the connection type driver.
|
||||||
|
* \param drvthis Pointer to driver structure.
|
||||||
|
* \retval 0 Success.
|
||||||
|
* \retval <0 Error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
glcd_serdisp_init(Driver *drvthis)
|
||||||
|
{
|
||||||
|
PrivateData *p = (PrivateData *)drvthis->private_data;
|
||||||
|
CT_serdisp_data *ct_data;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
report(RPT_INFO, "glcd/serdisplib: intializing...");
|
||||||
|
|
||||||
|
/* Set up connection type low-level functions */
|
||||||
|
p->glcd_functions->blit = glcd_serdisp_blit;
|
||||||
|
p->glcd_functions->close = glcd_serdisp_close;
|
||||||
|
p->glcd_functions->set_backlight = glcd_serdisp_backlight;
|
||||||
|
|
||||||
|
/* Allocate memory structures */
|
||||||
|
ct_data = (CT_serdisp_data *) calloc(1, sizeof(CT_serdisp_data));
|
||||||
|
if (ct_data == NULL) {
|
||||||
|
report(RPT_ERR, "%s: error allocating connection data",
|
||||||
|
drvthis->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p->ct_data = ct_data;
|
||||||
|
|
||||||
|
/* get the display name */
|
||||||
|
s = drvthis->config_get_string(drvthis->name, "serdisp_name", 0, NULL);
|
||||||
|
if (s == NULL) {
|
||||||
|
report(RPT_ERR, "%s: \'serdisp_name\' missing in configuration",
|
||||||
|
drvthis->name);
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
strncpy(ct_data->display_name, s, SERDISPLIB_MAX_DISPLAYNAME);
|
||||||
|
ct_data->display_name[SERDISPLIB_MAX_DISPLAYNAME - 1] = '\0';
|
||||||
|
|
||||||
|
/* get the display device */
|
||||||
|
s = drvthis->config_get_string(drvthis->name, "serdisp_device", 0, NULL);
|
||||||
|
if (s == NULL) {
|
||||||
|
report(RPT_ERR, "%s: \'serdisp_device\' missing in configuration",
|
||||||
|
drvthis->name);
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
strncpy(ct_data->display_device, s, SERDISPLIB_MAX_DEVICENAME);
|
||||||
|
ct_data->display_device[SERDISPLIB_MAX_DEVICENAME - 1] = '\0';
|
||||||
|
|
||||||
|
/* open the output device */
|
||||||
|
ct_data->serdisplib_conn = SDCONN_open(ct_data->display_device);
|
||||||
|
if (ct_data->serdisplib_conn == NULL) {
|
||||||
|
report(RPT_ERR, "Could not open %s: %s", ct_data->display_device,
|
||||||
|
sd_geterrormsg());
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open and initialize the display with options */
|
||||||
|
s = drvthis->config_get_string(drvthis->name, "serdisp_options", 0, "");
|
||||||
|
debug(RPT_INFO, "%s: Using serdisp options: %s", drvthis->name, s);
|
||||||
|
ct_data->disp = serdisp_init(ct_data->serdisplib_conn, ct_data->display_name, s);
|
||||||
|
if (ct_data->disp == NULL) {
|
||||||
|
report(RPT_ERR, "Error opening display %s: %s\n",
|
||||||
|
ct_data->display_name, sd_geterrormsg());
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set size overriding anything set in serdisp_options */
|
||||||
|
serdisp_setoption(ct_data->disp, "WIDTH", p->framebuf.px_width);
|
||||||
|
serdisp_setoption(ct_data->disp, "HEIGHT", p->framebuf.px_height);
|
||||||
|
|
||||||
|
/* allocate backing store based on frame buffer */
|
||||||
|
ct_data->bsbuf.px_width = p->framebuf.px_width;
|
||||||
|
ct_data->bsbuf.px_height = p->framebuf.px_height;
|
||||||
|
ct_data->bsbuf.bytesPerLine = p->framebuf.bytesPerLine;
|
||||||
|
ct_data->bsbuf.data = malloc(ct_data->bsbuf.px_height * ct_data->bsbuf.bytesPerLine);
|
||||||
|
if (ct_data->bsbuf.data == NULL) {
|
||||||
|
report(RPT_ERR, "%s: error allocating backing store",
|
||||||
|
drvthis->name);
|
||||||
|
}
|
||||||
|
memset(ct_data->bsbuf.data, 0x00, ct_data->bsbuf.px_height * ct_data->bsbuf.bytesPerLine);
|
||||||
|
|
||||||
|
serdisp_clearbuffer(ct_data->disp);
|
||||||
|
|
||||||
|
debug(RPT_INFO, "glcd/serdisplib: finished");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
glcd_serdisp_close(p);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API: Release low-level resources.
|
||||||
|
* \param p Pointer to glcd driver's private date structure.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
glcd_serdisp_close(PrivateData *p)
|
||||||
|
{
|
||||||
|
if (p->ct_data != NULL) {
|
||||||
|
CT_serdisp_data *ct_data = (CT_serdisp_data *) p->ct_data;
|
||||||
|
|
||||||
|
if (ct_data->serdisplib_conn && !ct_data->disp)
|
||||||
|
SDCONN_close(ct_data->serdisplib_conn);
|
||||||
|
if (ct_data->disp)
|
||||||
|
serdisp_quit(ct_data->disp);
|
||||||
|
if (ct_data->bsbuf.data) {
|
||||||
|
free(ct_data->bsbuf.data);
|
||||||
|
ct_data->bsbuf.data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(p->ct_data);
|
||||||
|
p->ct_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API: Write the framebuffer to the display
|
||||||
|
* \param p Pointer to glcd driver's private date structure.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
glcd_serdisp_blit(PrivateData *p)
|
||||||
|
{
|
||||||
|
CT_serdisp_data *ct_data = (CT_serdisp_data *) p->ct_data;
|
||||||
|
int px, py;
|
||||||
|
int pixel_new, pixel_old;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update method: go through the whole framebuffer line by line and
|
||||||
|
* compare each pixel with the one in the backing store. If different
|
||||||
|
* draw to serdisplib.
|
||||||
|
*/
|
||||||
|
for (py = 0; py < p->framebuf.px_height; py++) {
|
||||||
|
for (px = 0; px < p->framebuf.px_width; px++) {
|
||||||
|
pixel_old = fb_get_pixel(&(ct_data->bsbuf), px, py);
|
||||||
|
pixel_new = fb_get_pixel(&(p->framebuf), px, py);
|
||||||
|
if (pixel_old != pixel_new) {
|
||||||
|
serdisp_setcolour(ct_data->disp, px, py,
|
||||||
|
(pixel_new == FB_BLACK) ? SD_COL_BLACK : SD_COL_WHITE);
|
||||||
|
fb_draw_pixel(&(ct_data->bsbuf), px, py, pixel_new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serdisp_update(ct_data->disp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API: Turn the backlight on or off. The serdisp library does not support
|
||||||
|
* backlight levels. Any level set in glcd driver is ignored.
|
||||||
|
* \param p
|
||||||
|
* \param state
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
glcd_serdisp_backlight(PrivateData *p, int state)
|
||||||
|
{
|
||||||
|
CT_serdisp_data *ct_data = (CT_serdisp_data *) p->ct_data;
|
||||||
|
|
||||||
|
if (state == BACKLIGHT_ON)
|
||||||
|
serdisp_setoption(ct_data->disp, "BACKLIGHT", SD_OPTION_YES);
|
||||||
|
else
|
||||||
|
serdisp_setoption(ct_data->disp, "BACKLIGHT", SD_OPTION_NO);
|
||||||
|
}
|
||||||
@@ -26,12 +26,13 @@
|
|||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
#include "glcd-low.h"
|
#include "glcd-low.h"
|
||||||
#include "glcd-t6963.h"
|
|
||||||
#include "t6963_low.h"
|
#include "t6963_low.h"
|
||||||
|
|
||||||
#define DEFAULT_PORT 0x378
|
#define DEFAULT_PORT 0x378
|
||||||
|
|
||||||
static void t6963_graphic_clear(PrivateData *p);
|
static void t6963_graphic_clear(PrivateData *p);
|
||||||
|
void glcd_t6963_blit(PrivateData *p);
|
||||||
|
void glcd_t6963_close(PrivateData *p);
|
||||||
|
|
||||||
typedef struct glcd_t6963_data {
|
typedef struct glcd_t6963_data {
|
||||||
unsigned char *backingstore; /**< backing buffer */
|
unsigned char *backingstore; /**< backing buffer */
|
||||||
@@ -54,9 +55,9 @@ glcd_t6963_init(Driver *drvthis)
|
|||||||
report(RPT_INFO, "GLCD/T6963: intializing");
|
report(RPT_INFO, "GLCD/T6963: intializing");
|
||||||
|
|
||||||
/* Check the size before doing anything else! */
|
/* Check the size before doing anything else! */
|
||||||
if ((p->px_width > T6963_MAX_WIDTH) || (p->px_height > T6963_MAX_HEIGHT)) {
|
if ((p->framebuf.px_width > T6963_MAX_WIDTH) || (p->framebuf.px_height > T6963_MAX_HEIGHT)) {
|
||||||
report(RPT_ERR, "GLCD/T6963: Size %dx%d not supported by connection type",
|
report(RPT_ERR, "GLCD/T6963: Size %dx%d not supported by connection type",
|
||||||
p->px_width, p->px_height);
|
p->framebuf.px_width, p->framebuf.px_height);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,9 +137,9 @@ glcd_t6963_blit(PrivateData *p)
|
|||||||
CT_t6963_data *ct_data = (CT_t6963_data *) p->ct_data;
|
CT_t6963_data *ct_data = (CT_t6963_data *) p->ct_data;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
for (y = 0; y < p->px_height; y++) {
|
for (y = 0; y < p->framebuf.px_height; y++) {
|
||||||
/* set pointers to start of the line */
|
/* set pointers to start of the line */
|
||||||
unsigned char *sp = p->framebuf + (y * BYTES_PER_LINE);
|
unsigned char *sp = p->framebuf.data + (y * BYTES_PER_LINE);
|
||||||
unsigned char *sq = ct_data->backingstore + (y * BYTES_PER_LINE);
|
unsigned char *sq = ct_data->backingstore + (y * BYTES_PER_LINE);
|
||||||
|
|
||||||
/* set pointers to end of the line */
|
/* set pointers to end of the line */
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#ifndef GLCD_T6963_H
|
|
||||||
#define GLCD_T6963_H
|
|
||||||
|
|
||||||
int glcd_t6963_init(Driver *drvthis);
|
|
||||||
void glcd_t6963_blit(PrivateData *p);
|
|
||||||
void glcd_t6963_close(PrivateData *p);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
+23
-28
@@ -124,8 +124,10 @@ glcd_init(Driver *drvthis)
|
|||||||
drvthis->name, size, GLCD_DEFAULT_SIZE);
|
drvthis->name, size, GLCD_DEFAULT_SIZE);
|
||||||
sscanf(GLCD_DEFAULT_SIZE, "%dx%d", &w, &h);
|
sscanf(GLCD_DEFAULT_SIZE, "%dx%d", &w, &h);
|
||||||
}
|
}
|
||||||
p->px_width = w;
|
p->framebuf.px_width = w;
|
||||||
p->px_height = h;
|
p->framebuf.px_height = h;
|
||||||
|
p->framebuf.bytesPerLine = (p->framebuf.px_width + 7) / 8;
|
||||||
|
debug(RPT_INFO, "%s: bytesPerLine (first) = %d", drvthis->name, BYTES_PER_LINE);
|
||||||
|
|
||||||
/* Set contrast */
|
/* Set contrast */
|
||||||
tmp = drvthis->config_get_int(drvthis->name, "Contrast", 0, GLCD_DEFAULT_CONTRAST);
|
tmp = drvthis->config_get_int(drvthis->name, "Contrast", 0, GLCD_DEFAULT_CONTRAST);
|
||||||
@@ -170,39 +172,33 @@ glcd_init(Driver *drvthis)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Currently this driver supports only display which width is a multiple
|
* Check these values AFTER driver initialization, as the driver may
|
||||||
* of 8!
|
* update them.
|
||||||
*/
|
*/
|
||||||
if ((p->px_width % 8) != 0) {
|
if ((p->framebuf.px_width > GLCD_MAX_WIDTH) || (p->framebuf.px_height > GLCD_MAX_HEIGHT)) {
|
||||||
report(RPT_ERR, "%s: Pixel width must be mutiple of 8", drvthis->name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculate these values AFTER driver initialization, as the driver
|
|
||||||
* may update them.
|
|
||||||
*/
|
|
||||||
if ((p->px_width > GLCD_MAX_WIDTH) || (p->px_height > GLCD_MAX_HEIGHT)) {
|
|
||||||
report(RPT_ERR, "%s: Size %dx%d set by ConnectionType is not supported",
|
report(RPT_ERR, "%s: Size %dx%d set by ConnectionType is not supported",
|
||||||
drvthis->name, p->px_width, p->px_height);
|
drvthis->name, p->framebuf.px_width, p->framebuf.px_height);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate framebuffer */
|
/* Allocate framebuffer (re-calculate bytesPerLine before) */
|
||||||
p->framebuf = malloc(FB_BYTES_TOTAL);
|
p->framebuf.bytesPerLine = (p->framebuf.px_width + 7) / 8;
|
||||||
if (p->framebuf == NULL) {
|
debug(RPT_INFO, "%s: bytesPerLine (final) = %d", drvthis->name, BYTES_PER_LINE);
|
||||||
|
p->framebuf.data = malloc(FB_BYTES_TOTAL);
|
||||||
|
if (p->framebuf.data == NULL) {
|
||||||
report(RPT_ERR, "%s: unable to allocate framebuffer", drvthis->name);
|
report(RPT_ERR, "%s: unable to allocate framebuffer", drvthis->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(p->framebuf, 0x00, FB_BYTES_TOTAL);
|
memset(p->framebuf.data, 0x00, FB_BYTES_TOTAL);
|
||||||
|
|
||||||
/* Initialize renderer */
|
/* Initialize renderer */
|
||||||
if (glcd_render_init(drvthis) != 0)
|
if (glcd_render_init(drvthis) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Cellwidth / height are set by the renderer */
|
/* Cellwidth / height are set by the renderer */
|
||||||
p->width = p->px_width / p->cellwidth;
|
p->width = p->framebuf.px_width / p->cellwidth;
|
||||||
p->height = p->px_height / p->cellheight;
|
p->height = p->framebuf.px_height / p->cellheight;
|
||||||
|
debug(RPT_INFO, "%s: Screen size (final) = %dx%d", drvthis->name, p->width, p->height);
|
||||||
|
|
||||||
glcd_clear(drvthis);
|
glcd_clear(drvthis);
|
||||||
|
|
||||||
@@ -224,9 +220,9 @@ glcd_close(Driver *drvthis)
|
|||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
if (p->glcd_functions->close != NULL)
|
if (p->glcd_functions->close != NULL)
|
||||||
p->glcd_functions->close(p);
|
p->glcd_functions->close(p);
|
||||||
if (p->framebuf != NULL)
|
if (p->framebuf.data != NULL)
|
||||||
free(p->framebuf);
|
free(p->framebuf.data);
|
||||||
p->framebuf = NULL;
|
p->framebuf.data = NULL;
|
||||||
glcd_render_close(drvthis);
|
glcd_render_close(drvthis);
|
||||||
|
|
||||||
free(p);
|
free(p);
|
||||||
@@ -310,7 +306,7 @@ glcd_clear(Driver *drvthis)
|
|||||||
|
|
||||||
debug(RPT_DEBUG, "%s()", __FUNCTION__);
|
debug(RPT_DEBUG, "%s()", __FUNCTION__);
|
||||||
|
|
||||||
memset(p->framebuf, 0x00, FB_BYTES_TOTAL);
|
memset(p->framebuf.data, 0x00, FB_BYTES_TOTAL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +323,6 @@ glcd_flush(Driver *drvthis)
|
|||||||
debug(RPT_DEBUG, "%s()", __FUNCTION__);
|
debug(RPT_DEBUG, "%s()", __FUNCTION__);
|
||||||
|
|
||||||
p->glcd_functions->blit(p);
|
p->glcd_functions->blit(p);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -425,7 +420,7 @@ glcd_vbar(Driver *drvthis, int x, int y, int len, int promille, int options)
|
|||||||
|
|
||||||
for (col = xstart; col < xend; col++) {
|
for (col = xstart; col < xend; col++) {
|
||||||
for (row = ystart; row > yend; row--) {
|
for (row = ystart; row > yend; row--) {
|
||||||
fb_draw_pixel(p, col, row, 1);
|
fb_draw_pixel(&(p->framebuf), col, row, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -451,7 +446,7 @@ glcd_hbar(Driver *drvthis, int x, int y, int len, int promille, int options)
|
|||||||
|
|
||||||
for (row = ystart; row < yend; row++) {
|
for (row = ystart; row < yend; row++) {
|
||||||
for (col = xstart; col < xend; col++) {
|
for (col = xstart; col < xend; col++) {
|
||||||
fb_draw_pixel(p, col, row, 1);
|
fb_draw_pixel(&(p->framebuf), col, row, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user