From 374a0c10e3a43f9ab4710c9096dffa3845ea57bb Mon Sep 17 00:00:00 2001 From: awiouy Date: Fri, 14 Oct 2016 14:34:35 +0200 Subject: [PATCH] lcdd: initial addon --- packages/addons/service/lcdd/changelog.txt | 2 + packages/addons/service/lcdd/icon/icon.png | Bin 0 -> 35102 bytes packages/addons/service/lcdd/package.mk | 80 + .../lcdd-0.5.6-dm140_henlar_v0.2.patch | 1643 +++++++++++++++++ .../lcdd/patches/lcdd-0.5.6-libftdi1.patch | 65 + .../lcdd-fujitsu_siemens_scaleo_e.patch | 56 + .../service/lcdd/resources/settings.xml | 6 + .../addons/service/lcdd/source/bin/lcdd.start | 37 + .../addons/service/lcdd/source/default.py | 35 + .../resources/language/English/strings.po | 11 + .../lcdd/source/system.d/service.lcdd.service | 14 + 11 files changed, 1949 insertions(+) create mode 100644 packages/addons/service/lcdd/changelog.txt create mode 100644 packages/addons/service/lcdd/icon/icon.png create mode 100644 packages/addons/service/lcdd/package.mk create mode 100644 packages/addons/service/lcdd/patches/lcdd-0.5.6-dm140_henlar_v0.2.patch create mode 100644 packages/addons/service/lcdd/patches/lcdd-0.5.6-libftdi1.patch create mode 100644 packages/addons/service/lcdd/patches/lcdd-fujitsu_siemens_scaleo_e.patch create mode 100644 packages/addons/service/lcdd/resources/settings.xml create mode 100644 packages/addons/service/lcdd/source/bin/lcdd.start create mode 100644 packages/addons/service/lcdd/source/default.py create mode 100644 packages/addons/service/lcdd/source/resources/language/English/strings.po create mode 100644 packages/addons/service/lcdd/source/system.d/service.lcdd.service diff --git a/packages/addons/service/lcdd/changelog.txt b/packages/addons/service/lcdd/changelog.txt new file mode 100644 index 0000000000..ffbebe8438 --- /dev/null +++ b/packages/addons/service/lcdd/changelog.txt @@ -0,0 +1,2 @@ +100 +- Initial addon diff --git a/packages/addons/service/lcdd/icon/icon.png b/packages/addons/service/lcdd/icon/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5c77d84763d38b5d1579b56963def1ef3931552c GIT binary patch literal 35102 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. +################################################################################ + +PKG_NAME="lcdd" +PKG_VERSION="0.5.7-cvs20140217" +PKG_REV="100" +PKG_ARCH="any" +PKG_LICENSE="GPL" +PKG_SITE="http://lcdproc.org/" +PKG_URL="$DISTRO_SRC/lcdproc-$PKG_VERSION.tar.xz" +PKG_SOURCE_DIR="lcdproc-$PKG_VERSION" +PKG_DEPENDS_TARGET="toolchain freetype libftdi1 libhid libusb netbsd-curses serdisplib" +PKG_SECTION="service" +PKG_SHORTDESC="LCDproc: Software to display system information from your Linux/*BSD box on a LCD" +PKG_LONGDESC="LCDproc ($PKG_VERSION) is a piece of software that displays real-time system information from your Linux/*BSD box on a LCD. The server supports several serial devices: Matrix Orbital, Crystal Fontz, Bayrad, LB216, LCDM001 (kernelconcepts.de), Wirz-SLI, Cwlinux(.com) and PIC-an-LCD; and some devices connected to the LPT port: HD44780, STV5730, T6963, SED1520 and SED1330. Various clients are available that display things like CPU load, system load, memory usage, uptime, and a lot more." +PKG_AUTORECONF="yes" + +PKG_IS_ADDON="yes" +PKG_ADDON_NAME="LCDproc" +PKG_ADDON_TYPE="xbmc.service" + +PKG_CONFIGURE_OPTS_TARGET="--with-ft-prefix=$SYSROOT_PREFIX/usr \ + --enable-libusb \ + --enable-libftdi \ + --disable-libX11 \ + --enable-libhid \ + --disable-libpng \ + --enable-drivers=all \ + --enable-seamless-hbars" + +pre_make_target() { + # dont build parallel + MAKEFLAGS=-j1 +} + +addon() { + drivers="none|$(cat $ROOT/$PKG_BUILD/.$TARGET_NAME/config.log | sed -n "s|^DRIVERS=' \(.*\)'|\1|p" | sed "s|.so||g" | tr ' ' '|')" + + mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/config + + cp -PR $PKG_DIR/resources $ADDON_BUILD/$PKG_ADDON_ID + + cp -PR $PKG_BUILD/.install_pkg/etc/LCDd.conf $ADDON_BUILD/$PKG_ADDON_ID/config/ + cp -PR $PKG_BUILD/.install_pkg/usr/lib $ADDON_BUILD/$PKG_ADDON_ID/lib/ + cp -PR $PKG_BUILD/.install_pkg/usr/sbin $ADDON_BUILD/$PKG_ADDON_ID/bin/ + + cp -L $(get_build_dir serdisplib)/.install_pkg/usr/lib/libserdisp.so.1 $ADDON_BUILD/$PKG_ADDON_ID/lib/ + + sed -e "s|^DriverPath=.*$|DriverPath=/storage/.kodi/addons/service.lcdd/lib/lcdproc/|" \ + -e "s|^#Foreground=.*$|Foreground=no|" \ + -e "s|^#ServerScreen=.*$|ServerScreen=blank|" \ + -e "s|^#Backlight=.*$|Backlight=open|" \ + -e "s|^#Heartbeat=.*$|Heartbeat=open|" \ + -e "s|^#TitleSpeed=.*$|TitleSpeed=4|" \ + -e "s|^#Hello=\" Welcome to\"|Hello=\"Welcome to\"|" \ + -e "s|^#Hello=\" LCDproc!\"|Hello=\"$DISTRONAME\"|" \ + -e "s|^#GoodBye=\"Thanks for using\"|GoodBye=\"Thanks for using\"|" \ + -e "s|^#GoodBye=\" LCDproc!\"|GoodBye=\"$DISTRONAME\"|" \ + -e "s|^#normal_font=.*$|normal_font=/usr/share/fonts/liberation/LiberationMono-Bold.ttf|" \ + -i $ADDON_BUILD/$PKG_ADDON_ID/config/LCDd.conf + + sed -e "s/@DRIVERS@/$drivers/" \ + -i $ADDON_BUILD/$PKG_ADDON_ID/resources/settings.xml + +} diff --git a/packages/addons/service/lcdd/patches/lcdd-0.5.6-dm140_henlar_v0.2.patch b/packages/addons/service/lcdd/patches/lcdd-0.5.6-dm140_henlar_v0.2.patch new file mode 100644 index 0000000000..4570216b50 --- /dev/null +++ b/packages/addons/service/lcdd/patches/lcdd-0.5.6-dm140_henlar_v0.2.patch @@ -0,0 +1,1643 @@ +diff -Naur lcdproc-0.5.6-old/acinclude.m4 lcdproc-0.5.6-new/acinclude.m4 +--- lcdproc-0.5.6-old/acinclude.m4 2012-09-01 14:34:24.000000000 -0700 ++++ lcdproc-0.5.6-new/acinclude.m4 2012-11-14 12:06:48.000000000 -0800 +@@ -9,7 +9,7 @@ + [ which is a comma-separated list of drivers.] + [ Possible drivers are:] + [ bayrad,CFontz,CFontzPacket,curses,CwLnx,] +- [ ea65,EyeboxOne,g15,glcd,glcdlib,glk,hd44780,i2500vfd,] ++ [ dm140,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,] +@@ -22,7 +22,7 @@ + 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] ++allDrivers=[bayrad,CFontz,CFontzPacket,curses,CwLnx,dm140,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] + if test "$debug" = yes; then + allDrivers=["${allDrivers},debug"] + fi +@@ -127,6 +127,10 @@ + DRIVERS="$DRIVERS debug${SO}" + actdrivers=["$actdrivers debug"] + ;; ++ dm140) ++ DRIVERS="$DRIVERS dm140${SO}" ++ actdrivers=["$actdrivers dm140"] ++ ;; + ea65) + DRIVERS="$DRIVERS ea65${SO}" + actdrivers=["$actdrivers ea65"] +diff -Naur lcdproc-0.5.6-old/LCDd.conf lcdproc-0.5.6-new/LCDd.conf +--- lcdproc-0.5.6-old/LCDd.conf 2012-08-19 07:29:07.000000000 -0700 ++++ lcdproc-0.5.6-new/LCDd.conf 2012-11-14 12:06:25.000000000 -0800 +@@ -290,6 +290,10 @@ + + + ++## DM140 VFD ++[dm140] ++ ++ + ## ea65 driver for the display in AOpen XC Cube AV EA65 media barebones ## + [ea65] + +diff -Naur lcdproc-0.5.6-old/LCDd.conf.orig lcdproc-0.5.6-new/LCDd.conf.orig +diff -Naur lcdproc-0.5.6-old/server/drivers/dm140.c lcdproc-0.5.6-new/server/drivers/dm140.c +--- lcdproc-0.5.6-old/server/drivers/dm140.c 1969-12-31 16:00:00.000000000 -0800 ++++ lcdproc-0.5.6-new/server/drivers/dm140.c 2012-11-14 12:06:25.000000000 -0800 +@@ -0,0 +1,241 @@ ++/* ++ * dm1400 vfd driver (c)2007 Henrik Larsson ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "lcd.h" ++#include "dm140.h" ++ ++#include "report.h" ++#include "lcd_lib.h" ++#include "libvfd.h" ++#include "led.h" ++ ++#ifdef HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++ ++/* Vars for the server core */ ++MODULE_EXPORT char *api_version = API_VERSION; ++MODULE_EXPORT int stay_in_foreground = 0; ++MODULE_EXPORT int supports_multiple = 0; ++MODULE_EXPORT char *symbol_prefix = "dm140_"; ++ ++ ++MODULE_EXPORT int ++dm140_init (Driver *drvthis) ++{ ++ PrivateData *p; ++ int i; ++ ++ /* Allocate and store private data */ ++ p = (PrivateData *) calloc(1, sizeof(PrivateData)); ++ if (p == NULL) ++ { ++ report(RPT_CRIT, "Failed to allocate memory for PrivateData\n"); ++ return -1; ++ } ++ ++ if (drvthis->store_private_ptr(drvthis, p)) ++ { ++ report(RPT_CRIT, "Failed to store Private Ptr!"); ++ return -1; ++ } ++ ++ /* initialize private data */ ++ p->width = 18; ++ p->height = 2; ++ p->pszVendor = "040b"; ++ p->pszProduct = "7001"; ++ ++ p->gIconMask = 0; ++ p->gLayout = VFD_STR_LAYOUT_1; ++ p->gScrollTime = 1; ++ p->gFlags = 0; ++ p->gDisplayMode = VFD_MODE_NONE; ++ ++ if ((p->framebuf = (char *) calloc(1, p->height)) == NULL) ++ { ++ report(RPT_CRIT, "Allocating memory for framebuffer Failed\n"); ++ return -1; ++ } ++ ++ for (i=0; iheight; i++) ++ { ++ p->framebuf[i] = (char *) calloc(1, p->width+1); ++ report(RPT_INFO, "Allocating memory for framebuffer[%d]\n", i); ++ if (p->framebuf == NULL) ++ return -1; ++ } ++ ++ if((p->fd = OpenHID(drvthis))< 0) ++ { ++ report(RPT_INFO, "Device for Vendor[%s] Product[%s] was not found, exiting\n", p->pszVendor, p->pszProduct); ++ return -1; ++ } ++ ++ //****************************************************** ++ // Initialize the internal report structures ++ //****************************************************** ++ if(ioctl(p->fd, HIDIOCINITREPORT,0)<0) ++ return -1; ++ ++ //****************************************************** ++ // Find out what type of reports this device accepts ++ //****************************************************** ++ //FindReports(fd); ++ ++ //****************************************************** ++ // Set up the display to show graphics ++ //****************************************************** ++ VFDTurnOffIcons(drvthis); ++ VFDSetDisplay(drvthis, VFD_MODE_NONE, 0, 0, 0); ++ VFDGraphicsClearBuffer(drvthis, VFD_GR_PAGE_3); ++ ++ //****************************************************** ++ // Set up the display, scrolling region, scroll rate etc. ++ //****************************************************** ++ VFDDisableDisplay(drvthis); ++ VFDClearString(drvthis, VFD_STR_REGION_1); ++ VFDClearString(drvthis, VFD_STR_REGION_3); ++ VFDEnableString(drvthis, VFD_STR_LAYOUT_2); ++// VFDSetScrollRegion(drvthis, 0); ++// VFDSetScrollTime(drvthis, 500); ++ ++ VFDSetString(drvthis, VFD_STR_REGION_1, 0, "DM140 online!!!"); ++ ++ return 0; ++ ++} ++ ++MODULE_EXPORT void ++dm140_close (Driver *drvthis) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++ ++ VFDClearString(drvthis, VFD_STR_REGION_1); ++ VFDClearString(drvthis, VFD_STR_REGION_2); ++ VFDClearString(drvthis, VFD_STR_REGION_3); ++ VFDClearString(drvthis, VFD_STR_REGION_4); ++ ++ if (p != NULL) { ++ if (p->fd >= 0) ++ close(p->fd); ++ ++ free(p); ++ } ++ drvthis->store_private_ptr(drvthis, NULL); ++} ++ ++MODULE_EXPORT int ++dm140_width (Driver *drvthis) ++{ ++ PrivateData *p = drvthis->private_data; ++ return p->width; ++} ++ ++MODULE_EXPORT int ++dm140_height (Driver *drvthis) ++{ ++ PrivateData *p = drvthis->private_data; ++ return p->height; ++} ++ ++MODULE_EXPORT int ++dm140_string (Driver *drvthis, int x, int y, char *buffer) ++{ ++ PrivateData *p = drvthis->private_data; ++ int i; ++ ++ report(RPT_INFO, "%s called with values(x,y,c): %d, %d, %s", __FUNCTION__, x, y, buffer); ++ ++ for (i=0; iframebuf[y-1][x+i]=buffer[i]; ++ } ++ ++/* ++ if (y > p->height) ++ y = p->height; ++ ++ if (y == 2) ++ y = VFD_STR_REGION_3; ++ ++ return VFDSetString(drvthis, y, x, buffer); ++*/ ++ ++ return 0; ++} ++ ++MODULE_EXPORT int ++dm140_char (Driver *drvthis, int x, int y, char c) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++ report(RPT_INFO, "%s called with values(x,y,c): %d, %d, %c", __FUNCTION__, x, y, c); ++ ++ p->framebuf[y][x] = c; ++ ++ return 0; ++} ++ ++MODULE_EXPORT int ++dm140_clear (Driver *drvthis) ++{ ++ PrivateData *p = drvthis->private_data; ++ int i; ++ ++ report(RPT_INFO, "%s called with values()", __FUNCTION__); ++ ++ for (i=0; iheight; i++) ++ { ++ memset(p->framebuf[i], 0x20, p->width); ++ p->framebuf[i][p->width] = 0x00; ++ } ++ ++// VFDClearString(drvthis, VFD_STR_REGION_1); ++// VFDClearString(drvthis, VFD_STR_REGION_2); ++// VFDClearString(drvthis, VFD_STR_REGION_3); ++// VFDClearString(drvthis, VFD_STR_REGION_4); ++ ++ return 0; ++} ++ ++MODULE_EXPORT int ++dm140_flush (Driver *drvthis) ++{ ++ PrivateData *p = drvthis->private_data; ++ int i; ++ int y; ++ ++ report(RPT_INFO, "%s called with values()", __FUNCTION__); ++ ++ for (i=0; iheight; i++) ++ { ++ y = VFD_STR_REGION_1; ++ if(i==0) y = VFD_STR_REGION_1; ++ if(i==1) y = VFD_STR_REGION_3; ++ // Do switch depening on VFD_LAYOUT ++ VFDSetString(drvthis, y, 1, p->framebuf[i]); ++ } ++ ++ // Don't know what to do ++ ++ return 0; ++} ++ ++ +diff -Naur lcdproc-0.5.6-old/server/drivers/dm140.h lcdproc-0.5.6-new/server/drivers/dm140.h +--- lcdproc-0.5.6-old/server/drivers/dm140.h 1969-12-31 16:00:00.000000000 -0800 ++++ lcdproc-0.5.6-new/server/drivers/dm140.h 2012-11-14 12:06:25.000000000 -0800 +@@ -0,0 +1,38 @@ ++#ifndef DM140_H ++#define DM140_H ++ ++#include "libvfd.h" ++ ++typedef struct driver_private_data { ++ char device[256]; ++ int fd; ++ ++ int width; ++ int height; ++ ++ char *pszVendor; ++ char *pszProduct; ++ ++ int gIconMask; ++ char gLayout; ++ char gScrollTime; ++ char gFlags; ++ int gDisplayMode; ++ char gPages[VFD_PAGE_SIZE][VFD_PAGE_COUNT]; ++ ++ char **framebuf; ++ ++} PrivateData; ++ ++ ++/* dm140 */ ++MODULE_EXPORT int dm140_init (Driver *drvthis); ++MODULE_EXPORT void dm140_close (Driver *drvthis); ++MODULE_EXPORT int dm140_width (Driver *drvthis); ++MODULE_EXPORT int dm140_height (Driver *drvthis); ++MODULE_EXPORT int dm140_string (Driver *drvthis, int y, int x, char *buffer); ++MODULE_EXPORT int dm140_char (Driver *drvthis, int y, int x, char c); ++MODULE_EXPORT int dm140_clear (Driver *drvthis); ++MODULE_EXPORT int dm140_flush (Driver *drvthis); ++ ++#endif +diff -Naur lcdproc-0.5.6-old/server/drivers/led.c lcdproc-0.5.6-new/server/drivers/led.c +--- lcdproc-0.5.6-old/server/drivers/led.c 1969-12-31 16:00:00.000000000 -0800 ++++ lcdproc-0.5.6-new/server/drivers/led.c 2012-11-14 12:06:25.000000000 -0800 +@@ -0,0 +1,1065 @@ ++/* File modified by Henrik Larsson 2007 to interface with LCDproc API ++ */ ++ ++/* vfd demo application ++ * Copyright (C) 2006, Advanced Micro Devices, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++/* This is an example application that turns on the icons on the front panel ++ * and also displays text on the VFD screen ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "lcd.h" ++#include "libvfd.h" ++#include "report.h" ++#include "dm140.h" ++ ++ ++//************************************************************** ++// HID devices exchange data with the host computer using data bundles called ++// reports. Each report is divided into "fields", each of which can have one ++// or more "usages". In the hid-core each one of these usages has a single ++// signed 32 bit value. ++// ++// read(): ++// This is the event interface. When the HID device's state changes, it ++// performs an interrupt transfer containing a report which contains the ++// changed value. The hid-core.c module parses the report, and returns to ++// hiddev.c the individual usages that have changed within the report. In ++// its basic mode, the hiddev will make these individual usage changes ++// available to the reader using a struct hiddev_event: ++// struct hiddev_event { unsigned hid; ++// containing the HID usage identifier for the status that changed, and the ++// value that it was changed to. Note that the structure is defined within ++// , along with some other useful #defines and structures. ++// The HID usage identifier is a composite of the HID usage page shifed to ++// the 16 high order bits ORed with the usage code. The behavior of the read() ++// function can be modified using the HIDIOCSFLAG ioctl described below. ++// ++// ioctl(): ++// Instructs the kernel to retrieve all input and feature report values from ++// the device. At this point, all the usage structures will contain current ++// values for the device, and will maintain it as the device changes. Note ++// that the use of this ioctl is unnecessary in general, since later kernels ++// automatically initialize the reports from the device at attach time. ++//************************************************************** ++ ++/* hack - fix improper signed char handling - it's seeing 0x80 as a negative value*/ ++#define VALUE_FILTER(_value) (_value>0x7F)?(__s32)(0xFFFFFF00 | _value):(_value) ++ ++#define VFD_PACKET_SIZE(s) (s*8) ++ ++unsigned char amd_logo[VFD_PAGE_SIZE] = { ++ 0x7f,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0x3f,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0x1f,0xfe,0x07,0x83,0xc0,0xe3,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0x0f,0xfe,0x07,0x83,0xe1,0xe3,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0x07,0xfe,0x07,0xc3,0xe1,0xe3,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0x10,0x1e,0x0f,0xc3,0xf3,0xe3,0x87,0x80,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0x30,0x1e,0x0e,0xe3,0xb3,0x63,0x83,0x80,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0x30,0x1e,0x1c,0xe3,0xb7,0x63,0x83,0x80,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0xf0,0x1e,0x1c,0xe3,0x9e,0x63,0x83,0x80,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0xf0,0x1e,0x1c,0x73,0x9e,0x63,0x83,0x80,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0xf0,0x1e,0x3f,0xf3,0x9c,0x63,0x83,0x80,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0xff,0xce,0x3f,0xf3,0x8c,0x63,0x8f,0x80,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0xff,0x86,0x38,0x3b,0x80,0x63,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0xff,0x02,0x70,0x3b,0x80,0x63,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++}; ++ ++ ++char icon_bits[] = ++{ ++ 15, 14, 13, 12, 11, 10, 9, 8, ++ 18, 17, 16, 19, 23, 27, 31, 35, ++ 39, 43, 47, 51, 55, 59, 63 ++}; ++ ++//************************************************************** ++// FUNCTION: Compare ++// ++// INPUT: ++// const char *pszValue - string to compare ++// short sValue - numberic value to compare ++// ++// OUTPUT: ++// int - Boolean value, 0 on non match, 1 on success. ++// ++// DESCRIPTION: Compare a character value to a numeric value. ++//************************************************************** ++int Compare(const char *pszValue, short sValue) ++{ ++ int iValue; ++ // convert the pszValue to a number ++ sscanf( pszValue, "%4x", &iValue); ++ return( iValue == sValue ); ++} ++ ++ ++//************************************************************** ++// FUNCTION: OpenHID ++// ++// INPUT: ++// const char *pszVendor - Vendor ID of device to open ++// const char *pszProduct - Product ID of device to open ++// ++// OUTPUT: ++// int fd - file descriptor to the opened HID device or -1 if err. ++// ++// DESCRIPTION: This function will open all the HID's on the ++// system until we find a match or we've exhausted our search. ++//************************************************************** ++int OpenHID(Driver *drvthis) ++{ ++ int i, fd=-1; ++ char port[32]; ++ char name[256]; ++ const char *hiddev_prefix = "/dev/usb/hiddev"; /* in devfs */ ++ int version; ++ struct hiddev_devinfo device_info; ++ PrivateData *p = drvthis->private_data; ++ ++ ++ //****************************************************** ++ // Loop through all the 16 HID ports/devices looking for ++ // one that matches our device. ++ //****************************************************** ++ for(i=0; i<16;i++) ++ { ++ sprintf(port, "%s%d", hiddev_prefix, i); ++ if((fd = open(port,O_WRONLY))>=0) ++ { ++ ioctl(fd, HIDIOCGDEVINFO, &device_info); ++ ioctl(fd, HIDIOCGNAME(sizeof(name)), name); ++ ++ // If we've found our device, no need to look further, time to stop searching ++ if( Compare(p->pszVendor, device_info.vendor) && Compare(p->pszProduct, device_info.product)) ++ { ++ break; // stop the for loop ++ } ++ close(fd); // Added by HL ++ } ++ } ++ ++ //****************************************************** ++ // If we've found our device, print out some information about it. ++ //****************************************************** ++ if(fd != -1) ++ { ++ int appl; ++ report(RPT_INFO, "Found Device - Name is %s\n", name); ++ report(RPT_INFO, "Vendor[0x%04hx] Product[0x%04hx] Version[0x%04hx]\n\t", ++ device_info.vendor, device_info.product, device_info.version); ++ switch(device_info.bustype) ++ { ++ default: ++ report(RPT_INFO, " an unknown bus type: 0x%04hx ", device_info.bustype); ++ report(RPT_INFO, "bus[%d], devnum[%d] ifnum[%d]\n", device_info.busnum, ++ device_info.devnum, device_info.ifnum); ++ break; ++ } ++ //****************************************************** ++ // Read the version - it's a packed 32 field, so ++ // unpack it in order to display ++ //****************************************************** ++ ioctl(fd, HIDIOCGVERSION, &version); ++ report(RPT_INFO, "HIDdev Driver Version is %d.%d.%d\n", ++ version >>16, (version>>8)&0xff,version &0xff); ++ ++ report(RPT_INFO, "There are %d applications for this device\n", device_info.num_applications); ++ ++ for(i=0;i> 16) ++ { ++ case 0x01: report(RPT_INFO, "(Generic Desktop Page)\n");break; ++ case 0x02: report(RPT_INFO, "(Simulation Controls)\n"); break; ++ case 0x03: report(RPT_INFO, "(VR Controls)\n"); break; ++ case 0x04: report(RPT_INFO, "(Sport Controls)\n"); break; ++ case 0x05: report(RPT_INFO, "(Game Controls)\n"); break; ++ case 0x06: report(RPT_INFO, "(Generic Device Controls)\n");break; ++ case 0x07: report(RPT_INFO, "(Keyboard/Keypad)\n"); break; ++ case 0x08: report(RPT_INFO, "(LEDs)\n"); break; ++ case 0x09: report(RPT_INFO, "(Button)\n"); break; ++ case 0x0A: report(RPT_INFO, "(Ordinal)\n"); break; ++ case 0x0B: report(RPT_INFO, "(Telphony)\n"); break; ++ case 0x0C: report(RPT_INFO, "(Consumer Product Page)\n"); break; ++ case 0x0D: report(RPT_INFO, "(Digitizer)\n"); break; ++ case 0x0E: report(RPT_INFO, "(Reserved)\n"); break; ++ case 0x0F: report(RPT_INFO, "(PID Page)\n"); break; ++ case 0x14: report(RPT_INFO, "(Alphanumeric Display)\n"); break; ++ case 0x15: ++ case 0x3f: report(RPT_INFO, "(Reserved)\n"); break; ++ case 0x40: report(RPT_INFO, "(Medical Instruments)\n"); break; ++ case 0x80: report(RPT_INFO, "(USB Monitor Page)\n"); break; ++ case 0x81: report(RPT_INFO, "(USB Enumerated Values Page)\n"); break; ++ case 0x82: report(RPT_INFO, "(VESA Virtual Controls Page)\n"); break; ++ case 0x83: report(RPT_INFO, "(Reserved Monitor Page)\n"); break; ++ case 0x84: report(RPT_INFO, "(Power Device Page)\n"); break; ++ case 0x85: report(RPT_INFO, "(Battery System Page)\n"); break; ++ case 0x86: ++ case 0x87: report(RPT_INFO, "(Reserved Power Device Page)\n"); break; ++ case 0x8C: report(RPT_INFO, "(Bar Code Scanner Page)\n"); break; ++ case 0x8D: report(RPT_INFO, "(Scale Page)\n"); break; ++ case 0x8E: report(RPT_INFO, "(Magnetic Stripe Reading Device)\n"); break; ++ case 0x8F: report(RPT_INFO, "(Point of Sale pages)\n"); break; ++ case 0x90: report(RPT_INFO, "(Camera Control Page)\n"); break; ++ case 0x91: report(RPT_INFO, "(Arcade Page)\n"); break; ++ default: ++ { ++ int page = (appl >> 16) & 0x0000FFFF; ++ if((page >= 0xFF00) && (page <= 0xFFFF)) ++ report(RPT_INFO, "(Vendor Defined - 0x%04X)\n",page); ++ else ++ report(RPT_INFO, "(Unknown page - needs to be added 0x%04X)\n",(appl>>16)); ++ break; ++ } ++ } ++ } ++ } ++ return fd; ++} ++ ++//************************************************************** ++// FUNCTION: FindReports ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// ++// OUTPUT: ++// none ++// ++// DESCRIPTION: This function will print out the type of reports ++// this HID accepts. ++//************************************************************** ++void FindReports(Driver *drvthis) ++{ ++ int iFields, iUsage; ++ int iReportType; ++ struct hiddev_report_info repInfo; ++ struct hiddev_field_info fieldInfo; ++ struct hiddev_usage_ref usageRef; ++ PrivateData *p = drvthis->private_data; ++ int fd = p->fd; ++ ++ //****************************************************** ++ // For each type of report (Input, Output, Feature) ++ // find out which is accepted for this device. ++ //****************************************************** ++ for(iReportType=HID_REPORT_TYPE_MIN; ++ iReportType<=HID_REPORT_TYPE_MAX; ++ iReportType ++) ++ { ++ repInfo.report_type = iReportType; ++ repInfo.report_id = HID_REPORT_ID_FIRST; ++ ++ //****************************************************** ++ // HIDIOCGREPORTINFO - struct hiddev_report_info (read/write) ++ // Obtain the usage information if it is found ++ //****************************************************** ++ while(ioctl(fd, HIDIOCGREPORTINFO, &repInfo)>=0) ++ { ++ report(RPT_INFO, " Report id: %d (%s) (%d fields)\n", ++ repInfo.report_id, ++ (iReportType == HID_REPORT_TYPE_INPUT) ? "Input" : ++ (iReportType == HID_REPORT_TYPE_OUTPUT) ? "Output" : "Feature/Other", ++ repInfo.num_fields); ++ ++ //****************************************************** ++ // HIDIOCGFIELDINFO - struct hiddev_field_info (read/write) ++ // Returns the field information associated with a report ++ // in a hiddev_field_info structure. The user must fill ++ // in report_id and report_type in this structure. The ++ // field_index should also be filled in, which should be ++ // a number between 0 and maxfield-1. ++ //****************************************************** ++ for(iFields = 0; iFieldsprivate_data; ++ int fd = p->fd; ++ ++ //****************************************************** ++ // Initialize the usage Reference and mark it for OUTPUT ++ //****************************************************** ++ memset(&uref, 0, sizeof(uref)); ++ uref.report_type = HID_REPORT_TYPE_OUTPUT; ++ uref.report_id = 0; ++ uref.field_index = 0; ++ ++ //************************************************************** ++ // Fill in the information that we wish to set ++ //************************************************************** ++ uref.usage_code = 0xffa10005; // unused? ++ for(i=0;iprivate_data; ++ ++ if(icon > VFD_ICON_DVD) ++ return -1; ++ ++ if(state) ++ p->gIconMask |= 1<gIconMask &= ~(1<gIconMask); ++} ++ ++//************************************************************** ++// FUNCTION: VFDIconOn ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int icon - icon to turn on ++// ++// OUTPUT: ++// int err - result of the VFDIconSet call (On success 0, On error -1) ++// ++// DESCRIPTION: This function will turn on one specific icon. ++//************************************************************** ++int VFDIconOn(Driver *drvthis, int icon) ++{ ++#ifdef DEBUG ++ report(RPT_INFO, "VFDIconOn %d\n",icon); ++#endif ++ return VFDIconSet(drvthis, icon, 1); ++} ++ ++//************************************************************** ++// FUNCTION: VFDIconOff ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int icon - icon to turn off ++// ++// OUTPUT: ++// int err - result of the VFDIconSet call (On success 0, On error -1) ++// ++// DESCRIPTION: This function will turn off one specific icon. ++//************************************************************** ++int VFDIconOff(Driver *drvthis, int icon) ++{ ++#ifdef DEBUG ++ report(RPT_INFO, "VFDIconOff %d\n",icon); ++#endif ++ return VFDIconSet(drvthis, icon, 0); ++} ++ ++//************************************************************** ++// FUNCTION: VFDTurnOffIcons ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: This function will turn off all the icons ++//************************************************************** ++int VFDTurnOffIcons(Driver *drvthis) ++{ ++#ifdef DEBUG ++ report(RPT_INFO, "VFDTurnOffIcons\n"); ++#endif ++ int err; ++ const char panelCmd[] = {0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; ++ const char iconCmd[] = {0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //icon command ++ const char iconoff[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //icon data ++ ++ err = SendReport(drvthis, panelCmd, sizeof(panelCmd)); ++ err = SendReport(drvthis, iconCmd, sizeof(iconCmd)); ++ err = SendReport(drvthis, iconoff, sizeof(iconoff)); ++ return err; ++} ++ ++//************************************************************** ++// FUNCTION: VFDSetVolume ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int level - volume level (between 0 and 12) ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: This function will raise/lower the volume indicator. ++//************************************************************** ++int VFDSetVolume(Driver *drvthis, int level) ++{ ++ int i; ++ PrivateData *p = drvthis->private_data; ++ ++ if(level>12) ++ return -1; ++ ++ // Clear all of the volume values ++ p->gIconMask &= ~0xFFFFF800; ++ ++ for(i=0;igIconMask |= 1 << (VFD_VOLUME_1 + i); ++ ++ return VFDShowIcons(drvthis, p->gIconMask); ++} ++ ++//************************************************************** ++// FUNCTION: VFDSetString ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int region - region to display the string ++// int offset - location to display the string ++// char *buffer - string to display ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: This function will display a string in the ++// specified region. ++//************************************************************** ++int VFDSetString(Driver *drvthis, int region, int offset, char *buffer) ++{ ++#ifdef DEBUG ++ report(RPT_INFO, "VFDSetString region %d offset %d buffer %s\n",region,offset,buffer); ++#endif ++ ++ int i,size; ++ int len = strlen(buffer) + 1;// make sure we make room for the NULL ++ char stringCmd[8]; ++ ++ if( region > VFD_STR_REGION_4) ++ return -1; ++ ++ if( offset > 111) ++ offset = 111; ++ ++ if( len > 128) ++ { ++ len = 128; ++ buffer[127] = 0; ++ } ++ ++ //****************************************************** ++ // Figure out how many 8 character lines we'll be sending ++ //****************************************************** ++ size = ((len + 7) / 8) + 1; ++ ++ //****************************************************** ++ // Setup the string command packet ++ //****************************************************** ++ memset(stringCmd, 0, 8); ++ stringCmd[VFD_CLC_OFFSET] = size; ++ stringCmd[VFD_FID_OFFSET] = VFD_FID_SET_STRING; ++ stringCmd[VFD_SET_STRING_RN] = region; ++ stringCmd[VFD_SET_STRING_SL] = len; ++ stringCmd[VFD_SET_STRING_XP] = offset; ++ SendReport(drvthis, stringCmd, sizeof(stringCmd)); ++ ++ //****************************************************** ++ // Now send the string for display ++ //****************************************************** ++ for(i=0; i 8) ? 8 : size; ++ SendReport(drvthis, &buffer[i], size); ++ } ++ return VFDGlobalUpdateDisplay(drvthis); ++} ++ ++//************************************************************** ++// FUNCTION: VFDClearString ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int region - region to display the string based upon the chosen layout ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: This function will clear a string in the ++// specified region. ++//************************************************************** ++int VFDClearString(Driver *drvthis, int region) ++{ ++ char pszClearStr[8]; ++ ++ if( region > VFD_STR_REGION_4) ++ return -1; ++ ++ memset(pszClearStr, 0, 8); ++ pszClearStr[VFD_CLC_OFFSET] = 1; ++ pszClearStr[VFD_FID_OFFSET] = VFD_FID_STRING_CLEAR; ++ pszClearStr[VFD_STRING_CLEAR_MD] = VFD_CLEAR_STR; ++ pszClearStr[VFD_STRING_CLEAR_RN] = region; ++ return SendReport(drvthis, pszClearStr, sizeof(pszClearStr)); ++} ++ ++//************************************************************** ++// FUNCTION: VFDSetDisplay ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int mode - VFD_MODE_NONE, VFD_MODE_STR, VFD_MODE_GRAPHICS ++// char layout - VFD_STR_LAYOUT_1, VFD_STR_LAYOUT_2, VFD_STR_LAYOUT_3 ++// char time - Scrolling Time in 50 ms units ++// char flags - String Scrolling Enable Flag ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: This function will turn on scrolling in the specified region. ++//************************************************************** ++int VFDSetDisplay(Driver *drvthis, int mode, char layout, char time, char flags) ++{ ++ char packet[VFD_PACKET_SIZE(1)]; ++ ++ memset(packet, 0, 8); ++ ++ packet[VFD_CLC_OFFSET] = 1; ++ packet[VFD_FID_OFFSET] = VFD_FID_SET_DISPLAY; ++ packet[VFD_SET_DISPLAY_MD] = mode; ++ packet[VFD_SET_DISPLAY_DM] = layout; ++ packet[VFD_SET_DISPLAY_ST] = time; ++ packet[VFD_SET_DISPLAY_SF] = flags; ++ return SendReport(drvthis, packet, sizeof(packet)); ++} ++ ++//************************************************************** ++// FUNCTION: VFDUpdateDisplay ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int mode - VFD_MODE_NONE, VFD_MODE_STR, VFD_MODE_GRAPHICS ++// char layout - VFD_STR_LAYOUT_1, VFD_STR_LAYOUT_2, VFD_STR_LAYOUT_3 ++// char time - Scrolling Time in 50 ms units ++// char flags - String Scrolling Enable Flag ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: This function will update the display mode/layout/scrolltime. ++//************************************************************** ++int VFDUpdateDisplay(Driver *drvthis, int mode, char layout, char time, char flags) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++ if(mode != p->gDisplayMode) ++ return 0; ++ ++ return VFDSetDisplay(drvthis, mode, layout, time, flags); ++} ++ ++//************************************************************** ++// FUNCTION: VFDGlobalUpdateDisplay ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: Update the display based upon the global configuration values. ++//************************************************************** ++int VFDGlobalUpdateDisplay(Driver *drvthis) ++{ ++ PrivateData *p = drvthis->private_data; ++ return VFDUpdateDisplay(drvthis, p->gDisplayMode, p->gLayout, p->gScrollTime, p->gFlags); ++} ++ ++//************************************************************** ++// FUNCTION: VFDSetScrollRegion ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int region - region to scroll ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: This function will turn on scrolling in the specified region. ++//************************************************************** ++int VFDSetScrollRegion(Driver *drvthis, int region) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++#ifdef DEBUG ++ report(RPT_INFO, "VFDSetScrollRegion region %d\n",region); ++#endif ++ p->gFlags &= ~0x0F; ++ p->gFlags |= (region & 0x0F); ++ return VFDUpdateDisplay(drvthis, VFD_MODE_STR, p->gLayout, p->gScrollTime, p->gFlags | VFD_SCROLL_ENABLE); ++} ++ ++//************************************************************** ++// FUNCTION: VFDSetScrollTime ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int time - time in ms to scroll ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: This function will set the rate at which to scroll ++//************************************************************** ++int VFDSetScrollTime(Driver *drvthis, int time) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++ p->gScrollTime = time / 50; ++ return VFDUpdateDisplay(drvthis, VFD_MODE_STR, p->gLayout, p->gScrollTime, p->gFlags | VFD_SCROLL_ENABLE); ++} ++ ++//************************************************************** ++// FUNCTION: VFDEnableDisplay ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int mode - VFD_MODE_NONE, VFD_MODE_STR, VFD_MODE_GRAPHICS ++// char layout - VFD_STR_LAYOUT_1, VFD_STR_LAYOUT_2, VFD_STR_LAYOUT_3 ++// char time - Scrolling Time in 50 ms units ++// char flags - String Scrolling Enable Flag ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: This function specifies how the VFD is segmented. ++//************************************************************** ++int VFDEnableDisplay(Driver *drvthis, int mode, char layout, char time, char flags) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++ p->gDisplayMode = mode; ++ return VFDSetDisplay(drvthis, mode, layout, time, flags); ++} ++ ++//************************************************************** ++// FUNCTION: VFDDisableDisplay ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: This function will disable any updates to the display ++//************************************************************** ++int VFDDisableDisplay(Driver *drvthis) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++ p->gDisplayMode = VFD_MODE_NONE; ++ return VFDSetDisplay(drvthis, VFD_MODE_NONE, 0, 0, 0); ++} ++ ++ ++//************************************************************** ++// FUNCTION: VFDEnableString ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// char ucLayout - specify how the VFD is segmented ++// ++// OUTPUT: ++// int err - result of the SendReport call (On success 0, On error -1) ++// ++// DESCRIPTION: This function specifies how the VFD is laid out. ++// LAYOUT 1 LAYOUT 2 LAYOUT 3 ++// /----------------\ /---------------\ /--------------------\ ++// | | | Region 1 | |Region 1 | Region 2 | ++// | Region 1 | |---------------| |---------+----------| ++// | | | Region 3 | |Region 3 | Region 4 | ++// \----------------/ \---------------/ \--------------------/ ++//************************************************************** ++int VFDEnableString(Driver *drvthis, char ucLayout) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++ if(ucLayout < VFD_STR_LAYOUT_1 || ucLayout > VFD_STR_LAYOUT_3) ++ return -1; ++ ++ p->gLayout = ucLayout; ++ return VFDEnableDisplay(drvthis, VFD_MODE_STR, p->gLayout, p->gScrollTime, p->gFlags | VFD_SCROLL_ENABLE); ++} ++ ++ ++//************************************************************** ++// FUNCTION: _set_pixel ++// ++// INPUT: ++// int page - page to draw on(VFD_GR_PAGE_1 ... VFD_GR_PAGE_4) ++// int x - coordinate ++// int y - coordinate ++// int color - 0 or 1 - turn on/off the LED ++// ++// OUTPUT: ++// Nothing ++// ++// DESCRIPTION: This function turns on/off pixels in the graphic page. ++//************************************************************** ++static void _set_pixel(Driver *drvthis, int page, int x, int y, int color) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++ char dst = ((y/8) * 112) + x; ++ char mask = (1 << (7 - (y%8))); ++ ++ // Turn the LED on/off based upon the color setting ++ if(color) ++ p->gPages[page][dst] |= mask; ++ else ++ p->gPages[page][dst] &= ~mask; ++} ++ ++ ++//************************************************************** ++// FUNCTION: VFDGraphicsClearBuffer ++// ++// INPUT: ++// int page - page to clear (VFD_GR_PAGE_1 ... VFD_GR_PAGE_4) ++// ++// OUTPUT: ++// 0 on success, -1 on error ++// ++// DESCRIPTION: This function clears the specified graphic page. ++//************************************************************** ++int VFDGraphicsClearBuffer(Driver *drvthis, int page) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++ if(page >= VFD_PAGE_COUNT) ++ return -1; ++ ++ // Clear the page to all off ++ memset(p->gPages[page], 0, VFD_PAGE_SIZE); ++ return 0; ++} ++ ++//************************************************************** ++// FUNCTION: VFDGraphicsCopyPage ++// ++// INPUT: ++// int page - Graphic page (dst) (VFD_GR_PAGE_1 ... VFD_GR_PAGE_4) ++// char *buffer - buffer worth of data (src) ++// ++// OUTPUT: ++// Nothing ++// ++// DESCRIPTION: This function turns on/off pixels in the graphic page. ++//************************************************************** ++int VFDGraphicsCopyPage(Driver *drvthis, int page, char *buffer) ++{ ++ int x, y; ++ int shift; ++ ++ if(page >= VFD_PAGE_COUNT) ++ return -1; ++ ++ for(y=0; y < VFD_HEIGHT; y++) ++ { ++ for(x=0; x < VFD_WIDTH; x++) ++ { ++ char src = (y*14)+(x/8); ++ shift = 7 - (x%8); ++ if(shift == 0) ++ shift = 1; ++ else ++ shift = 1 << shift; ++ _set_pixel(drvthis, page, x, y, buffer[src] & shift); ++ } ++ } ++ return 0; ++} ++ ++//************************************************************** ++// FUNCTION: VFDSetGraphics ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// char region - Graphic Page index ++// char *buf - data to display ++// ++// OUTPUT: ++// ++// DESCRIPTION: ++//************************************************************** ++int VFDSetGraphics(Driver *drvthis, char region, char *buf) ++{ ++ int i, size; ++ char packet[8]; ++ ++ // Send the Command to Set Graphics ++ memset(packet, 0, 8); ++ ++ packet[VFD_CLC_OFFSET] = 29; ++ packet[VFD_FID_OFFSET] = VFD_FID_SET_GRAPHICS; ++ packet[VFD_SET_GRAPHICS_GP]=region; ++ SendReport(drvthis, packet, sizeof(packet)); ++ ++ // Send the actual graphics ++ for(i=0; i 8) ? 8 : size; ++ SendReport(drvthis, &buf[i], size); ++ } ++ return 0; ++} ++ ++//************************************************************** ++// FUNCTION: VFDGraphicsSendPage ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int page - page to display (VFD_GR_PAGE_1 ... VFD_GR_PAGE_4) ++// ++// OUTPUT: ++// -1 on error, or results of VFDSetGraphics ++// ++// DESCRIPTION: Sends the graphics page to the VFD to be displayed. ++//************************************************************** ++int VFDGraphicsSendPage(Driver *drvthis, int page) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++ if(page >= VFD_PAGE_COUNT) ++ return -1; ++ return VFDSetGraphics(drvthis, page+1, p->gPages[page]); ++} ++ ++//************************************************************** ++// FUNCTION: VFDGraphicsShowPage ++// ++// INPUT: ++// int fd - file descriptor to the opened HID device ++// int page - page to get ready to show (VFD_GR_PAGE_1 ... VFD_GR_PAGE_4) ++// ++// OUTPUT: ++// -1 on error ++// ++// DESCRIPTION: Sets the VFD into Graphic mode ++//************************************************************** ++int VFDGraphicsShowPage(Driver *drvthis, int page) ++{ ++ if(page >= VFD_PAGE_COUNT) ++ return -1; ++ return VFDEnableDisplay(drvthis, VFD_MODE_GRAPHICS, page+1, 0, 0); ++} ++ ++//************************************************************** ++// FUNCTION: VFDGraphicsRect ++// ++// INPUT: ++// int page - page to get ready to show (VFD_GR_PAGE_1 ... VFD_GR_PAGE_4) ++// char color - 0 or 1 ++// int srcx - starting X Coordinate ++// int srcy - starting Y Coordinate ++// int width - how wide to make the box ++// int height - how tall to make the box ++// ++// OUTPUT: ++// -1 on error ++// ++// DESCRIPTION: Draws a box at (srcx,srcy) - (srcx+width, srcy+height) ++//************************************************************** ++int VFDGraphicsRect(Driver *drvthis, int page, char color, int srcx, int srcy, int width, int height) ++{ ++ PrivateData *p = drvthis->private_data; ++ ++ char *b; ++ int h, w, x, y; ++ ++ if( page >= VFD_PAGE_COUNT) ++ return -1; ++ ++ if (srcx > VFD_WIDTH || srcy > VFD_HEIGHT) ++ return 0; ++ ++ h = (srcy + height > VFD_HEIGHT) ? VFD_HEIGHT - srcy : srcy + height; ++ w = (srcx + width > VFD_WIDTH) ? VFD_WIDTH - srcx : srcx + width; ++ b = p->gPages[page]; ++ ++ for( y = srcy; y < h; y++ ) ++ for( x = srcx; x < w; x++) ++ _set_pixel(drvthis, page, x, y, color); ++ ++ return 0; ++} +diff -Naur lcdproc-0.5.6-old/server/drivers/led.h lcdproc-0.5.6-new/server/drivers/led.h +--- lcdproc-0.5.6-old/server/drivers/led.h 1969-12-31 16:00:00.000000000 -0800 ++++ lcdproc-0.5.6-new/server/drivers/led.h 2012-11-14 12:06:25.000000000 -0800 +@@ -0,0 +1,29 @@ ++#ifndef LED_H ++#define LED_H ++ ++// led.c functions ++int OpenHID(Driver *drvthis); ++int VFDShowIcons(Driver *drvthis, int mask); ++int VFDIconSet(Driver *drvthis, int icon, int state); ++int VFDIconOn(Driver *drvthis, int icon); ++int VFDIconOff(Driver *drvthis, int icon); ++int VFDTurnOffIcons(Driver *drvthis); ++int VFDSetVolume(Driver *drvthis, int level); ++int VFDSetString(Driver *drvthis, int region, int offset, char *buffer); ++int VFDClearString(Driver *drvthis, int region); ++int VFDSetDisplay(Driver *drvthis, int mode, char layout, char time, char flags); ++int VFDUpdateDisplay(Driver *drvthis, int mode, char layout, char time, char flags); ++int VFDGlobalUpdateDisplay(Driver *drvthis); ++int VFDSetScrollRegion(Driver *drvthis, int region); ++int VFDSetScrollTime(Driver *drvthis, int time); ++int VFDEnableDisplay(Driver *drvthis, int mode, char layout, char time, char flags); ++int VFDDisableDisplay(Driver *drvthis); ++int VFDEnableString(Driver *drvthis, char ucLayout); ++int VFDGraphicsClearBuffer(Driver *drvthis, int page); ++int VFDGraphicsCopyPage(Driver *drvthis, int page, char *buffer); ++int VFDSetGraphics(Driver *drvthis, char region, char *buf); ++int VFDGraphicsSendPage(Driver *drvthis, int page); ++int VFDGraphicsShowPage(Driver *drvthis, int page); ++int VFDGraphicsRect(Driver *drvthis, int page, char color, int srcx, int srcy, int width, int height); ++ ++#endif +diff -Naur lcdproc-0.5.6-old/server/drivers/libvfd.h lcdproc-0.5.6-new/server/drivers/libvfd.h +--- lcdproc-0.5.6-old/server/drivers/libvfd.h 1969-12-31 16:00:00.000000000 -0800 ++++ lcdproc-0.5.6-new/server/drivers/libvfd.h 2012-11-14 12:06:25.000000000 -0800 +@@ -0,0 +1,183 @@ ++/* Header for libvfd ++ * Copyright (C) 2006, Advanced Micro Devices, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef LIBVFD_H_ ++#define LIBVFD_H_ ++ ++/* Offsets into the VFD command packet */ ++ ++#define VFD_CLC_OFFSET 0x00 ++#define VFD_FID_OFFSET 0x01 ++ ++/* VFD FID (Function IDs) */ ++ ++#define VFD_FID_PANEL_BANK 0x01 ++#define VFD_FID_ICON_CONTROL 0x02 ++#define VFD_FID_SET_STRING 0x03 ++#define VFD_FID_STRING_CLEAR 0x04 ++#define VFD_FID_SET_DISPLAY 0x05 ++#define VFD_FID_SET_GRAPHICS 0x06 ++#define VFD_FID_GRAPHIC_AREA 0x07 ++ ++/* Command specific offsets */ ++ ++/* Panel Blank */ ++#define VFD_PANEL_BLANK_BL 0x02 ++ ++/* Icon Control */ ++#define VFD_ICON_CONTROL_BITMAP 0x08 ++ ++/* Set String */ ++#define VFD_SET_STRING_RN 0x02 ++#define VFD_SET_STRING_SL 0x03 ++#define VFD_SET_STRING_XP 0x04 ++#define VFD_SET_STRING_DATA 0x08 ++ ++/* String Clear */ ++#define VFD_STRING_CLEAR_MD 0x02 ++#define VFD_CLEAR_STR 0x01 ++#define VFD_CLEAR_GRAPHICS 0x02 ++#define VFD_STRING_CLEAR_RN 0x03 ++ ++/* Set Display */ ++#define VFD_SET_DISPLAY_MD 0x02 ++#define VFD_MODE_NONE 0x00 ++#define VFD_MODE_STR 0x02 ++#define VFD_MODE_GRAPHICS 0x03 ++#define VFD_SET_DISPLAY_DM 0x03 ++#define VFD_SET_DISPLAY_ST 0x04 ++#define VFD_SET_DISPLAY_SF 0x06 ++ ++/* Set Graphics */ ++#define VFD_SET_GRAPHICS_GP 0x02 ++#define VFD_SET_GRAPHICS_DATA 0x08 ++ ++/* Graphic Area */ ++#define VFD_GRAPHIC_AREA_OOF 0x02 ++ ++/* LAYOUT 1 ++ /-----------------------\ ++ | | ++ | Region 1 | ++ | | ++ \-----------------------/ ++*/ ++ ++/* LAYOUT 2 ++ /-----------------------\ ++ | Region 1 | ++ |---------------------- | ++ | Region 3 | ++ \-----------------------/ ++*/ ++ ++/* LAYOUT 3 ++ /-----------------------\ ++ | Region 1 | Region 2 | ++ |---------------------- | ++ | Region 3 | Region 4 | ++ \-----------------------/ ++*/ ++ ++#define VFD_GR_PAGE_1 0x0 ++#define VFD_GR_PAGE_2 0x1 ++#define VFD_GR_PAGE_3 0x2 ++#define VFD_GR_PAGE_4 0x3 ++ ++#define VFD_STR_LAYOUT_1 0x01 ++#define VFD_STR_LAYOUT_2 0x02 ++#define VFD_STR_LAYOUT_3 0x03 ++ ++#define VFD_STR_REGION_1 0x01 ++#define VFD_STR_REGION_2 0x02 ++#define VFD_STR_REGION_3 0x03 ++#define VFD_STR_REGION_4 0x04 ++ ++#define VFD_SCROLL_REGION1 (1 << 0) ++#define VFD_SCROLL_REGION2 (1 << 1) ++#define VFD_SCROLL_REGION3 (1 << 2) ++#define VFD_SCROLL_REGION4 (1 << 3) ++ ++#define VFD_SCROLL_ENABLE (1 << 7) ++ ++/* Graphics defintions */ ++/* The graphics area has a static resolution */ ++ ++#define VFD_WIDTH 112 ++#define VFD_HEIGHT 16 ++#define VFD_PITCH (112 / 8) ++#define VFD_PAGE_SIZE (VFD_PITCH * VFD_HEIGHT) ++#define VFD_PAGE_COUNT 4 ++ ++#define VFD_ICON_VIDEO 0 ++#define VFD_ICON_CD 1 ++#define VFD_ICON_PLAY 2 ++#define VFD_ICON_RWND 3 ++#define VFD_ICON_PAUSE 4 ++#define VFD_ICON_FFWD 5 ++#define VFD_ICON_SPEAKER 6 ++#define VFD_ICON_REC 7 ++#define VFD_ICON_VOLUME 8 ++#define VFD_ICON_RADIO 9 ++#define VFD_ICON_DVD 10 ++ ++#define VFD_VOLUME_1 11 ++#define VFD_VOLUME_2 12 ++#define VFD_VOLUME_3 13 ++#define VFD_VOLUME_4 14 ++#define VFD_VOLUME_5 15 ++#define VFD_VOLUME_6 16 ++#define VFD_VOLUME_7 17 ++#define VFD_VOLUME_8 18 ++#define VFD_VOLUME_9 19 ++#define VFD_VOLUME_10 20 ++#define VFD_VOLUME_11 21 ++#define VFD_VOLUME_12 22 ++ ++#define VFD_ICON_COUNT 23 ++ ++int vfd_cmd_graphic_area_state(unsigned char); ++int vfd_cmd_panel_bank(unsigned char); ++int vfd_cmd_icon_control(unsigned char *); ++int vfd_cmd_set_string(unsigned char, unsigned char, unsigned char *, int); ++int vfd_cmd_clear(unsigned char, unsigned char); ++int vfd_cmd_set_display(unsigned char, unsigned char, unsigned char, unsigned char); ++int vfd_cmd_set_graphics(unsigned char, unsigned char *); ++ ++int vfd_enable_display(int, unsigned char, unsigned char, unsigned char); ++int vfd_update_display(int, unsigned char, unsigned char, unsigned char); ++int vfd_disable_display(int); ++ ++void vfd_str_set_scroll_time(int); ++void vfd_str_set_scroll_speed(unsigned char); ++void vfd_str_set_scroll_regions(unsigned char); ++int vfd_str_set_string(unsigned char, unsigned char, const unsigned char *); ++int vfd_str_clear_string(unsigned char); ++int vfd_str_enable(unsigned char); ++int vfd_str_disable(void); ++ ++int vfd_gr_clear_buffer(unsigned char); ++int vfd_gr_show_page(int); ++int vfd_gr_disable(void); ++int vfd_gr_send_page(int); ++int vfd_gr_clear_page(int); ++int vfd_gr_copy_page(int page, char *src); ++ ++int vfd_icon_set(int, int); ++int vfd_icon_on(int, int); ++int vfd_icon_off(int, int); ++ ++void vfr_gr_bitmap(int, char *, int, int, int, int, int, int); ++int vfr_gr_rect(int, unsigned char, int, int, int, int); ++ ++int vfd_init(void); ++int vfd_send_command(unsigned char, int, unsigned char *); ++void vfd_close(void); ++ ++#endif +diff -Naur lcdproc-0.5.6-old/server/drivers/Makefile.am lcdproc-0.5.6-new/server/drivers/Makefile.am +--- lcdproc-0.5.6-old/server/drivers/Makefile.am 2012-08-19 07:29:08.000000000 -0700 ++++ lcdproc-0.5.6-new/server/drivers/Makefile.am 2012-11-14 12:07:13.000000000 -0800 +@@ -23,7 +23,7 @@ + + lcdexecbindir = $(pkglibdir) + lcdexecbin_PROGRAMS = @DRIVERS@ +-EXTRA_PROGRAMS = bayrad CFontz CFontzPacket curses debug 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 MtxOrb mx5000 NoritakeVFD picolcd pyramid sdeclcd sed1330 sed1520 serialPOS serialVFD shuttleVFD stv5730 SureElec svga t6963 text tyan sli ula200 vlsys_m428 xosd i2500vfd irtrans ++EXTRA_PROGRAMS = bayrad CFontz CFontzPacket curses debug CwLnx dm140 ea65 EyeboxOne g15 glcd glcdlib glk hd44780 icp_a106 imon imonlcd IOWarrior irman joy lb216 lcdm001 lcterm lirc lis MD8800 mdm166a ms6931 mtc_s16209x MtxOrb mx5000 NoritakeVFD picolcd pyramid sdeclcd sed1330 sed1520 serialPOS serialVFD shuttleVFD stv5730 SureElec svga t6963 text tyan sli ula200 vlsys_m428 xosd i2500vfd irtrans + noinst_LIBRARIES = libLCD.a libbignum.a + + g15_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS) +@@ -87,6 +87,7 @@ + curses_SOURCES = lcd.h curses_drv.h curses_drv.c report.h + CwLnx_SOURCES = lcd.h lcd_lib.h CwLnx.c CwLnx.h report.h + debug_SOURCES = lcd.h report.h debug.c debug.h ++dm140_SOURCES = lcd.h led.c libvfd.h led.h dm140.c dm140.h report.h + 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 diff --git a/packages/addons/service/lcdd/patches/lcdd-0.5.6-libftdi1.patch b/packages/addons/service/lcdd/patches/lcdd-0.5.6-libftdi1.patch new file mode 100644 index 0000000000..b183619be3 --- /dev/null +++ b/packages/addons/service/lcdd/patches/lcdd-0.5.6-libftdi1.patch @@ -0,0 +1,65 @@ +diff --git a/configure.ac b/configure.ac +index 7c053d2..dcb0c4d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -314,7 +314,7 @@ AC_MSG_RESULT($enable_libftdi) + + if test "$enable_libftdi" = "yes"; then + ifdef([PKG_CHECK_MODULES], +- [PKG_CHECK_MODULES(LIBFTDI, libftdi >= 0.8, ++ [PKG_CHECK_MODULES(LIBFTDI, libftdi1 >= 0.8, + [AC_DEFINE(HAVE_LIBFTDI, [1], [Define to 1 if you have libftdi])], + [ enable_libftdi=no ])], + [AC_MSG_WARN([pkg-config not (fully) installed; drivers requiring libftdi may not be built])]) +diff --git a/server/drivers/hd44780-low.h b/server/drivers/hd44780-low.h +index 47acf45..6faa830 100644 +--- a/server/drivers/hd44780-low.h ++++ b/server/drivers/hd44780-low.h +@@ -26,7 +26,7 @@ + #endif + + #ifdef HAVE_LIBFTDI +-# include ++# include + #endif + + /** \name Symbolic names for connection types +diff --git a/server/drivers/i2500vfd.c b/server/drivers/i2500vfd.c +index d896a69..7fe74f2 100644 +--- a/server/drivers/i2500vfd.c ++++ b/server/drivers/i2500vfd.c +@@ -32,7 +32,7 @@ + #include + #include + #include +-#include ++#include + + #include "lcd.h" + #include "i2500vfd.h" +diff --git a/server/drivers/lis.c b/server/drivers/lis.c +index 5d3e97a..6c26a19 100644 +--- a/server/drivers/lis.c ++++ b/server/drivers/lis.c +@@ -42,7 +42,7 @@ + #include + + #include +-#include ++#include + + #include "lcd.h" + #include "lis.h" +diff --git a/server/drivers/ula200.c b/server/drivers/ula200.c +index cbdde40..a84eb49 100644 +--- a/server/drivers/ula200.c ++++ b/server/drivers/ula200.c +@@ -31,7 +31,7 @@ + #include + + #include +-#include ++#include + + #include "lcd.h" + #include "ula200.h" diff --git a/packages/addons/service/lcdd/patches/lcdd-fujitsu_siemens_scaleo_e.patch b/packages/addons/service/lcdd/patches/lcdd-fujitsu_siemens_scaleo_e.patch new file mode 100644 index 0000000000..1798f9c103 --- /dev/null +++ b/packages/addons/service/lcdd/patches/lcdd-fujitsu_siemens_scaleo_e.patch @@ -0,0 +1,56 @@ +diff -Naur lcdproc-0.5.7-cvs20140217/server/drivers/dm140.c lcdproc-0.5.7-cvs20140217.patch/server/drivers/dm140.c +--- lcdproc-0.5.7-cvs20140217/server/drivers/dm140.c 2014-12-24 01:37:27.439628078 +0100 ++++ lcdproc-0.5.7-cvs20140217.patch/server/drivers/dm140.c 2014-12-24 01:41:34.556853466 +0100 +@@ -81,10 +81,17 @@ + return -1; + } + +- if((p->fd = OpenHID(drvthis))< 0) ++ if ((p->fd = OpenHID(drvthis)) < 0) + { +- report(RPT_INFO, "Device for Vendor[%s] Product[%s] was not found, exiting\n", p->pszVendor, p->pszProduct); +- return -1; ++ report(RPT_INFO, "Device for Vendor[%s] Product[%s] was not found\n", p->pszVendor, p->pszProduct); ++ p->pszVendor = "1509"; ++ p->pszProduct = "925d"; ++ if ((p->fd = OpenHID(drvthis)) < 0) ++ { ++ report(RPT_INFO, "Device for Vendor[%s] Product[%s] was not found\n", p->pszVendor, p->pszProduct); ++ report(RPT_INFO, "No dm140 device found, exiting\n"); ++ return -1; ++ } + } + + //****************************************************** +diff -Naur lcdproc-0.5.7-cvs20140217/server/drivers/led.c lcdproc-0.5.7-cvs20140217.patch/server/drivers/led.c +--- lcdproc-0.5.7-cvs20140217/server/drivers/led.c 2014-12-24 01:37:27.439628078 +0100 ++++ lcdproc-0.5.7-cvs20140217.patch/server/drivers/led.c 2014-12-24 01:49:38.519253308 +0100 +@@ -95,21 +95,21 @@ + //************************************************************** + // FUNCTION: Compare + // +-// INPUT: ++// INPUT: + // const char *pszValue - string to compare +-// short sValue - numberic value to compare ++// short sOtherValue - numeric value to compare + // + // OUTPUT: + // int - Boolean value, 0 on non match, 1 on success. + // +-// DESCRIPTION: Compare a character value to a numeric value. ++// DESCRIPTION: Compare a hex value in a string to a numeric value. + //************************************************************** +-int Compare(const char *pszValue, short sValue) ++int Compare(const char *pszValue, short sOtherValue) + { +- int iValue; ++ short sValue; + // convert the pszValue to a number +- sscanf( pszValue, "%4x", &iValue); +- return( iValue == sValue ); ++ sscanf( pszValue, "%4hx", &sValue ); ++ return( sValue == sOtherValue ); + } + + diff --git a/packages/addons/service/lcdd/resources/settings.xml b/packages/addons/service/lcdd/resources/settings.xml new file mode 100644 index 0000000000..f9c9ec0e32 --- /dev/null +++ b/packages/addons/service/lcdd/resources/settings.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/addons/service/lcdd/source/bin/lcdd.start b/packages/addons/service/lcdd/source/bin/lcdd.start new file mode 100644 index 0000000000..8e93d8fc81 --- /dev/null +++ b/packages/addons/service/lcdd/source/bin/lcdd.start @@ -0,0 +1,37 @@ +#!/bin/sh +################################################################################ +# This file is part of LibreELEC - https://libreelec.tv +# Copyright (C) 2016 Team LibreELEC +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +. /etc/profile +oe_setup_addon service.lcdd + +if [ -z "$LCD_DRIVER" -o "$LCD_DRIVER" == "none" ]; then + exit 0 +fi + +LCDCONF=$ADDON_HOME/LCDd.conf + +if [ ! -f $LCDCONF ]; then + if [ -f /storage/.cache/LCDd.conf ]; then + mv /storage/.cache/LCDd.conf $LCDCONF + else + cp $ADDON_DIR/config/LCDd.conf $LCDCONF + fi +fi + +LCDd -f -c $LCDCONF -d $LCD_DRIVER diff --git a/packages/addons/service/lcdd/source/default.py b/packages/addons/service/lcdd/source/default.py new file mode 100644 index 0000000000..6c6b84a8a5 --- /dev/null +++ b/packages/addons/service/lcdd/source/default.py @@ -0,0 +1,35 @@ +################################################################################ +# This file is part of LibreELEC - https://libreelec.tv +# Copyright (C) 2016 Team LibreELEC +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +import subprocess +import xbmc +import xbmcaddon + + +class Monitor(xbmc.Monitor): + + def __init__(self, *args, **kwargs): + xbmc.Monitor.__init__(self) + self.id = xbmcaddon.Addon().getAddonInfo('id') + + def onSettingsChanged(self): + subprocess.call(['systemctl', 'restart', self.id]) + + +if __name__ == '__main__': + Monitor().waitForAbort() diff --git a/packages/addons/service/lcdd/source/resources/language/English/strings.po b/packages/addons/service/lcdd/source/resources/language/English/strings.po new file mode 100644 index 0000000000..8e2ffb4582 --- /dev/null +++ b/packages/addons/service/lcdd/source/resources/language/English/strings.po @@ -0,0 +1,11 @@ +# Kodi Media Center language file +msgid "" +msgstr "" + +msgctxt "#30000" +msgid "Configuration" +msgstr "" + +msgctxt "#30001" +msgid "LCD driver" +msgstr "" diff --git a/packages/addons/service/lcdd/source/system.d/service.lcdd.service b/packages/addons/service/lcdd/source/system.d/service.lcdd.service new file mode 100644 index 0000000000..6453fb6303 --- /dev/null +++ b/packages/addons/service/lcdd/source/system.d/service.lcdd.service @@ -0,0 +1,14 @@ +[Unit] +Description=LCDProc +After=multi-user.target + +[Service] +ExecStart=/bin/sh /storage/.kodi/addons/service.lcdd/bin/lcdd.start +TimeoutStopSec=1s +Restart=on-failure +RestartSec=5 +StartLimitInterval=30 +StartLimitBurst=5 + +[Install] +WantedBy=multi-user.target