LCDproc development and user support list

Text archives Help


[Lcdproc] [PATCH] New driver linux_input


Chronological Thread 
  • From: harald at ccbib.org (Harald Geyer)
  • Subject: [Lcdproc] [PATCH] New driver linux_input
  • Date: Fri, 11 Dec 2015 12:49:05 +0100

This driver receives input from event devices of the linux input subsystem.
Tested on Debian/i386. Compile tested on OpenWRT/arm.

Signed-off-by: Harald Geyer <harald at ccbib.org>
---
LCDd.conf | 17 +-
acinclude.m4 | 12 +-
docs/LCDd.8.in | 3 +
docs/lcdproc-user/drivers.docbook | 1 +
docs/lcdproc-user/drivers/linux_input.docbook | 57 +++++++
docs/lcdproc-user/lcdproc-user.docbook | 1 +
server/drivers/Makefile.am | 3 +-
server/drivers/linux_input.c | 230
++++++++++++++++++++++++++
server/drivers/linux_input.h | 11 ++
9 files changed, 331 insertions(+), 4 deletions(-)
create mode 100644 docs/lcdproc-user/drivers/linux_input.docbook
create mode 100644 server/drivers/linux_input.c
create mode 100644 server/drivers/linux_input.h

diff --git a/LCDd.conf b/LCDd.conf
index f0ac69b..41aa8dd 100644
--- a/LCDd.conf
+++ b/LCDd.conf
@@ -46,7 +46,7 @@ DriverPath=server/drivers/
# The following drivers are supported:
# bayrad, CFontz, CFontzPacket, curses, CwLnx, ea65, EyeboxOne, g15, glcd,
# glcdlib, glk, hd44780, icp_a106, imon, imonlcd,, IOWarrior, irman, joy,
-# lb216, lcdm001, lcterm, lirc, lis, MD8800,, mdm166a, ms6931, mtc_s16209x,
+# lb216, lcdm001, lcterm, linux_input, lirc, lis, MD8800, mdm166a, ms6931,
mtc_s16209x,
# MtxOrb, mx5000, NoritakeVFD, picolcd,, pyramid, rawserial, sdeclcd,
# sed1330, sed1520, serialPOS, serialVFD, shuttleVFD, sli,, stv5730, svga,
# t6963, text, tyan, ula200, vlsys_m428, xosd
@@ -797,6 +797,21 @@ Device=/dev/ttyS1
Size=16x2


+## Linux event device input driver ##
+[linux_input]
+
+# Select the input device to use [default: /dev/input/event0]
+Device=/dev/input/event0
+
+# specify a non-default key map
+#key=1,Escape
+#key=28,Enter
+#key=96,Enter
+#key=105,Left
+#key=106,Right
+#key=103,Up
+#key=108,Down
+

