glcd driver: Add the 'x11' connection type that draws the screen to a X
window (by S. Meharg).
This commit is contained in:
@@ -15,6 +15,7 @@ v0.5dev (ongoing development)
|
|||||||
+ hd44780: Add support for FreeBSD's iic I2C framework
|
+ hd44780: Add support for FreeBSD's iic I2C framework
|
||||||
+ hd44780: New connection type 'piplate' (J. Brogdon)
|
+ hd44780: New connection type 'piplate' (J. Brogdon)
|
||||||
* lcdproc client: Add option to turn off title and heartbeat on OldTime screen
|
* lcdproc client: Add option to turn off title and heartbeat on OldTime screen
|
||||||
|
+ glcd driver: Connection type 'x11' that draws to a X window (S. Meharg)
|
||||||
|
|
||||||
v0.5.6
|
v0.5.6
|
||||||
- Remove deprecated CFontz633 driver. Use CFontzPacket with Model=633 instead!
|
- Remove deprecated CFontz633 driver. Use CFontzPacket with Model=633 instead!
|
||||||
|
|||||||
@@ -407,32 +407,55 @@ KeyMap_B=Down
|
|||||||
KeyMap_C=Enter
|
KeyMap_C=Enter
|
||||||
KeyMap_D=Escape
|
KeyMap_D=Escape
|
||||||
|
|
||||||
# t6963: Parallel port to use [default: 0x378; legal: 0x200 - 0x400]
|
# --- t6963 options ---
|
||||||
|
|
||||||
|
# Parallel port to use [default: 0x378; legal: 0x200 - 0x400]
|
||||||
#Port=0x378
|
#Port=0x378
|
||||||
|
|
||||||
# t6963: Use LPT port in bi-directional mode. This should work on most LPT port
|
# Use LPT port in bi-directional mode. This should work on most LPT port
|
||||||
# and is required for proper timing! [default: yes; legal: yes, no]
|
# and is required for proper timing! [default: yes; legal: yes, no]
|
||||||
#bidirectional=yes
|
#bidirectional=yes
|
||||||
|
|
||||||
# t6963: Insert additional delays into reads / writes. [default: no;
|
# Insert additional delays into reads / writes. [default: no; legal: yes, no]
|
||||||
# legal: yes, no]
|
|
||||||
#delayBus=no
|
#delayBus=no
|
||||||
|
|
||||||
# serdisplib: Name of the underlying serdisplib driver, e.g. ctinclud. See
|
# --- serdisplib options ---
|
||||||
|
|
||||||
|
# Name of the underlying serdisplib driver, e.g. ctinclud. See
|
||||||
# serdisplib documentation for details.
|
# serdisplib documentation for details.
|
||||||
serdisp_name=t6963
|
serdisp_name=t6963
|
||||||
|
|
||||||
# serdisplib: The display device to use, e.g. serraw:/dev/ttyS0,
|
# The display device to use, e.g. serraw:/dev/ttyS0,
|
||||||
# parport:/dev/parport0 or USB:07c0/1501.
|
# parport:/dev/parport0 or USB:07c0/1501.
|
||||||
serdisp_device=/dev/ppi0
|
serdisp_device=/dev/ppi0
|
||||||
|
|
||||||
# serdisplib: Options string to pass to serdisplib during initialization. Use
|
# Options string to pass to serdisplib during initialization. Use
|
||||||
# this to set any display related options (e.g. wiring). The display size is
|
# 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
|
# always set based on the Size configured above! By default, no options are
|
||||||
# set.
|
# set.
|
||||||
# Important: The value must be quoted as it contains equal signs!
|
# Important: The value must be quoted as it contains equal signs!
|
||||||
#serdisp_options="INVERT=1"
|
#serdisp_options="INVERT=1"
|
||||||
|
|
||||||
|
# --- x11 options ---
|
||||||
|
|
||||||
|
# PixelSize is size of each dot in pixels + a pixel gap. [default: 3+1]
|
||||||
|
#x11_PixelSize=3+1
|
||||||
|
|
||||||
|
# Colors are in RRGGBB format prefixed with "0x".
|
||||||
|
# PixelColor: The color of each dot at full contrast. [default: 0x000000]
|
||||||
|
#x11_PixelColor=0x000000
|
||||||
|
|
||||||
|
# BacklightColor: The color of the backlight as full brightness.
|
||||||
|
# [default: 0x80FF80]
|
||||||
|
#x11_BacklightColor=0x80FF80
|
||||||
|
|
||||||
|
# Border: Adds a border (empty space) around the LCD portion of X11 window.
|
||||||
|
# [default: 20]
|
||||||
|
#x11_Border=20
|
||||||
|
|
||||||
|
# Inverted: inverts the pixels [default: no; legal: yes, no]
|
||||||
|
#x11_Inverted=no
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## glcdlib meta driver for graphical LCDs ##
|
## glcdlib meta driver for graphical LCDs ##
|
||||||
|
|||||||
@@ -186,6 +186,9 @@ dnl else
|
|||||||
])
|
])
|
||||||
])
|
])
|
||||||
AC_SUBST(LIBSERDISP)
|
AC_SUBST(LIBSERDISP)
|
||||||
|
if test "$enable_libX11" = yes ; then
|
||||||
|
GLCD_DRIVERS="$GLCD_DRIVERS glcd-glcd-x11.o"
|
||||||
|
fi
|
||||||
DRIVERS="$DRIVERS glcd${SO}"
|
DRIVERS="$DRIVERS glcd${SO}"
|
||||||
actdrivers=["$actdrivers glcd"]
|
actdrivers=["$actdrivers glcd"]
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -316,6 +316,29 @@ fi
|
|||||||
AC_SUBST(LIBFTDI_LIBS)
|
AC_SUBST(LIBFTDI_LIBS)
|
||||||
AC_SUBST(LIBFTDI_CFLAGS)
|
AC_SUBST(LIBFTDI_CFLAGS)
|
||||||
|
|
||||||
|
dnl ######################################################################
|
||||||
|
dnl X11 library support
|
||||||
|
dnl ######################################################################
|
||||||
|
AC_MSG_CHECKING([if X11 support has been enabled]);
|
||||||
|
AC_ARG_ENABLE(libX11,
|
||||||
|
[AS_HELP_STRING([--disable-libX11],[disable X11 support])],
|
||||||
|
[ if test "$enableval" != "no"; then
|
||||||
|
enable_libX11=yes
|
||||||
|
fi ],
|
||||||
|
[ enable_libX11=yes ]
|
||||||
|
)
|
||||||
|
AC_MSG_RESULT($enable_libX11)
|
||||||
|
|
||||||
|
if test "$enable_libX11" = "yes"; then
|
||||||
|
ifdef([PKG_CHECK_MODULES],
|
||||||
|
[PKG_CHECK_MODULES([LIBX11], [x11],
|
||||||
|
[AC_DEFINE(HAVE_LIBX11, [1], [Define to 1 if you have X11 library])],
|
||||||
|
[ enable_libX11=no ])],
|
||||||
|
[AC_MSG_WARN([pkg-config not (fully) installed; drivers requiring X11 may not be built])])
|
||||||
|
fi
|
||||||
|
AC_SUBST(LIBX11_LIBS)
|
||||||
|
AC_SUBST(LIBX11_CFLAGS)
|
||||||
|
|
||||||
dnl ######################################################################
|
dnl ######################################################################
|
||||||
dnl libhid support
|
dnl libhid support
|
||||||
dnl ######################################################################
|
dnl ######################################################################
|
||||||
|
|||||||
@@ -80,6 +80,15 @@ ignored as the size reported by the device is used.
|
|||||||
</para>
|
</para>
|
||||||
</sect3>
|
</sect3>
|
||||||
|
|
||||||
|
<sect3 id="glcd-ct-x11">
|
||||||
|
<title>Connection type x11</title>
|
||||||
|
<para>
|
||||||
|
This connection type draws the frame buffer to a X window. It features
|
||||||
|
adjustable LCD pixel size, pixel color, backlight color and simulates
|
||||||
|
contrast and brightness. PC keyboard is used to simulate buttons.
|
||||||
|
</para>
|
||||||
|
</sect3>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<sect3 id="glcd-ct-xyz">
|
<sect3 id="glcd-ct-xyz">
|
||||||
<title>Connection type xyz</title>
|
<title>Connection type xyz</title>
|
||||||
@@ -107,6 +116,7 @@ ignored as the size reported by the device is used.
|
|||||||
<parameter><literal>glcd2usb</literal></parameter> |
|
<parameter><literal>glcd2usb</literal></parameter> |
|
||||||
<parameter><literal>png</literal></parameter> |
|
<parameter><literal>png</literal></parameter> |
|
||||||
<parameter><literal>serdisplib</literal></parameter>
|
<parameter><literal>serdisplib</literal></parameter>
|
||||||
|
<parameter><literal>x11</literal></parameter>
|
||||||
}
|
}
|
||||||
</term>
|
</term>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
@@ -419,6 +429,65 @@ ignored as the size reported by the device is used.
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<title>Settings for the x11 connection type</title>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<property>x11_PixelSize</property> =
|
||||||
|
<parameter>
|
||||||
|
<replaceable>PIXELS</replaceable>
|
||||||
|
<literal>+</literal>
|
||||||
|
<replaceable>GAP</replaceable>
|
||||||
|
</parameter>
|
||||||
|
</term>
|
||||||
|
<listitem><para>
|
||||||
|
Each LCD dot is drawn in the X window as a filled rectangle of this size
|
||||||
|
plus a gap between each filled rectangle. A PixelSize of <literal>3+1</literal>
|
||||||
|
would draw a 3x3 filled rectangle with a gap of 1 pixel to the right and
|
||||||
|
bottom, effectively using a 4x4 area of the window. Default is <literal>3+1</literal>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<property>x11_PixelColor</property> =
|
||||||
|
<parameter><literal>0x</literal><replaceable>RRGGBB</replaceable></parameter>
|
||||||
|
</term>
|
||||||
|
<listitem><para>
|
||||||
|
The color used to draw each LCD dot at full contrast and full brightness.
|
||||||
|
Default is <literal>0x000000</literal>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<property>x11_BacklightColor</property> =
|
||||||
|
<parameter><literal>0x</literal><replaceable>RRGGBB</replaceable></parameter>
|
||||||
|
</term>
|
||||||
|
<listitem><para>
|
||||||
|
The color used for the backlight at full brightness.
|
||||||
|
Default is <literal>0x80FF80</literal>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<property>x11_Border</property> =
|
||||||
|
<parameter><replaceable>PIXELS</replaceable></parameter>
|
||||||
|
</term>
|
||||||
|
<listitem><para>
|
||||||
|
Extra space in pixels around the LCD portion of the X window.
|
||||||
|
Default is <literal>20</literal>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<property>x11_Inverted</property> = ¶meters.yesnodef;
|
||||||
|
</term>
|
||||||
|
<listitem><para>
|
||||||
|
Swap the colors for the pixel and backlight within the LCD portion of the
|
||||||
|
X window. This results in an inverted display.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
</sect3>
|
</sect3>
|
||||||
</sect2>
|
</sect2>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ EXTRA_PROGRAMS = bayrad CFontz CFontzPacket curses debug CwLnx ea65 EyeboxOne g1
|
|||||||
noinst_LIBRARIES = libLCD.a libbignum.a
|
noinst_LIBRARIES = libLCD.a libbignum.a
|
||||||
|
|
||||||
g15_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
|
g15_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
|
||||||
glcd_CFLAGS = @FT2_CFLAGS@ @LIBPNG_CFLAGS@ @LIBUSB_CFLAGS@ $(AM_CFLAGS)
|
glcd_CFLAGS = @FT2_CFLAGS@ @LIBPNG_CFLAGS@ @LIBUSB_CFLAGS@ @LIBX11_CFLAGS@ $(AM_CFLAGS)
|
||||||
hd44780_CFLAGS = @LIBUSB_CFLAGS@ @LIBFTDI_CFLAGS@ $(AM_CFLAGS)
|
hd44780_CFLAGS = @LIBUSB_CFLAGS@ @LIBFTDI_CFLAGS@ $(AM_CFLAGS)
|
||||||
i2500vfd_CFLAGS = @LIBFTDI_CFLAGS@ $(AM_CFLAGS)
|
i2500vfd_CFLAGS = @LIBFTDI_CFLAGS@ $(AM_CFLAGS)
|
||||||
IOWarrior_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
|
IOWarrior_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
|
||||||
@@ -44,7 +44,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@ @LIBSERDISP@ @LIBUSB_LIBS@
|
glcd_LDADD = libLCD.a @GLCD_DRIVERS@ @FT2_LIBS@ @LIBPNG_LIBS@ @LIBSERDISP@ @LIBUSB_LIBS@ @LIBX11_LIBS@
|
||||||
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
|
||||||
@@ -91,7 +91,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 t6963_low.c t6963_low.h glcd-png.c glcd-serdisp.c glcd-glcd2usb.c glcd-glcd2usb.h
|
EXTRA_glcd_SOURCES = glcd-t6963.c t6963_low.c t6963_low.h glcd-png.c glcd-serdisp.c glcd-glcd2usb.c glcd-glcd2usb.h glcd-x11.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
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ int glcd_serdisp_init(Driver *drvthis);
|
|||||||
#ifdef HAVE_LIBUSB
|
#ifdef HAVE_LIBUSB
|
||||||
int glcd2usb_init(Driver *drvthis);
|
int glcd2usb_init(Driver *drvthis);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_LIBX11
|
||||||
|
int glcd_x11_init(Driver *drvthis);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* symbolic names for connection types */
|
/* symbolic names for connection types */
|
||||||
#define GLCD_CT_UNKNOWN 0
|
#define GLCD_CT_UNKNOWN 0
|
||||||
@@ -32,6 +35,7 @@ int glcd2usb_init(Driver *drvthis);
|
|||||||
#define GLCD_CT_PNG 2
|
#define GLCD_CT_PNG 2
|
||||||
#define GLCD_CT_SERDISP 3
|
#define GLCD_CT_SERDISP 3
|
||||||
#define GLCD_CT_GLCD2USB 4
|
#define GLCD_CT_GLCD2USB 4
|
||||||
|
#define GLCD_CT_X11 5
|
||||||
|
|
||||||
/** Structure linking symbolic names to initialization routines */
|
/** Structure linking symbolic names to initialization routines */
|
||||||
typedef struct ConnectionMapping {
|
typedef struct ConnectionMapping {
|
||||||
@@ -58,6 +62,9 @@ static const ConnectionMapping connectionMapping[] = {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBUSB
|
#ifdef HAVE_LIBUSB
|
||||||
{"glcd2usb", GLCD_CT_GLCD2USB, glcd2usb_init},
|
{"glcd2usb", GLCD_CT_GLCD2USB, glcd2usb_init},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_LIBX11
|
||||||
|
{"x11", GLCD_CT_X11, glcd_x11_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}
|
||||||
|
|||||||
Executable
+440
@@ -0,0 +1,440 @@
|
|||||||
|
/** \file server/drivers/glcd-x11.c
|
||||||
|
* This driver writes the framebuffer content to an X11 window.
|
||||||
|
* Written to mimic X11 driver written for lcd4linux. Except this one does not
|
||||||
|
* have graphical buttons or cell gaps. Written to represent a graphical LCD
|
||||||
|
* only.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Scott Meharg <ssmeharg@gmail.com>
|
||||||
|
*
|
||||||
|
* 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 <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xresource.h>
|
||||||
|
|
||||||
|
#include "lcd.h"
|
||||||
|
#include "report.h"
|
||||||
|
#include "glcd-low.h"
|
||||||
|
|
||||||
|
#define X11_DEF_PIXEL_SIZE "3+1"
|
||||||
|
#define X11_DEF_PIXEL_COLOR 0x000000
|
||||||
|
#define X11_DEF_BACKLIGHT_COLOR 0x80FF80
|
||||||
|
#define X11_DEF_BORDER 20
|
||||||
|
#define X11_DEF_INVERTED 0
|
||||||
|
|
||||||
|
/** Private data for the X11 connection type */
|
||||||
|
typedef struct glcd_x11_data {
|
||||||
|
int pixel; /** Size of a LCD pixel (in screen pixels) */
|
||||||
|
int pgap; /** Gap between each LCD pixel */
|
||||||
|
int border; /** Free space around LCD area */
|
||||||
|
unsigned long bgcolor; /** Background/backlight color */
|
||||||
|
unsigned long fgcolor; /** Foreground/pixel color */
|
||||||
|
unsigned char inverted; /** Indicate swapped background/foreground */
|
||||||
|
|
||||||
|
Display *dp; /** Connection to X server */
|
||||||
|
int sc; /** Default screen number */
|
||||||
|
Window rw; /** Root window for default screen */
|
||||||
|
Window w; /** The window the LCD area will be drawn to */
|
||||||
|
Visual *vi; /** Default visual style */
|
||||||
|
GC gc; /** Default graphics context */
|
||||||
|
|
||||||
|
int dimx, dimy; /** Width/height of the X window */
|
||||||
|
Atom wmDeleteMessage; /** Atom identifier for closing the window */
|
||||||
|
|
||||||
|
unsigned char *backingstore; /** Holds a copy of the LCD screen data */
|
||||||
|
} CT_x11_data;
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
void glcd_x11_blit(PrivateData *p);
|
||||||
|
void glcd_x11_close(PrivateData *p);
|
||||||
|
unsigned char glcd_x11_pollkeys(PrivateData *p);
|
||||||
|
void glcd_x11_set_backlight(PrivateData *p, int state);
|
||||||
|
static void x11w_adj_contrast_brightness(unsigned long *pfgc, unsigned long *pbgc, int contrast,
|
||||||
|
int brightness);
|
||||||
|
static void x11w_draw_pixel(CT_x11_data * ct_data, int x, int y, unsigned long fgc,
|
||||||
|
unsigned long bgc, int backlightstate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws a single LCD pixel in the X11 window.
|
||||||
|
* \param ct_data Connection type's private data.
|
||||||
|
* \param x LCD x position.
|
||||||
|
* \param y LCD y position.
|
||||||
|
* \param fgc Foreground color.
|
||||||
|
* \param bgc Background color
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
x11w_draw_pixel(CT_x11_data * ct_data, int x, int y, unsigned long fgc, unsigned long bgc,
|
||||||
|
int backlightstate)
|
||||||
|
{
|
||||||
|
int pxlsize = ct_data->pixel + ct_data->pgap;
|
||||||
|
int xoffset = ct_data->border + (x * pxlsize);
|
||||||
|
int yoffset = ct_data->border + (y * pxlsize);
|
||||||
|
|
||||||
|
/* This basically erases the area beneath LCD pixel being drawn. */
|
||||||
|
XSetForeground(ct_data->dp, ct_data->gc, bgc);
|
||||||
|
XFillRectangle(ct_data->dp, ct_data->w, ct_data->gc, xoffset, yoffset, pxlsize, pxlsize);
|
||||||
|
|
||||||
|
/* Only draw if foreground color is different from background color.
|
||||||
|
* No need to draw the same area twice. */
|
||||||
|
if (fgc != bgc) {
|
||||||
|
XSetForeground(ct_data->dp, ct_data->gc, fgc);
|
||||||
|
XFillRectangle(ct_data->dp, ct_data->w, ct_data->gc, xoffset,
|
||||||
|
yoffset, ct_data->pixel, ct_data->pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the foreground color and background color for contrast and
|
||||||
|
* brightness.
|
||||||
|
* \param pfgc Pointer to foreground color that will be updated.
|
||||||
|
* \param pbgc Pointer to background color that will be updated.
|
||||||
|
* \param contrast The contrast value between 0 - 1000.
|
||||||
|
* \param brightness The brightness value between 0 - 1000.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
x11w_adj_contrast_brightness(unsigned long *pfgc, unsigned long *pbgc, int contrast, int brightness)
|
||||||
|
{
|
||||||
|
float adjf = 0;
|
||||||
|
|
||||||
|
unsigned long fgc = *pfgc;
|
||||||
|
unsigned long bgc = *pbgc;
|
||||||
|
|
||||||
|
unsigned char fgr = (fgc >> 16);
|
||||||
|
unsigned char fgg = ((fgc << 8) >> 16);
|
||||||
|
unsigned char fgb = ((fgc << 16) >> 16);
|
||||||
|
|
||||||
|
unsigned char bgr = (bgc >> 16);
|
||||||
|
unsigned char bgg = ((bgc << 8) >> 16);
|
||||||
|
unsigned char bgb = ((bgc << 16) >> 16);
|
||||||
|
|
||||||
|
/* Adjust contrast */
|
||||||
|
adjf = ((1000 - contrast) / (float) 1000);
|
||||||
|
|
||||||
|
fgr += ((bgr - fgr) * adjf);
|
||||||
|
fgg += ((bgg - fgg) * adjf);
|
||||||
|
fgb += ((bgb - fgb) * adjf);
|
||||||
|
|
||||||
|
|
||||||
|
/* Adjust the brightness */
|
||||||
|
adjf = ((1000 - brightness) / (float) 1000);
|
||||||
|
|
||||||
|
bgr -= (bgr * adjf);
|
||||||
|
bgg -= (bgg * adjf);
|
||||||
|
bgb -= (bgb * adjf);
|
||||||
|
|
||||||
|
fgr -= (fgr * adjf);
|
||||||
|
fgg -= (fgg * adjf);
|
||||||
|
fgb -= (fgb * adjf);
|
||||||
|
|
||||||
|
fgc = (fgr << 16) + (fgg << 8) + fgb;
|
||||||
|
bgc = (bgr << 16) + (bgg << 8) + bgb;
|
||||||
|
|
||||||
|
*pfgc = fgc;
|
||||||
|
*pbgc = bgc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API: Initialize the connection type driver.
|
||||||
|
* \param drvthis Pointer to driver structure.
|
||||||
|
* \retval 0 Success.
|
||||||
|
* \retval <0 Error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
glcd_x11_init(Driver *drvthis)
|
||||||
|
{
|
||||||
|
PrivateData *p = (PrivateData *) drvthis->private_data;
|
||||||
|
CT_x11_data *ct_data;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
report(RPT_INFO, "GLCD/x11: initializing");
|
||||||
|
|
||||||
|
/* Set up connection type low-level functions */
|
||||||
|
p->glcd_functions->blit = glcd_x11_blit;
|
||||||
|
p->glcd_functions->close = glcd_x11_close;
|
||||||
|
p->glcd_functions->poll_keys = glcd_x11_pollkeys;
|
||||||
|
p->glcd_functions->set_backlight = glcd_x11_set_backlight;
|
||||||
|
|
||||||
|
/* Allocate memory structures */
|
||||||
|
ct_data = (CT_x11_data *) calloc(1, sizeof(CT_x11_data));
|
||||||
|
if (ct_data == NULL) {
|
||||||
|
report(RPT_ERR, "GLCD/x11: error allocating connection data");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p->ct_data = ct_data;
|
||||||
|
|
||||||
|
ct_data->backingstore = malloc(p->framebuf.size);
|
||||||
|
if (ct_data->backingstore == NULL) {
|
||||||
|
report(RPT_ERR, "GLCD/x11: unable to allocate backing store");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(ct_data->backingstore, 0x00, p->framebuf.size);
|
||||||
|
|
||||||
|
/* Get and parse pixel size */
|
||||||
|
strncpy(buf, drvthis->config_get_string(drvthis->name, "x11_PixelSize",
|
||||||
|
0, X11_DEF_PIXEL_SIZE), sizeof(buf));
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
|
||||||
|
if ((sscanf(buf, "%d+%d", &ct_data->pixel, &ct_data->pgap) != 2) ||
|
||||||
|
(ct_data->pixel <= 0) || (ct_data->pgap < 0)) {
|
||||||
|
report(RPT_WARNING, "GLCD/x11: Cannot read/use PixelSize: %s; using default %s",
|
||||||
|
buf, X11_DEF_PIXEL_SIZE);
|
||||||
|
strncpy(buf, X11_DEF_PIXEL_SIZE, sizeof(buf));
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
/* this assumes X11_DEF_PIXEL_SIZE is usable */
|
||||||
|
sscanf(buf, "%d+%d", &ct_data->pixel, &ct_data->pgap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Pixel Color (pixel on color) */
|
||||||
|
ct_data->fgcolor = drvthis->config_get_int(drvthis->name,
|
||||||
|
"x11_PixelColor", 0, X11_DEF_PIXEL_COLOR);
|
||||||
|
|
||||||
|
/* Get Backlight Color (pixel off color) */
|
||||||
|
ct_data->bgcolor = drvthis->config_get_int(drvthis->name,
|
||||||
|
"x11_BacklightColor", 0,
|
||||||
|
X11_DEF_BACKLIGHT_COLOR);
|
||||||
|
|
||||||
|
/* Get Border size in pixels */
|
||||||
|
ct_data->border = drvthis->config_get_int(drvthis->name, "x11_Border", 0, X11_DEF_BORDER);
|
||||||
|
|
||||||
|
/* Get inverted setting */
|
||||||
|
ct_data->inverted =
|
||||||
|
drvthis->config_get_bool(drvthis->name, "x11_Inverted", 0, X11_DEF_INVERTED);
|
||||||
|
|
||||||
|
/* Setup X11-Window */
|
||||||
|
XSetWindowAttributes wa;
|
||||||
|
XSizeHints sh;
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
|
if ((ct_data->dp = XOpenDisplay(NULL)) == NULL) {
|
||||||
|
report(RPT_ERR, "GLCD/x11: can't open display");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ct_data->sc = DefaultScreen(ct_data->dp);
|
||||||
|
ct_data->gc = DefaultGC(ct_data->dp, ct_data->sc);
|
||||||
|
ct_data->vi = DefaultVisual(ct_data->dp, ct_data->sc);
|
||||||
|
ct_data->rw = DefaultRootWindow(ct_data->dp);
|
||||||
|
|
||||||
|
ct_data->dimx = (p->framebuf.px_width * (ct_data->pixel + ct_data->pgap))
|
||||||
|
+ (ct_data->border * 2);
|
||||||
|
ct_data->dimy = (p->framebuf.px_height * (ct_data->pixel + ct_data->pgap))
|
||||||
|
+ (ct_data->border * 2);
|
||||||
|
|
||||||
|
wa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
|
||||||
|
ButtonPressMask | ButtonReleaseMask;
|
||||||
|
|
||||||
|
sh.min_width = sh.max_width = ct_data->dimx;
|
||||||
|
sh.min_height = sh.max_height = ct_data->dimy;
|
||||||
|
sh.flags = PPosition | PSize | PMinSize | PMaxSize;
|
||||||
|
|
||||||
|
if (sh.min_width > DisplayWidth(ct_data->dp, ct_data->sc) ||
|
||||||
|
sh.min_height > DisplayHeight(ct_data->dp, ct_data->sc)) {
|
||||||
|
report(RPT_WARNING,
|
||||||
|
"GLCD/x11: Warning: X11-Window with dimensions (%d,%d) is greater than display (%d,%d)!",
|
||||||
|
sh.min_width, sh.min_height, DisplayWidth(ct_data->dp, ct_data->sc),
|
||||||
|
DisplayHeight(ct_data->dp, ct_data->sc));
|
||||||
|
if (sh.min_width > 32767 || sh.min_height > 32676) {
|
||||||
|
report(RPT_ERR, "GLCD/x11: XProtocol data size exceeded");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ct_data->w = XCreateWindow(ct_data->dp, ct_data->rw, 0, 0, sh.min_width,
|
||||||
|
sh.min_height, 0, 0, InputOutput, ct_data->vi, CWEventMask, &wa);
|
||||||
|
|
||||||
|
XSetWMProperties(ct_data->dp, ct_data->w, NULL, NULL, NULL, 0, &sh, NULL, NULL);
|
||||||
|
ct_data->wmDeleteMessage = XInternAtom(ct_data->dp, "WM_DELETE_WINDOW", False);
|
||||||
|
XSetWMProtocols(ct_data->dp, ct_data->w, &ct_data->wmDeleteMessage, 1);
|
||||||
|
|
||||||
|
XSetWindowBackground(ct_data->dp, ct_data->w, ct_data->bgcolor);
|
||||||
|
XClearWindow(ct_data->dp, ct_data->w);
|
||||||
|
|
||||||
|
XStoreName(ct_data->dp, ct_data->w, "GLCD/x11");
|
||||||
|
XMapWindow(ct_data->dp, ct_data->w);
|
||||||
|
|
||||||
|
XFlush(ct_data->dp);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
XNextEvent(ct_data->dp, &ev);
|
||||||
|
if (ev.type == Expose && ev.xexpose.count == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(RPT_DEBUG, "GLCD/x11: init() done");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API: Write the frame buffer to the display
|
||||||
|
* \param p Pointer to glcd driver's private date structure.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
glcd_x11_blit(PrivateData *p)
|
||||||
|
{
|
||||||
|
CT_x11_data *ct_data = (CT_x11_data *) p->ct_data;
|
||||||
|
|
||||||
|
/* Check if frame buffer has changed. If not there's nothing to do */
|
||||||
|
if (memcmp(p->framebuf.data, ct_data->backingstore, p->framebuf.size)
|
||||||
|
== 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned long fgc = ct_data->fgcolor;
|
||||||
|
unsigned long bgc = ct_data->bgcolor;
|
||||||
|
int y;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
/* Adjust colors for contrast and brightness */
|
||||||
|
if (p->backlightstate == 0) {
|
||||||
|
x11w_adj_contrast_brightness(&fgc, &bgc, p->contrast, p->offbrightness);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x11w_adj_contrast_brightness(&fgc, &bgc, p->contrast, p->brightness);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw each LCD pixel on the X11 window. */
|
||||||
|
for (y = 0; y < p->framebuf.px_height; y++) {
|
||||||
|
for (x = 0; x < p->framebuf.px_width; x++) {
|
||||||
|
if ((fb_get_pixel(&p->framebuf, x, y) ^ ct_data->inverted) == FB_BLACK)
|
||||||
|
x11w_draw_pixel(ct_data, x, y, fgc, bgc, p->backlightstate);
|
||||||
|
else
|
||||||
|
x11w_draw_pixel(ct_data, x, y, bgc, bgc, p->backlightstate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XFlush(ct_data->dp);
|
||||||
|
memcpy(ct_data->backingstore, p->framebuf.data, p->framebuf.size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API: Release low-level resources.
|
||||||
|
* \param p Pointer to glcd driver's private date structure.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
glcd_x11_close(PrivateData *p)
|
||||||
|
{
|
||||||
|
if (p->ct_data != NULL) {
|
||||||
|
CT_x11_data *ct_data = (CT_x11_data *) p->ct_data;
|
||||||
|
|
||||||
|
if (ct_data->dp != NULL) {
|
||||||
|
XCloseDisplay(ct_data->dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ct_data->backingstore != NULL)
|
||||||
|
free(ct_data->backingstore);
|
||||||
|
|
||||||
|
free(p->ct_data);
|
||||||
|
p->ct_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API: Poll for key presses.
|
||||||
|
* \param p Pointer to glcd driver's private data structure.
|
||||||
|
*/
|
||||||
|
unsigned char
|
||||||
|
glcd_x11_pollkeys(PrivateData *p)
|
||||||
|
{
|
||||||
|
CT_x11_data *ct_data = (CT_x11_data *) p->ct_data;
|
||||||
|
unsigned char rv = 0;
|
||||||
|
|
||||||
|
XEvent ev;
|
||||||
|
KeySym key;
|
||||||
|
|
||||||
|
if (XCheckWindowEvent(ct_data->dp, ct_data->w, KeyPressMask |
|
||||||
|
KeyReleaseMask | ButtonPressMask | ButtonReleaseMask, &ev) == 0
|
||||||
|
&& XCheckTypedWindowEvent(ct_data->dp, ct_data->w, ClientMessage, &ev) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (ev.type) {
|
||||||
|
case KeyPress:
|
||||||
|
key = XLookupKeysym(&ev.xkey, 0);
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case XK_Up:
|
||||||
|
rv = 1;
|
||||||
|
break;
|
||||||
|
case XK_Down:
|
||||||
|
rv = 2;
|
||||||
|
break;
|
||||||
|
case XK_Left:
|
||||||
|
rv = 3;
|
||||||
|
break;
|
||||||
|
case XK_Right:
|
||||||
|
rv = 4;
|
||||||
|
break;
|
||||||
|
case XK_Return:
|
||||||
|
rv = 5;
|
||||||
|
break;
|
||||||
|
case XK_Escape:
|
||||||
|
rv = 6;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ClientMessage:
|
||||||
|
if ((Atom) (ev.xclient.data.l[0]) == ct_data->wmDeleteMessage) {
|
||||||
|
p->glcd_functions->drv_report(RPT_INFO,
|
||||||
|
"GLCD/x11: Window closed by WindowManager");
|
||||||
|
|
||||||
|
if (raise(SIGTERM) != 0) {
|
||||||
|
p->glcd_functions->drv_report(RPT_ERR,
|
||||||
|
"GLCD/x11: Error raising SIGTERM");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p->glcd_functions->drv_report(RPT_DEBUG,
|
||||||
|
"GLCD/x11: Get XClient message 0x!lx %lx %lx %lx %lx",
|
||||||
|
ev.xclient.data.l[0], ev.xclient.data.l[1],
|
||||||
|
ev.xclient.data.l[2], ev.xclient.data.l[3],
|
||||||
|
ev.xclient.data.l[4]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API: Switch backlight on and off.
|
||||||
|
* \param p Pointer to glcd driver's private data structure.
|
||||||
|
* \param state State of backlight.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
glcd_x11_set_backlight(PrivateData *p, int state)
|
||||||
|
{
|
||||||
|
CT_x11_data *ct_data = p->ct_data;
|
||||||
|
|
||||||
|
unsigned long fgc = ct_data->fgcolor;
|
||||||
|
unsigned long bgc = ct_data->bgcolor;
|
||||||
|
|
||||||
|
if (state == 0) {
|
||||||
|
x11w_adj_contrast_brightness(&fgc, &bgc, p->contrast, p->offbrightness);
|
||||||
|
XSetWindowBackground(ct_data->dp, ct_data->w, bgc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x11w_adj_contrast_brightness(&fgc, &bgc, p->contrast, p->brightness);
|
||||||
|
XSetWindowBackground(ct_data->dp, ct_data->w, bgc);
|
||||||
|
}
|
||||||
|
|
||||||
|
XClearWindow(ct_data->dp, ct_data->w);
|
||||||
|
memset(ct_data->backingstore, 0, p->framebuf.size);
|
||||||
|
}
|
||||||
@@ -574,7 +574,7 @@ glcd_get_contrast(Driver *drvthis)
|
|||||||
{
|
{
|
||||||
PrivateData *p = drvthis->private_data;
|
PrivateData *p = drvthis->private_data;
|
||||||
|
|
||||||
debug(RPT_INFO, "%s()", __FUNCTION__);
|
debug(RPT_DEBUG, "%s()", __FUNCTION__);
|
||||||
|
|
||||||
return p->contrast;
|
return p->contrast;
|
||||||
}
|
}
|
||||||
@@ -590,7 +590,7 @@ glcd_set_contrast(Driver *drvthis, int promille)
|
|||||||
{
|
{
|
||||||
PrivateData *p = drvthis->private_data;
|
PrivateData *p = drvthis->private_data;
|
||||||
|
|
||||||
debug(RPT_INFO, "%s(%i)", __FUNCTION__, promille);
|
debug(RPT_DEBUG, "%s(%i)", __FUNCTION__, promille);
|
||||||
|
|
||||||
/* Check it */
|
/* Check it */
|
||||||
if (promille < 0 || promille > 1000)
|
if (promille < 0 || promille > 1000)
|
||||||
|
|||||||
Reference in New Issue
Block a user