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]
|
||||
#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 ##
|
||||
|
||||
@@ -173,6 +173,16 @@ dnl else
|
||||
if test "$enable_libpng" = yes ; then
|
||||
GLCD_DRIVERS="$GLCD_DRIVERS glcd-glcd-png.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])
|
||||
LIBSERDISP="-lserdisp"
|
||||
GLCD_DRIVERS="$GLCD_DRIVERS glcd-glcd-serdisp.o"
|
||||
],[
|
||||
AC_MSG_WARN([serdisp library not working])
|
||||
])
|
||||
])
|
||||
AC_SUBST(LIBSERDISP)
|
||||
DRIVERS="$DRIVERS glcd${SO}"
|
||||
actdrivers=["$actdrivers glcd"]
|
||||
;;
|
||||
|
||||
@@ -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@
|
||||
glcd_LDADD = libLCD.a @GLCD_DRIVERS@ @FT2_LIBS@ @LIBPNG_LIBS@ @LIBSERDISP@
|
||||
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 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
|
||||
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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** \file server/drivers/glcd-drivers.h
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -12,18 +12,22 @@
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
/* Include connection type header below */
|
||||
/* Include prototypes for initialization functions below */
|
||||
#ifdef HAVE_PCSTYLE_LPT_CONTROL
|
||||
# include "glcd-t6963.h"
|
||||
int glcd_t6963_init(Driver *drvthis);
|
||||
#endif
|
||||
#ifdef HAVE_LIBPNG
|
||||
# include "glcd-png.h"
|
||||
int glcd_png_init(Driver *drvthis);
|
||||
#endif
|
||||
#ifdef HAVE_SERDISPLIB
|
||||
int glcd_serdisp_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
|
||||
|
||||
/** Structure linking symbolic names to initialization routines */
|
||||
typedef struct ConnectionMapping {
|
||||
@@ -44,6 +48,9 @@ static const ConnectionMapping connectionMapping[] = {
|
||||
#endif
|
||||
#ifdef HAVE_LIBPNG
|
||||
{"png", GLCD_CT_PNG, glcd_png_init},
|
||||
#endif
|
||||
#ifdef HAVE_SERDISPLIB
|
||||
{"serdisplib", GLCD_CT_SERDISP, glcd_serdisp_init},
|
||||
#endif
|
||||
/* default, end of structure element (do not delete) */
|
||||
{NULL, GLCD_CT_UNKNOWN, NULL}
|
||||
|
||||
+45
-11
@@ -17,11 +17,17 @@
|
||||
#define GLCD_DEFAULT_BRIGHTNESS 800
|
||||
#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 */
|
||||
typedef struct glcd_private_data {
|
||||
unsigned char *framebuf; /**< frame buffer */
|
||||
int px_width; /**< display width in dots */
|
||||
int px_height; /**< display height in dots */
|
||||
struct glcd_framebuf framebuf; /**< the main framebuffer */
|
||||
int cellwidth; /**< character cell width */
|
||||
int cellheight; /**< character cell height */
|
||||
int width; /**< display width in characters */
|
||||
@@ -61,8 +67,10 @@ typedef struct hwDependentFns {
|
||||
|
||||
/* ================== Framebuffer functions and macros =================== */
|
||||
|
||||
#define BYTES_PER_LINE (p->px_width / 8)
|
||||
#define FB_BYTES_TOTAL (p->px_height * BYTES_PER_LINE)
|
||||
#define BYTES_PER_LINE (p->framebuf.bytesPerLine)
|
||||
#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
|
||||
@@ -75,21 +83,47 @@ typedef struct hwDependentFns {
|
||||
* \param color Pixel color: 1 = set (black), 0 = not set (blank/white)
|
||||
*/
|
||||
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 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;
|
||||
|
||||
pos = y * BYTES_PER_LINE + (x / 8);
|
||||
pos = y * fb->bytesPerLine + (x / 8);
|
||||
bit = 0x80 >> (x % 8);
|
||||
|
||||
if (color == 1)
|
||||
p->framebuf[pos] |= bit;
|
||||
if (color == FB_BLACK)
|
||||
fb->data[pos] |= bit;
|
||||
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
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
#include "lcd.h"
|
||||
#include "report.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 */
|
||||
typedef struct glcd_png_data {
|
||||
@@ -89,7 +92,7 @@ glcd_png_blit(PrivateData *p)
|
||||
png_bytep row_pointer;
|
||||
|
||||
/* 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;
|
||||
|
||||
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_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,
|
||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
png_set_invert_mono(png_ptr);
|
||||
@@ -128,8 +131,8 @@ glcd_png_blit(PrivateData *p)
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
/* Write the image row by row */
|
||||
row_pointer = p->framebuf;
|
||||
for (row = 0; row < p->px_height; row++) {
|
||||
row_pointer = p->framebuf.data;
|
||||
for (row = 0; row < p->framebuf.px_height; row++) {
|
||||
png_write_row(png_ptr, row_pointer);
|
||||
row_pointer += BYTES_PER_LINE;
|
||||
}
|
||||
@@ -139,7 +142,7 @@ glcd_png_blit(PrivateData *p)
|
||||
fp = NULL;
|
||||
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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
int w, h;
|
||||
|
||||
debug(RPT_INFO, "%s(): Freetype", __FUNCTION__);
|
||||
debug(RPT_INFO, "%s: render_init: Freetype", drvthis->name);
|
||||
|
||||
/* Allocate memory structures */
|
||||
rconf = (RenderConfig *) calloc(1, sizeof(RenderConfig));
|
||||
@@ -117,11 +117,10 @@ glcd_render_init(Driver *drvthis)
|
||||
}
|
||||
p->cellwidth = w;
|
||||
p->cellheight = h;
|
||||
debug(RPT_INFO, "%s: using cellsize %dx%d", drvthis->name, p->cellwidth, p->cellheight);
|
||||
}
|
||||
#endif
|
||||
debug(RPT_INFO, "%s: using cellsize %dx%d", drvthis->name, p->cellwidth, p->cellheight);
|
||||
|
||||
debug(RPT_INFO, "%s() successful", __FUNCTION__);
|
||||
return 0;
|
||||
|
||||
#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++) {
|
||||
px = x * p->cellwidth;
|
||||
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;
|
||||
|
||||
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++;
|
||||
}
|
||||
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--) {
|
||||
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
|
||||
fb_draw_pixel(p, px, py, 0);
|
||||
fb_draw_pixel(&(p->framebuf), px, py, 0);
|
||||
px++;
|
||||
}
|
||||
py++;
|
||||
@@ -409,7 +408,7 @@ glcd_render_bignum(Driver *drvthis, int x, int num)
|
||||
int c, z; /* Column and byte within font definition */
|
||||
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;
|
||||
|
||||
x--;
|
||||
@@ -417,13 +416,13 @@ glcd_render_bignum(Driver *drvthis, int x, int num)
|
||||
px = x * p->cellwidth;
|
||||
for (c = 0; c < widtbl_NUM[num]; c++) {
|
||||
/* 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++) {
|
||||
/* Test if pixel bit is set and draw it */
|
||||
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
|
||||
fb_draw_pixel(p, px, py, 0);
|
||||
fb_draw_pixel(&(p->framebuf), px, py, 0);
|
||||
py++;
|
||||
}
|
||||
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 "report.h"
|
||||
#include "glcd-low.h"
|
||||
#include "glcd-t6963.h"
|
||||
#include "t6963_low.h"
|
||||
|
||||
#define DEFAULT_PORT 0x378
|
||||
|
||||
static void t6963_graphic_clear(PrivateData *p);
|
||||
void glcd_t6963_blit(PrivateData *p);
|
||||
void glcd_t6963_close(PrivateData *p);
|
||||
|
||||
typedef struct glcd_t6963_data {
|
||||
unsigned char *backingstore; /**< backing buffer */
|
||||
@@ -54,9 +55,9 @@ glcd_t6963_init(Driver *drvthis)
|
||||
report(RPT_INFO, "GLCD/T6963: intializing");
|
||||
|
||||
/* 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",
|
||||
p->px_width, p->px_height);
|
||||
p->framebuf.px_width, p->framebuf.px_height);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -136,9 +137,9 @@ glcd_t6963_blit(PrivateData *p)
|
||||
CT_t6963_data *ct_data = (CT_t6963_data *) p->ct_data;
|
||||
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 */
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
sscanf(GLCD_DEFAULT_SIZE, "%dx%d", &w, &h);
|
||||
}
|
||||
p->px_width = w;
|
||||
p->px_height = h;
|
||||
p->framebuf.px_width = w;
|
||||
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 */
|
||||
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
|
||||
* of 8!
|
||||
* Check these values AFTER driver initialization, as the driver may
|
||||
* update them.
|
||||
*/
|
||||
if ((p->px_width % 8) != 0) {
|
||||
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)) {
|
||||
if ((p->framebuf.px_width > GLCD_MAX_WIDTH) || (p->framebuf.px_height > GLCD_MAX_HEIGHT)) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* Allocate framebuffer */
|
||||
p->framebuf = malloc(FB_BYTES_TOTAL);
|
||||
if (p->framebuf == NULL) {
|
||||
/* Allocate framebuffer (re-calculate bytesPerLine before) */
|
||||
p->framebuf.bytesPerLine = (p->framebuf.px_width + 7) / 8;
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
memset(p->framebuf, 0x00, FB_BYTES_TOTAL);
|
||||
memset(p->framebuf.data, 0x00, FB_BYTES_TOTAL);
|
||||
|
||||
/* Initialize renderer */
|
||||
if (glcd_render_init(drvthis) != 0)
|
||||
return -1;
|
||||
|
||||
/* Cellwidth / height are set by the renderer */
|
||||
p->width = p->px_width / p->cellwidth;
|
||||
p->height = p->px_height / p->cellheight;
|
||||
p->width = p->framebuf.px_width / p->cellwidth;
|
||||
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);
|
||||
|
||||
@@ -224,9 +220,9 @@ glcd_close(Driver *drvthis)
|
||||
if (p != NULL) {
|
||||
if (p->glcd_functions->close != NULL)
|
||||
p->glcd_functions->close(p);
|
||||
if (p->framebuf != NULL)
|
||||
free(p->framebuf);
|
||||
p->framebuf = NULL;
|
||||
if (p->framebuf.data != NULL)
|
||||
free(p->framebuf.data);
|
||||
p->framebuf.data = NULL;
|
||||
glcd_render_close(drvthis);
|
||||
|
||||
free(p);
|
||||
@@ -310,7 +306,7 @@ glcd_clear(Driver *drvthis)
|
||||
|
||||
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__);
|
||||
|
||||
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 (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 (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