## LIRC input driver ##
[lirc]
diff --git a/acinclude.m4 b/acinclude.m4
index 76ca6c5..2802f5d 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -11,7 +11,7 @@ AC_ARG_ENABLE(drivers,
[ bayrad,CFontz,CFontzPacket,curses,CwLnx,ea65,]
[ EyeboxOne,g15,glcd,glcdlib,glk,hd44780,i2500vfd,]
[ icp_a106,imon,imonlcd,IOWarrior,irman,irtrans,]
- [
joy,lb216,lcdm001,lcterm,lirc,lis,MD8800,mdm166a,]
+ [
joy,lb216,lcdm001,lcterm,linux_input,lirc,lis,MD8800,mdm166a,]
[ ms6931,mtc_s16209x,MtxOrb,mx5000,NoritakeVFD,]
[
picolcd,pyramid,rawserial,sdeclcd,sed1330,sed1520,]
[
serialPOS,serialVFD,shuttleVFD,sli,stv5730,SureElec,]
@@ -22,7 +22,7 @@ AC_ARG_ENABLE(drivers,
drivers="$enableval",

drivers=[bayrad,CFontz,CFontzPacket,curses,CwLnx,glk,lb216,lcdm001,MtxOrb,pyramid,text])

-allDrivers=[bayrad,CFontz,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,g15,glcd,glcdlib,glk,hd44780,i2500vfd,icp_a106,imon,imonlcd,IOWarrior,irman,irtrans,joy,lb216,lcdm001,lcterm,lirc,lis,MD8800,mdm166a,ms6931,mtc_s16209x,MtxOrb,mx5000,NoritakeVFD,picolcd,pyramid,sdeclcd,sed1330,sed1520,serialPOS,serialVFD,shuttleVFD,sli,stv5730,SureElec,svga,t6963,text,tyan,ula200,vlsys_m428,xosd,rawserial]
+allDrivers=[bayrad,CFontz,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,g15,glcd,glcdlib,glk,hd44780,i2500vfd,icp_a106,imon,imonlcd,IOWarrior,irman,irtrans,joy,lb216,lcdm001,lcterm,linux_input,lirc,lis,MD8800,mdm166a,ms6931,mtc_s16209x,MtxOrb,mx5000,NoritakeVFD,picolcd,pyramid,sdeclcd,sed1330,sed1520,serialPOS,serialVFD,shuttleVFD,sli,stv5730,SureElec,svga,t6963,text,tyan,ula200,vlsys_m428,xosd,rawserial]
if test "$debug" = yes; then
allDrivers=["${allDrivers},debug"]
fi
@@ -310,6 +310,14 @@ dnl else
DRIVERS="$DRIVERS lcterm${SO}"
actdrivers=["$actdrivers lcterm"]
;;
+ linux_input)
+ case $host in
+ *-*-linux*)
+ DRIVERS="$DRIVERS linux_input${SO}"
+ actdrivers=["$actdrivers linux_input"]
+ ;;
+ esac
+ ;;
lirc)
AC_CHECK_LIB(lirc_client, main,[
LIBLIRC_CLIENT="-llirc_client"
diff --git a/docs/LCDd.8.in b/docs/LCDd.8.in
index 977e22d..6028b91 100644
--- a/docs/LCDd.8.in
+++ b/docs/LCDd.8.in
@@ -247,6 +247,9 @@ kernelconcepts.de 20x4 serial LCD displays
.B lcterm
serial LCD terminal from Helmut Neumark Elektronik (http://www.neumark.de)
.TP
+.B linux_input
+Linux event devices (input)
+.TP
.B lirc
Infrared (input)
.TP
diff --git a/docs/lcdproc-user/drivers.docbook
b/docs/lcdproc-user/drivers.docbook
index 72a4244..e9a83f7 100644
--- a/docs/lcdproc-user/drivers.docbook
+++ b/docs/lcdproc-user/drivers.docbook
@@ -30,6 +30,7 @@ well as the configuration of LCDd.
&lb216;
&lcdm001;
&lcterm;
+&linux_input;
&lirc;
&lis;
&MD8800;
diff --git a/docs/lcdproc-user/drivers/linux_input.docbook
b/docs/lcdproc-user/drivers/linux_input.docbook
new file mode 100644
index 0000000..394d361
--- /dev/null
+++ b/docs/lcdproc-user/drivers/linux_input.docbook
@@ -0,0 +1,57 @@
+<sect1 id="linux_input-howto">
+<title>The Linux Event Device Input Driver</title>
+
+<para>
+This section covers the linux event device input driver for LCDd.
+</para>
+
+<!-- ## Linux input driver ## -->
+<sect2 id="linux_input-config">
+<title>Configuration in LCDd.conf</title>
+
+<sect3 id="linux_input-config-section">
+<title>[linux_input]</title>
+
+<variablelist>
+<varlistentry>
+ <term>
+ <property>Device</property> =
+ <parameter><replaceable>DEVICE</replaceable></parameter>
+ </term>
+ <listitem><para>
+ Select the input device to use [default:
<filename>/dev/input/event0</filename>]
+ </para></listitem>
+</varlistentry>
+
+<varlistentry>
+ <term>
+ <property>key</property> =
+
<parameter><replaceable>KEYCODE</replaceable>,<replaceable>KEY</replaceable></parameter>
+ </term>
+ <listitem>
+ <para>
+ Set an alternate key map, e.g. to use custom buttons instead of the
+ standard codes for Escape, Enter, Left, Right, Up and Down. This entry
+ typically repeaded for any non-standard key code.
+ </para>
+
+ <para>
+ <replaceable>KEYCODE</replaceable> is an integer like the ones defined in
+ <filename>/usr/include/linux/input.h</filename>.
+ </para>
+
+ <para>
+ <replaceable>KEY</replaceable> can be one of the keys that LCDd
recognizes
+ (<literal>Left</literal>, <literal>Right</literal>,
<literal>Up</literal>,
+ <literal>Down</literal>, <literal>Enter</literal> or
<literal>Escape</literal>)
+ or any other string that a client can parse.
+ </para>
+ </listitem>
+</varlistentry>
+</variablelist>
+
+</sect3>
+
+</sect2>
+
+</sect1>
diff --git a/docs/lcdproc-user/lcdproc-user.docbook
b/docs/lcdproc-user/lcdproc-user.docbook
index 1c73ed6..b3ec38d 100644
--- a/docs/lcdproc-user/lcdproc-user.docbook
+++ b/docs/lcdproc-user/lcdproc-user.docbook
@@ -37,6 +37,7 @@
<!ENTITY lb216 SYSTEM "drivers/lb216.docbook">
<!ENTITY lcdm001 SYSTEM "drivers/lcdm001.docbook">
<!ENTITY lcterm SYSTEM "drivers/lcterm.docbook">
+ <!ENTITY linux_input SYSTEM "drivers/linux_input.docbook">
<!ENTITY lirc SYSTEM "drivers/lircin.docbook">
<!ENTITY lis SYSTEM "drivers/lis.docbook">
<!ENTITY MD8800 SYSTEM "drivers/MD8800.docbook">
diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am
index 0fa38f2..9787e0f 100644
--- a/server/drivers/Makefile.am
+++ b/server/drivers/Makefile.am
@@ -23,7 +23,7 @@ AM_LDFLAGS = @LDSHARED@

lcdexecbindir = $(pkglibdir)
lcdexecbin_PROGRAMS = @DRIVERS@
-EXTRA_PROGRAMS = bayrad CFontz CFontzPacket curses CwLnx debug ea65
EyeboxOne g15 glcd glcdlib glk hd44780 i2500vfd icp_a106 imon imonlcd
IOWarrior irman irtrans joy lb216 lcdm001 lcterm lirc lis MD8800 mdm166a
ms6931 mtc_s16209x MtxOrb mx5000 NoritakeVFD picolcd pyramid rawserial
sdeclcd sed1330 sed1520 serialPOS serialVFD shuttleVFD sli stv5730 SureElec
svga t6963 text tyan ula200 vlsys_m428 xosd
+EXTRA_PROGRAMS = bayrad CFontz CFontzPacket curses CwLnx debug ea65
EyeboxOne g15 glcd glcdlib glk hd44780 i2500vfd icp_a106 imon imonlcd
IOWarrior irman irtrans joy lb216 lcdm001 lcterm linux_input lirc lis MD8800
mdm166a ms6931 mtc_s16209x MtxOrb mx5000 NoritakeVFD picolcd pyramid
rawserial sdeclcd sed1330 sed1520 serialPOS serialVFD shuttleVFD sli stv5730
SureElec svga t6963 text tyan ula200 vlsys_m428 xosd
noinst_LIBRARIES = libLCD.a libbignum.a

g15_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
@@ -107,6 +107,7 @@ joy_SOURCES = lcd.h joy.c joy.h port.h report.h
lb216_SOURCES = lcd.h lcd_lib.h lb216.c lb216.h report.h
lcdm001_SOURCES = lcd.h lcdm001.c lcdm001.h report.h
lcterm_SOURCES = lcd.h lcd_lib.h lcterm.c lcterm.h report.h
+linux_input_SOURCES = lcd.h linux_input.h linux_input.c report.h
lirc_SOURCES = lcd.h lircin.c lircin.h report.h
lis_SOURCES = lcd.h lcd_lib.h lis.h lis.c report.h
MD8800_SOURCES = lcd.h lcd_lib.h MD8800.c MD8800.h report.h
diff --git a/server/drivers/linux_input.c b/server/drivers/linux_input.c
new file mode 100644
index 0000000..86a3855
--- /dev/null
+++ b/server/drivers/linux_input.c
@@ -0,0 +1,230 @@
+/** \file server/drivers/linux_input.c
+ * LCDd \c linux event device driver for inputting data from the input
+ * subsystem of the linux kernel..
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/input.h>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "lcd.h"
+#include "linux_input.h"
+#include "report.h"
+#include "shared/LL.h"
+
+#define LINUXINPUT_DEFAULT_DEVICE "/dev/input/event0"
+
+/** describe the button of a keycode */
+struct keycode {
+ unsigned short code;
+ char *button;
+};
+
+/**
+ * Parse key definition from config file
+ * \param configvalue value part of the config file entry
+ * \retval NULL Error.
+ * \retval else Pointer to newly allocated struct keycode.
+ */
+static struct keycode *
+keycode_create(const char *configvalue)
+{
+ int code;
+ char *button;
+ struct keycode *ret;
+
+ code = atoi(configvalue);
+ if (code < 0 || code > UINT16_MAX)
+ return NULL;
+
+ button = strchr(configvalue,',');
+ if (!button)
+ return NULL;
+ button = strdup(&button[1]);
+ if (!button)
+ return NULL;
+
+ ret = malloc(sizeof(*ret));
+ if (ret) {
+ ret->code = code;
+ ret->button = button;
+ }
+
+ return ret;
+}
+
+/** private data for the linux event device driver */
+typedef struct linuxInput_private_data {
+ int fd;
+ LinkedList *buttonmap;
+} PrivateData;
+
+
+// Vars for the server core
+MODULE_EXPORT char *api_version = API_VERSION;
+MODULE_EXPORT int stay_in_foreground = 0;
+MODULE_EXPORT int supports_multiple = 1;
+MODULE_EXPORT char *symbol_prefix = "linuxInput_";
+
+
+/**
+ * Initialize the driver.
+ * \param drvthis Pointer to driver structure.
+ * \retval 0 Success.
+ * \retval <0 Error.
+ */
+MODULE_EXPORT int
+linuxInput_init (Driver *drvthis)
+{
+ PrivateData *p;
+ const char *s;
+ struct keycode *key;
+ int i;
+
+ /* Allocate and store private data */
+ p = (PrivateData *) calloc(1, sizeof(PrivateData));
+ if (p == NULL)
+ return -1;
+ if (drvthis->store_private_ptr(drvthis, p))
+ return -1;
+
+ /* initialize private data */
+ p->fd = -1;
+ if ((p->buttonmap = LL_new()) == NULL) {
+ report(RPT_ERR, "%s: cannot allocate memory for buttons",
drvthis->name);
+ return -1;
+ }
+
+ /* Read config file */
+
+ /* What device should be used */
+ s = drvthis->config_get_string(drvthis->name, "Device", 0,
+ LINUXINPUT_DEFAULT_DEVICE);
+ report(RPT_INFO, "%s: using Device %s", drvthis->name, s);
+
+
+ if ((p->fd = open(s, O_RDONLY | O_NONBLOCK)) < 0) {
+ report(RPT_ERR, "%s: open(%s) failed (%s)",
+ drvthis->name, s, strerror(errno));
+ return -1;
+ }
+
+ for (i = 0; (s = drvthis->config_get_string(drvthis->name, "key", i,
NULL)) != NULL; i++) {
+ if ((key = keycode_create(s)) == NULL) {
+ report(RPT_ERR, "%s: parsing configvalue '%s' failed",
+ drvthis->name, s);
+ continue;
+ }
+ LL_AddNode(p->buttonmap, key);
+ }
+
+ report(RPT_DEBUG, "%s: init() done", drvthis->name);
+
+ return 0;
+}
+
+
+/**
+ * Close the driver (do necessary clean-up).
+ * \param drvthis Pointer to driver structure.
+ */
+MODULE_EXPORT void
+linuxInput_close (Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+ struct keycode *k;
+
+ if (p != NULL) {
+ if (p->fd >= 0)
+ close(p->fd);
+
+ if (p->buttonmap != NULL) {
+ while ((k = LL_Pop(p->buttonmap)) != NULL) {
+ free(k->button);
+ free(k);
+ }
+ LL_Destroy(p->buttonmap);
+ }
+
+ free(p);
+ }
+ drvthis->store_private_ptr(drvthis, NULL);
+}
+
+
+/**
+ * Helper function to check LL items against a given key code.
+ * \param data Pointer to data of list item
+ * \param codep Pointer to value holding the received key code
+ * \retval 0 We found the right item.
+ * \retval else We need to continue searching.
+ */
+static int
+compare_with_keycode (void *data, void *codep)
+{
+ uint16_t code = *(uint16_t *)codep;
+ struct keycode *k = data;
+
+ return k->code != code;
+}
+
+/**
+ * Read the next input event.
+ * \param drvthis Pointer to driver structure.
+ * \retval String representation of the key;
+ * \c NULL for nothing available / error.
+ */
+MODULE_EXPORT const char *
+linuxInput_get_key (Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+ struct input_event event;
+ struct keycode *k;
+
+ if (read(p->fd, &event, sizeof(event)) != sizeof(event))
+ return NULL;
+
+ /* Ignore release events and not-key events */
+ if (event.type != EV_KEY || event.value == 0)
+ return NULL;
+
+ switch (event.code) {
+ case KEY_ESC:
+ return "Escape";
+
+ case KEY_UP:
+ return "Up";
+
+ case KEY_LEFT:
+ return "Left";
+
+ case KEY_RIGHT:
+ return "Right";
+
+ case KEY_DOWN:
+ return "Down";
+
+ case KEY_ENTER:
+ case KEY_KPENTER:
+ return "Enter";
+
+ default:
+ LL_Rewind(p->buttonmap);
+ k = LL_Find(p->buttonmap, compare_with_keycode, &event.code);
+ if (k)
+ return k->button;
+
+ return NULL;
+ }
+}
diff --git a/server/drivers/linux_input.h b/server/drivers/linux_input.h
new file mode 100644
index 0000000..8477f58
--- /dev/null
+++ b/server/drivers/linux_input.h
@@ -0,0 +1,11 @@
+#ifndef LINUX_INPUT_H
+#define LINUX_INPUT_H
+
+#include "lcd.h"
+
+MODULE_EXPORT int linuxInput_init (Driver *drvthis);
+MODULE_EXPORT void linuxInput_close (Driver *drvthis);
+
+MODULE_EXPORT const char *linuxInput_get_key (Driver *drvthis);
+
+#endif

--
If you want to support my work:
see http://friends.ccbib.org/harald/supporting/
or donate via bitcoin to 1FUtd8T9jRN1rFz63vZz7s2fDtB6d6A7aS




Archive powered by MHonArc 2.6.18.

Top of page