diff --git a/ChangeLog b/ChangeLog index 0ad265d..9cb72cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,6 +31,7 @@ v.0.5dev (ongoing development) - obsolete hd44780 subdrivers-removed: lcdserializer, picanlcd * character mapping for special HD44780 modules (Matteo Pillon) + g15 - driver for LCD in Logitech G15 gaming keyboards (Anthony J. Mirabella) + + EyeboxOne - driver for the LCD display on the EyeboxOne (Cedric TESSIER) v0.5.0 This version has split off from unstable-0.4.3. Includes major changes. diff --git a/LCDd.conf b/LCDd.conf index 771b18b..aeb99be 100644 --- a/LCDd.conf +++ b/LCDd.conf @@ -44,6 +44,7 @@ Driver=curses #Driver=MtxOrb #Driver=NoritakeVFD #Driver=serialVFD +#Driver=EyeboxOne # Tells the driver to bind to the given interface Bind=127.0.0.1 @@ -278,6 +279,40 @@ Keypad=yes # Default value is no #keypad_test_mode=yes +## EyeboxOne driver ## +[EyeboxOne] + +# Select the output device to use [default: /dev/ttyS1] +#Device=/dev/cua01 +Device=/dev/ttyS1 + +# Set the display size [default: 20x4] +Size=20x4 + +# Switch on the backlight? [default: yes] +Backlight=yes + +# Switch on the cursor? [default: no] +Cursor=no + +# Set the communication speed [default: 19200; legal: 1200, 2400, 9600, 19200] +Speed=19200 + +# Enter Key is a \r character, so it's hardcoded in the driver +LeftKey=D +RightKey=C +UpKey=A +DownKey=B +EscapeKey=P + +# You can find out which key of your display sends which +# character by setting keypad_test_mode to yes and running +# LCDd. LCDd will output all characters it receives. +# Afterwards you can modify the settings above and set +# keypad_set_mode to no again. +keypad_test_mode=no + + ## g15 driver for Logitech G15 Keyboard LCDs ## [g15] diff --git a/acinclude.m4 b/acinclude.m4 index f6de04c..79fbb4e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -5,7 +5,7 @@ AC_ARG_ENABLE(drivers, [ --enable-drivers= compile driver for LCDs in .] [ drivers may be separated with commas.] [ Possible choices are:] - [ bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,] + [ bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,EyeboxOne,] [ g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,] [ joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,mtc_s16209x,] [ MtxOrb,NoritakeVFD,pyramid,sed1330,sed1520,serialVFD,] @@ -15,7 +15,7 @@ AC_ARG_ENABLE(drivers, drivers="$enableval", drivers=[bayrad,CFontz,CFontz633,curses,CwLnx,glk,lb216,lcdm001,MtxOrb,pyramid,text]) -allDrivers=[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,mtc_s16209x,MtxOrb,NoritakeVFD,pyramid,sed1330,sed1520,serialVFD,sli,stv5730,svga,t6963,text,tyan,ula200,xosd] +allDrivers=[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,EyeboxOne,g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,mtc_s16209x,MtxOrb,NoritakeVFD,pyramid,sed1330,sed1520,serialVFD,sli,stv5730,svga,t6963,text,tyan,ula200,xosd] drivers=`echo $drivers | sed -e 's/,/ /g'` @@ -124,6 +124,10 @@ dnl else DRIVERS="$DRIVERS CwLnx${SO}" actdrivers=["$actdrivers CwLnx"] ;; + EyeboxOne) + DRIVERS="$DRIVERS EyeboxOne${SO}" + actdrivers=["$actdrivers EyeboxOne"] + ;; g15) AC_CHECK_HEADERS([g15daemon_client.h],[ AC_CHECK_LIB(g15daemon_client, new_g15_screen,[ diff --git a/clients/lcdproc/Makefile.am b/clients/lcdproc/Makefile.am index 45aa5ff..5da515b 100644 --- a/clients/lcdproc/Makefile.am +++ b/clients/lcdproc/Makefile.am @@ -4,7 +4,7 @@ sysconf_DATA = lcdproc.conf bin_PROGRAMS = lcdproc -lcdproc_SOURCES = main.c main.h mode.c mode.h batt.c batt.h chrono.c chrono.h cpu.c cpu.h cpu_smp.c cpu_smp.h disk.c disk.h load.c load.h mem.c mem.h machine.h machine_Linux.c machine_OpenBSD.c machine_FreeBSD.c machine_NetBSD.c machine_Darwin.c machine_SunOS.c util.c util.h iface.c iface.h +lcdproc_SOURCES = main.c main.h mode.c mode.h batt.c batt.h chrono.c chrono.h cpu.c cpu.h cpu_smp.c cpu_smp.h disk.c disk.h load.c load.h mem.c mem.h eyebox.c eyebox.h machine.h machine_Linux.c machine_OpenBSD.c machine_FreeBSD.c machine_NetBSD.c machine_Darwin.c machine_SunOS.c util.c util.h iface.c iface.h lcdproc_LDADD = @ldap_libs@ ../../shared/libLCDstuff.a diff --git a/clients/lcdproc/eyebox.c b/clients/lcdproc/eyebox.c new file mode 100644 index 0000000..033e8ad --- /dev/null +++ b/clients/lcdproc/eyebox.c @@ -0,0 +1,140 @@ +/* This is the LCDproc client module for EyeboxOne devices + + This allows to use leds, one as a free CPU meter, and one + as a free RAM meter. + + All this is in BETA version, take it as a demo... + + Copyright (C) 2006 Cedric TESSIER (aka NeZetiC) http://www.nezetic.info + + 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 + any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "shared/sockets.h" +#include "shared/debug.h" + +#include "main.h" +#include "mode.h" +#include "machine.h" +#include "eyebox.h" +#include "util.h" + + int +eyebox_screen(char display, int init) +{ +#undef CPU_BUF_SIZE +#define CPU_BUF_SIZE 4 + int i, j; + double value; + static double cpu[CPU_BUF_SIZE + 1][5]; // last buffer is scratch + meminfo_type mem[2]; + load_type load; + + if (init == 0) { + sprintf(buffer, "widget_add %c eyebo_cpu string\n", display); + sock_send_string(sock, buffer); + sprintf(buffer, "widget_add %c eyebo_mem string\n", display); + sock_send_string(sock, buffer); + + return(0); + } + + machine_get_load(&load); + machine_get_meminfo(mem); + + // Shift values over by one + for (i = 0; i < (CPU_BUF_SIZE - 1); i++) + for (j = 0; j < 5; j++) + cpu[i][j] = cpu[i + 1][j]; + + // Read new data + if (load.total > 0L) { + cpu[CPU_BUF_SIZE - 1][0] = 100.0 * ((double) load.user / (double) load.total); + cpu[CPU_BUF_SIZE - 1][1] = 100.0 * ((double) load.system / (double) load.total); + cpu[CPU_BUF_SIZE - 1][2] = 100.0 * ((double) load.nice / (double) load.total); + cpu[CPU_BUF_SIZE - 1][3] = 100.0 * ((double) load.idle / (double) load.total); + cpu[CPU_BUF_SIZE - 1][4] = 100.0 * (((double) load.user + (double) load.system + (double) load.nice) / (double) load.total); + } + else { + cpu[CPU_BUF_SIZE - 1][0] = 0.0; + cpu[CPU_BUF_SIZE - 1][1] = 0.0; + cpu[CPU_BUF_SIZE - 1][2] = 0.0; + cpu[CPU_BUF_SIZE - 1][3] = 0.0; + cpu[CPU_BUF_SIZE - 1][4] = 0.0; + } + + // Average values for final result + for (i = 0; i < 5; i++) { + value = 0.0; + for (j = 0; j < CPU_BUF_SIZE; j++) + value += cpu[j][i]; + value /= CPU_BUF_SIZE; + cpu[CPU_BUF_SIZE][i] = value; + } + + /* + * /xBab = Use Bar + * a = Bar ID + * b = Level + */ + + sprintf(buffer, "widget_set %c eyebo_cpu 1 2 {/xB%d%d}\n", display, 2,(int)(cpu[CPU_BUF_SIZE][4]/10)); + sock_send_string(sock, buffer); + + /* + * /xBab = Use Bas + * a = Bar ID + * b = Level + */ + + value = 1.0 - (double) (mem[0].free + mem[0].buffers + mem[0].cache) + / (double) mem[0].total; + sprintf(buffer, "widget_set %c eyebo_mem 1 3 {/xB%d%d}\n", display, 1, (int) (value * 10)) ; + sock_send_string(sock, buffer); + + return 0; +} // End mem_screen() + +void eyebox_clear(void){ + /* + * Clear LEDs before exit + */ + sock_send_string(sock, "screen_add OFF\n"); + sock_send_string(sock, "screen_set OFF -priority alert -name {EyeBO}\n"); + sock_send_string(sock, "widget_add OFF title title\n"); + sock_send_string(sock, "widget_set OFF title {EYEBOX ONE}\n"); + sock_send_string(sock, "widget_add OFF text string\n"); + sock_send_string(sock, "widget_add OFF about string\n"); + sock_send_string(sock, "widget_add OFF cpu string\n"); + sock_send_string(sock, "widget_add OFF mem string\n"); + + sock_send_string(sock, "widget_set OFF text 1 2 {Reseting Leds...}\n"); + sock_send_string(sock, "widget_set OFF about 5 4 {EyeBO by NeZetiC}\n"); + sprintf(buffer, "widget_set OFF cpu 1 2 {/xB%d%d}\n", 2, 0); + sock_send_string(sock, buffer); + sprintf(buffer, "widget_set OFF mem 1 3 {/xB%d%d}\n", 1, 0); + sock_send_string(sock, buffer); + usleep(2000000); /* Wait last order execution */ +} diff --git a/clients/lcdproc/eyebox.h b/clients/lcdproc/eyebox.h new file mode 100644 index 0000000..a360270 --- /dev/null +++ b/clients/lcdproc/eyebox.h @@ -0,0 +1,7 @@ +#ifndef CTRL_H +#define CTRL_H + +int eyebox_screen (char display, int init); +void eyebox_clear(void); + +#endif diff --git a/clients/lcdproc/main.c b/clients/lcdproc/main.c index 01549bd..5d72d37 100644 --- a/clients/lcdproc/main.c +++ b/clients/lcdproc/main.c @@ -34,6 +34,9 @@ #include "mem.h" #include "machine.h" #include "iface.h" +#ifdef LCDPROC_EYEBOXONE +# include "eyebox.h" +#endif // TODO: Commenting... Everything! @@ -433,6 +436,12 @@ HelpScreen (int exit_state) void exit_program(int val) { +#ifdef LCDPROC_EYEBOXONE + /* + * Clear Eyebox Leds + */ + eyebox_clear(); +#endif //printf("exit program\n"); Quit = 1; sock_close(sock); diff --git a/clients/lcdproc/mode.c b/clients/lcdproc/mode.c index bf32d93..baa792a 100644 --- a/clients/lcdproc/mode.c +++ b/clients/lcdproc/mode.c @@ -19,6 +19,9 @@ #include "mode.h" #include "main.h" #include "machine.h" +#ifdef LCDPROC_EYEBOXONE +# include "eyebox.h" +#endif // TODO: Clean this up... Support multiple display sizes.. @@ -66,6 +69,13 @@ update_screen(mode *m, int display) int old_status = status; if (m && m->func) { +#ifdef LCDPROC_EYEBOXONE + /* Eyebox Init */ + if((m->flags & INITIALIZED) == 0) + eyebox_screen(m->which,0); + /* Eyebox Flush */ + eyebox_screen(m->which,1); +#endif status = m->func(m->timer, display, &(m->flags)); } diff --git a/docs/LCDd.8 b/docs/LCDd.8 index bb5e0fb..2b46538 100644 --- a/docs/LCDd.8 +++ b/docs/LCDd.8 @@ -81,6 +81,9 @@ Standard video display using the (n)curses library .B CwLnx serial/USB displays by Cwlinux (http://www.cwlinux.com) .TP +.B EyeboxOne +LCD display on the EyeboxOne (http://www.rightvision.com) +.TP .B g15 LCD display on the Logitech G15 keyboard .TP diff --git a/docs/lcdproc-user/drivers.docbook b/docs/lcdproc-user/drivers.docbook index 5948bef..94c07a1 100644 --- a/docs/lcdproc-user/drivers.docbook +++ b/docs/lcdproc-user/drivers.docbook @@ -13,6 +13,7 @@ well as the configuration of LCDd. &CFontzPacket; &curses; &CwLnx; +&EyeboxOne; &g15; &glcdlib; &glk; diff --git a/docs/lcdproc-user/lcdproc-user.docbook b/docs/lcdproc-user/lcdproc-user.docbook index f3ae7a3..d9ad2a0 100644 --- a/docs/lcdproc-user/lcdproc-user.docbook +++ b/docs/lcdproc-user/lcdproc-user.docbook @@ -19,6 +19,7 @@ + diff --git a/server/drivers/EyeboxOne.c b/server/drivers/EyeboxOne.c new file mode 100644 index 0000000..7c77956 --- /dev/null +++ b/server/drivers/EyeboxOne.c @@ -0,0 +1,668 @@ +/* This is the LCDproc driver for EyeboxOne devices + + This code is based on MtxOrb driver (William Ferrell and Scott Scriven) + + Copyright (C) 2006 Cedric TESSIER (aka NeZetiC) http://www.nezetic.info + + 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 + any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "lcd.h" +#include "lcd_lib.h" +#include "EyeboxOne.h" + +#include "report.h" + +#define INPUT_PAUSE_KEY 'A' +#define INPUT_BACK_KEY 'B' +#define INPUT_FORWARD_KEY 'D' +#define INPUT_MAIN_MENU_KEY 'C' +#define EYEBOXONE_DEFAULT_Left 'D' +#define EYEBOXONE_DEFAULT_Right 'C' +#define EYEBOXONE_DEFAULT_Up 'A' +#define EYEBOXONE_DEFAULT_Down 'B' +#define EYEBOXONE_DEFAULT_Enter '\r' +#define EYEBOXONE_DEFAULT_Escape 'P' + +#define DEFAULT_SIZE "20x4" +#define DEFAULT_BACKLIGHT 1 + +#define LED_OFF 0 +#define LED_RED 1 +#define LED_ORANGE 2 +#define LED_GREEN 3 + +typedef struct p { + int def[9]; + int use[9]; + int backlight_state; /* static data from EyeboxOne_backlight */ + int width; + int height; + char *framebuf; /* Frame buffer */ + char *old; /* Current on screen frame buffer */ + int widthBYheight; /* Avoid computing width * height frequently */ + int clear; /* Control when the LCD is cleared */ + int fd; /* The LCD file descriptor */ + int backlightenabled; + int cursorenabled; + char left_key; + char right_key; + char up_key; + char down_key; + char enter_key; + char escape_key; + int keypad_test_mode; + int cellwidth; + int cellheight; + char info[255]; + /* LibData *libdata; */ + /* Private Data of the new library: Work in progress */ +} 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 = "EyeboxOne_"; + +static void EyeboxOne_showcursor (Driver *drvthis, int on); +static void EyeboxOne_use_bar(int fd, int bar, int level); +static void EyeboxOne_use_led(int fd, int led, int color); + +/* Parse one key from the configfile */ +static char EyeboxOne_parse_keypad_setting (Driver *drvthis, char * keyname, char default_value) +{ + char return_val = 0; + char * s; + char buf[255]; + + s = drvthis->config_get_string(drvthis->name, keyname, 0, NULL); + if (s != NULL) { + strncpy(buf, s, sizeof(buf)); + buf[sizeof(buf)-1] = '\0'; + return_val = buf[0]; + } else { + return_val = default_value; + } + return return_val; +} + +/* Opens com port and sets baud correctly... + * + * Called to initialize driver settings + */ + MODULE_EXPORT int +EyeboxOne_init (Driver *drvthis) +{ + struct termios portset; + + char device[256] = DEFAULT_DEVICE; + int speed = DEFAULT_SPEED; + char size[256] = DEFAULT_SIZE; + int tmp, w, h; + + PrivateData *p; + + /* Alocate and store private data */ + p = (PrivateData *) malloc(sizeof(PrivateData)); + if (p == NULL) + return -1; + if (drvthis->store_private_ptr(drvthis, p)) + return -1; + + /* Initialise the PrivateData structure */ + memset(p->def, -1, sizeof(p->def)); + memset(p->use, 0, sizeof(p->use)); + p->fd = -1; + p->backlight_state = 2; /* static data from EyeboxOne_backlight */ + p->width = LCD_DEFAULT_WIDTH; + p->height = LCD_DEFAULT_HEIGHT; + p->widthBYheight = LCD_DEFAULT_WIDTH * LCD_DEFAULT_HEIGHT; + p->clear = 1; /* assume LCD is cleared at startup */ + p->framebuf = NULL; + p->backlightenabled = DEFAULT_BACKLIGHT; + p->cursorenabled = DEFAULT_CURSOR; + p->old = NULL; + p->left_key = EYEBOXONE_DEFAULT_Left; + p->right_key = EYEBOXONE_DEFAULT_Right; + p->up_key = EYEBOXONE_DEFAULT_Up; + p->down_key = EYEBOXONE_DEFAULT_Down; + p->enter_key = EYEBOXONE_DEFAULT_Enter; + p->escape_key = EYEBOXONE_DEFAULT_Escape; + p->keypad_test_mode = 0; + p->cellwidth = LCD_DEFAULT_CELLWIDTH; + p->cellheight = LCD_DEFAULT_CELLHEIGHT; + + debug(RPT_INFO, "EyeBO: init(%p)", drvthis); + + /* READ CONFIG FILE */ + + /* Get serial device to use */ + strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(device)); + device[sizeof(device)-1] = '\0'; + report(RPT_INFO, "%s: using Device %s", drvthis->name, device); + + /* Get display size */ + strncpy(size, drvthis->config_get_string(drvthis->name, "Size", 0, DEFAULT_SIZE), sizeof(size)); + size[sizeof(size)-1] = '\0'; + if ((sscanf(size, "%dx%d", &w, &h) != 2) + || (w <= 0) || (w > LCD_MAX_WIDTH) + || (h <= 0) || (h > LCD_MAX_HEIGHT)) { + report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", + drvthis->name, size, DEFAULT_SIZE); + sscanf(DEFAULT_SIZE , "%dx%d", &w, &h); + } + p->width = w; + p->height = h; + p->widthBYheight = w * h; + + /* Get speed */ + tmp = drvthis->config_get_int(drvthis->name, "Speed", 0, DEFAULT_SPEED); + switch (tmp) { + case 1200: + speed = B1200; + break; + case 2400: + speed = B2400; + break; + case 9600: + speed = B9600; + break; + case 19200: + speed = B19200; + break; + default: + speed = B19200; + report(RPT_WARNING, "%s: Speed must be 1200, 2400, 9600 or 19200; using default %d", + drvthis->name, tmp); + } + + /* Get backlight setting*/ + p->backlightenabled = drvthis->config_get_bool(drvthis->name, "Backlight", 0, DEFAULT_BACKLIGHT); + + /* Get backlight setting*/ + p->cursorenabled = drvthis->config_get_bool(drvthis->name, "Cursor", 0, DEFAULT_CURSOR); + + + /* Get keypad settings*/ + + /* keypad test mode? */ + if (drvthis->config_get_bool(drvthis->name, "keypad_test_mode", 0, 0)) { + fprintf( stdout, "EyeBO: Entering keypad test mode...\n"); + p->keypad_test_mode = 1; + stay_in_foreground = 1; + } + + if (!p->keypad_test_mode) { + /* We don't send any chars to the server in keypad test mode. + * So there's no need to get them from the configfile in keypad + * test mode. + */ + + /* left_key */ + p->left_key = EyeboxOne_parse_keypad_setting(drvthis, "LeftKey", EYEBOXONE_DEFAULT_Left); + report(RPT_DEBUG, "%s: Using \"%c\" as Leftkey.", drvthis->name, p->left_key); + + /* right_key */ + p->right_key = EyeboxOne_parse_keypad_setting(drvthis, "RightKey", EYEBOXONE_DEFAULT_Right); + report(RPT_DEBUG, "%s: Using \"%c\" as RightKey.", drvthis->name, p->right_key); + + /* up_key */ + p->up_key = EyeboxOne_parse_keypad_setting(drvthis, "UpKey", EYEBOXONE_DEFAULT_Up); + report(RPT_DEBUG, "%s: Using \"%c\" as UpKey.", drvthis->name, p->up_key); + + /* down_key */ + p->down_key = EyeboxOne_parse_keypad_setting(drvthis, "DownKey", EYEBOXONE_DEFAULT_Down); + report(RPT_DEBUG, "%s: Using \"%c\" as DownKey.", drvthis->name, p->down_key); + + /* right_key */ + p->enter_key = EyeboxOne_parse_keypad_setting(drvthis, "EnterKey", EYEBOXONE_DEFAULT_Enter); + report(RPT_DEBUG, "%s: Using \"%c\" as EnterKey.", drvthis->name, p->enter_key); + + /* escape_key */ + p->escape_key = EyeboxOne_parse_keypad_setting(drvthis, "EscapeKey", EYEBOXONE_DEFAULT_Escape); + report(RPT_DEBUG, "%s: Using \"%c\" as EscapeKey.", drvthis->name, p->escape_key); + + } + /* End of config file parsing*/ + + /* Set up io port correctly, and open it... */ + p->fd = open(device, O_RDWR | O_NOCTTY); + if (p->fd == -1) { + report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, device, strerror(errno)); + if (errno == EACCES) + report(RPT_ERR, "%s: %s device could not be opened...", drvthis->name, device); + return -1; + } + report(RPT_INFO, "%s: opened display on %s", drvthis->name, device); + + tcgetattr(p->fd, &portset); + + // THIS ALL COMMENTED OUT BECAUSE WE NEED TO SET TIMEOUTS + /* We use RAW mode */ +#ifdef HAVE_CFMAKERAW_NOT + /* The easy way */ + cfmakeraw(&portset); +#else + /* The hard way */ + portset.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP + | INLCR | IGNCR | ICRNL | IXON ); + portset.c_oflag &= ~OPOST; + portset.c_lflag &= ~( ECHO | ECHONL | ICANON | ISIG | IEXTEN ); + portset.c_cflag &= ~( CSIZE | PARENB | CRTSCTS ); + portset.c_cflag |= CS8 | CREAD | CLOCAL; + portset.c_cc[VMIN] = 1; + portset.c_cc[VTIME] = 3; +#endif + + /* Set port speed */ + cfsetospeed(&portset, speed); + cfsetispeed(&portset, B0); + + /* Do it... */ + tcsetattr(p->fd, TCSANOW, &portset); + + /* Make sure the frame buffer is there... */ + p->framebuf = (char *) calloc(p->widthBYheight, 1); + if (p->framebuf == NULL) { + report(RPT_ERR, "%s: unable to create framebuffer", drvthis->name); + return -1; + } + memset(p->framebuf, ' ', p->widthBYheight); + + report(RPT_DEBUG, "%s: init() done", drvthis->name); + + return 1; +} + +#define ValidX(x) if ((x) > p->width) { (x) = p->width; } else (x) = (x) < 1 ? 1 : (x); +#define ValidY(y) if ((y) > p->height) { (y) = p->height; } else (y) = (y) < 1 ? 1 : (y); + + +/******************** + * Use bars + */ +static void EyeboxOne_use_bar(int fd, int bar, int level){ + char buffer[16]; + + if(bar > 2 || bar < 1) + return; + + if(level > 10 || level < 0) + return; + + sprintf(buffer, "\E[%d;%dB",bar,level); + write(fd,buffer,strlen(buffer)); + +} + +/******************** + * Use leds + */ +static void EyeboxOne_use_led(int fd, int led, int color){ + char buffer[16]; + int a,b; + + if(led > 3 || led < 1) + return; + + switch(color){ + case LED_OFF: + a=b=0; + break; + case LED_RED: + a=1; + b=0; + break; + case LED_ORANGE: + a=1; + b=1; + break; + case LED_GREEN: + a=0; + b=1; + break; + default: + a=b=0; + } + + sprintf(buffer, "\E[%d;%dL",led+(led-1),a); + write(fd,buffer,strlen(buffer)); + sprintf(buffer, "\E[%d;%dL",led+(led-1)+1,b); + write(fd,buffer,strlen(buffer)); + +} + +/****************************** + * Clear the screen (the frame buffer) + */ + MODULE_EXPORT void +EyeboxOne_clear (Driver *drvthis) +{ + PrivateData * p = drvthis->private_data; + + if (p->framebuf != NULL) + memset(p->framebuf, ' ', (p->widthBYheight)); + p->clear = 1; /* Remember that custom char are no more visible. */ + + debug(RPT_DEBUG, "EyeBO: cleared screen"); +} + +/****************************** + * Clean-up + */ + MODULE_EXPORT void +EyeboxOne_close (Driver *drvthis) +{ + PrivateData * p = drvthis->private_data; + /* Clear bars && leds before exit */ + EyeboxOne_use_bar(p->fd,1,0); + EyeboxOne_use_bar(p->fd,2,0); + EyeboxOne_use_led(p->fd,1,LED_OFF); + EyeboxOne_use_led(p->fd,2,LED_OFF); + EyeboxOne_use_led(p->fd,3,LED_OFF); + + debug(RPT_DEBUG, "EyeBO: cleared bars and leds"); + + if (p != NULL) { + if (p->fd >= 0) + close(p->fd); + + if (p->framebuf) + free(p->framebuf); + p->framebuf = NULL; + + free(p); + } + drvthis->store_private_ptr(drvthis, NULL); + debug(RPT_DEBUG, "EyeBO: closed"); +} + +/****************************** + * Returns the display width + */ + MODULE_EXPORT int +EyeboxOne_width (Driver *drvthis) +{ + PrivateData * p = drvthis->private_data; + + return p->width; +} + +/****************************** + * Returns the display height + */ + MODULE_EXPORT int +EyeboxOne_height (Driver *drvthis) +{ + PrivateData * p = drvthis->private_data; + + return p->height; +} + +/****************************** + * Display a string at x,y + */ + MODULE_EXPORT void +EyeboxOne_string (Driver *drvthis, int x, int y, char *string) +{ + int offset, siz; + int bar,level; + + PrivateData * p = drvthis->private_data; + /* + * /xBab = Use Bar + * a = Bar ID + * b = Level + */ + if(strncmp(string,"/xB",3) == 0){ + bar = (int) (string[3] - 48); + level = (int) (string[4] - 48); + if(level == 1) + if(strlen(string) > 5) + if(((int) (string[5] - 48)) == 0) + level = 10; + EyeboxOne_use_bar(p->fd, bar, level); + report(RPT_DEBUG, "EyeBO: Changed bar %d to level %d", bar, level); + return; + } + + ValidX(x); + ValidY(y); + + x--; y--; + offset = (y * p->width) + x; + siz = (p->widthBYheight) - offset; + siz = (siz > strlen(string)) ? strlen(string) : siz; + memcpy(p->framebuf + offset, string, siz); + + debug(RPT_DEBUG, "EyeBO: printed string at (%d,%d)", x, y); +} + +/****************************** + * Send what we have to the hardware + */ + MODULE_EXPORT void +EyeboxOne_flush (Driver *drvthis) +{ + char out[12]; + int i,j,mv = 1; + char *xp, *xq; + + PrivateData * p = drvthis->private_data; + + if (p->old == NULL) { + p->old = malloc(p->widthBYheight); + + write(p->fd, "\E[H\E[2J", 7); // Clear Screen + EyeboxOne_showcursor(drvthis, p->cursorenabled); + write(p->fd, p->framebuf, p->widthBYheight); + + strncpy(p->old, p->framebuf, p->widthBYheight); + + return; + } + xp = p->framebuf; + xq = p->old; + + for (i = 1; i <= p->height; i++) { + for (j = 1; j <= p->width; j++) { + + if ((*xp == *xq) && (*xp > 8)) + mv = 1; + else { + if (mv == 1) { + snprintf(out, sizeof(out), "\E[%d;%dH", j-1, i); + write(p->fd, out, strlen(out)); + mv = 0; + } + write(p->fd, xp, 1); + } + xp++; + xq++; + } + } + + strncpy(p->old, p->framebuf, p->widthBYheight); + debug(RPT_DEBUG, "EyeBO: frame buffer flushed"); +} + +/****************************** + * Prints a character on the lcd display, at position (x,y). + * The upper-left is (1,1), and the lower right should be (20,4). + */ + MODULE_EXPORT void +EyeboxOne_chr (Driver *drvthis, int x, int y, char c) +{ + int offset; + + PrivateData * p = drvthis->private_data; + + ValidX(x); + ValidY(y); + + y--; x--; + offset = (y * p->width) + x; + p->framebuf[offset] = c; + + debug(RPT_DEBUG, "writing character %02X to position (%d,%d)", c, x, y); +} + +/****************************** + * Sets the backlight on or off + */ + +#define BACKLIGHT_OFF 0 +#define BACKLIGHT_ON 1 + + MODULE_EXPORT void +EyeboxOne_backlight (Driver *drvthis, int on) +{ + PrivateData * p = drvthis->private_data; + /* Disable in LCDd.conf + * Force Off mode */ + if(p->backlight_state == -1) + return; + + if (p->backlight_state == on) + return; + + p->backlight_state = on; + + if(!p->backlightenabled){ /* Disable in LCDd.conf */ + p->backlight_state = -1; + on = 0; + } + + switch (on) { + case BACKLIGHT_ON: + write(p->fd, "\E[E", 3); + debug(RPT_DEBUG, "EyeBO: backlight turned on"); + break; + case BACKLIGHT_OFF: + debug(RPT_DEBUG, "EyeBO: backlight turned off"); + write(p->fd, "\E[e", 3); + break; + default: /* ignored... */ + debug(RPT_DEBUG, "EyeBO: backlight - invalid setting"); + break; + } +} + +/********************** + * Toggle cursor on/off + */ + static void +EyeboxOne_showcursor (Driver *drvthis, int on) +{ + PrivateData * p = drvthis->private_data; + + if (on) { + write(p->fd, "\E[S", 3); + debug(RPT_DEBUG, "EyeBO: cursor turned on"); + } else { + write(p->fd, "\E[s", 3); + debug(RPT_DEBUG, "EyeBO: cursor turned off"); + } +} + +/***************************************************************** + * returns a string for the function characters from the keypad... + * (A-Z) on success, 0 on failure... + */ + MODULE_EXPORT const char * +EyeboxOne_get_key (Driver *drvthis) +{ + PrivateData * p = drvthis->private_data; + + char in = 0; + + // POLL For data or return + struct pollfd fds[1]; + fds[0].fd = p->fd; + fds[0].events = POLLIN; + fds[0].revents = 0; + poll(fds,1,0); + if (fds[0].revents == 0) + return NULL; + + (void) read(p->fd, &in, 1); + report(RPT_DEBUG, "%s: get_key: key 0x%02X", drvthis->name, in); + /* There is a lot of undesirable chars which appear + * when a key is pressed + * */ + if (in == '\0' || (int) in == 19 || (int) in == 91 || (int) in == 79 || (int) in == 27) + return NULL; + + if (!p->keypad_test_mode) { + if (in == p->left_key) + return "Left"; + else if (in == p->right_key) + return "Right"; + else if (in == p->up_key) + return "Up"; + else if (in == p->down_key) + return "Down"; + else if (in == p->enter_key) + return "Enter"; + else if (in == p->escape_key) + return "Escape"; + else { + report(RPT_INFO, "%s: untreated key 0x%02X", drvthis->name, in); + return NULL; + } + } + else { + fprintf(stdout, "EyeBO: Received character %c (%d)\n", in, (int)in); + fprintf(stdout, "EyeBO: Press another key of your device.\n"); + } + return NULL; +} + +/****************************** + * Returns string with general information about the display + * I think lcd is able to tell us more, but I can't find how... + */ + MODULE_EXPORT const char * +EyeboxOne_get_info (Driver *drvthis) +{ + PrivateData * p = drvthis->private_data; + + debug(RPT_DEBUG, "EyeBO: get_info"); + + memset(p->info, '\0', sizeof(p->info)); + strcpy(p->info, "Eyebox Driver "); + strcat(p->info, "(c) NeZetiC (nezetic.info)"); + + return p->info; +} + diff --git a/server/drivers/EyeboxOne.h b/server/drivers/EyeboxOne.h new file mode 100644 index 0000000..8eb8667 --- /dev/null +++ b/server/drivers/EyeboxOne.h @@ -0,0 +1,27 @@ +#ifndef EYEBOXONE_H +#define EYEBOXONE_H + +#include "lcd.h" + +MODULE_EXPORT int EyeboxOne_init (Driver *drvthis); +MODULE_EXPORT void EyeboxOne_close (Driver *drvthis); +MODULE_EXPORT int EyeboxOne_width (Driver *drvthis); +MODULE_EXPORT int EyeboxOne_height (Driver *drvthis); +MODULE_EXPORT void EyeboxOne_clear (Driver *drvthis); +MODULE_EXPORT void EyeboxOne_flush (Driver *drvthis); +MODULE_EXPORT void EyeboxOne_string (Driver *drvthis, int x, int y, char *string); +MODULE_EXPORT void EyeboxOne_chr (Driver *drvthis, int x, int y, char c); + +MODULE_EXPORT void EyeboxOne_set_char (Driver *drvthis, int n, char *dat); + +MODULE_EXPORT void EyeboxOne_backlight (Driver *drvthis, int on); + +MODULE_EXPORT const char * EyeboxOne_get_key (Driver *drvthis); +MODULE_EXPORT const char * EyeboxOne_get_info (Driver *drvthis); + +#define DEFAULT_DEVICE "/dev/ttyS1" +#define DEFAULT_SPEED 19200 +#define DEFAULT_CURSOR 0 + +#endif + diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am index 059e0b0..5e290b2 100644 --- a/server/drivers/Makefile.am +++ b/server/drivers/Makefile.am @@ -19,7 +19,7 @@ AM_LDFLAGS = @LDSHARED@ LIBS = pkglib_PROGRAMS = @DRIVERS@ -EXTRA_PROGRAMS = bayrad CFontz CFontz633 CFontzPacket curses CwLnx g15 glcdlib glk hd44780 icp_a106 imon IOWarrior irman joy lb216 lcdm001 lcterm lirc MD8800 ms6931 mtc_s16209x MtxOrb NoritakeVFD pyramid sed1330 sed1520 serialVFD stv5730 svga t6963 text tyan sli ula200 xosd +EXTRA_PROGRAMS = bayrad CFontz CFontz633 CFontzPacket curses CwLnx EyeboxOne g15 glcdlib glk hd44780 icp_a106 imon IOWarrior irman joy lb216 lcdm001 lcterm lirc MD8800 ms6931 mtc_s16209x MtxOrb NoritakeVFD pyramid sed1330 sed1520 serialVFD stv5730 svga t6963 text tyan sli ula200 xosd noinst_LIBRARIES = libLCD.a libbignum.a IOWarrior_CFLAGS = @libusb_cflags@ $(AM_CFLAGS) @@ -62,6 +62,7 @@ CFontz633_SOURCES = lcd.h lcd_lib.h CFontz633.c CFontz633.h CFontz-charmap.h CF CFontzPacket_SOURCES = lcd.h lcd_lib.h CFontzPacket.c CFontzPacket.h CFontz-charmap.h CFontz633io.c CFontz633io.h report.h adv_bignum.h 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 +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 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