diff options
author | Martin Hammerschmid <linux@home.pages.at> | 2002-07-21 19:46:06 +0200 |
---|---|---|
committer | Martin Hammerschmid <linux@home.pages.at> | 2002-07-21 19:46:06 +0200 |
commit | b49a01e5a6304aeb0b6ad20c4d74468e7d19ef47 (patch) | |
tree | 95ff43114959fe9d1df1ebda272fc901e9781d65 | |
download | vdr-plugin-lcdproc-b49a01e5a6304aeb0b6ad20c4d74468e7d19ef47.tar.gz vdr-plugin-lcdproc-b49a01e5a6304aeb0b6ad20c4d74468e7d19ef47.tar.bz2 |
Version 0.0.1v0.0.1release/v0.0.1
-rw-r--r-- | COPYING | 340 | ||||
-rw-r--r-- | HISTORY | 6 | ||||
-rw-r--r-- | Makefile | 84 | ||||
-rw-r--r-- | README | 78 | ||||
-rw-r--r-- | lcd.c | 677 | ||||
-rw-r--r-- | lcd.h | 75 | ||||
-rw-r--r-- | lcdkeyconf.h | 7 | ||||
-rw-r--r-- | lcdproc.c | 299 | ||||
-rw-r--r-- | lcdtranstbl-CFontz.h | 265 | ||||
-rw-r--r-- | lcdtranstbl-hd44780.h | 265 | ||||
-rw-r--r-- | lcdtranstbl-nomap.h | 264 | ||||
-rw-r--r-- | sockets.c | 230 | ||||
-rw-r--r-- | sockets.h | 92 |
13 files changed, 2682 insertions, 0 deletions
@@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 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 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. @@ -0,0 +1,6 @@ +VDR Plugin 'lcdproc' Revision History +------------------------------------ + +2002-05-20: Version 0.0.1 + +- Initial revision. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..32814dd --- /dev/null +++ b/Makefile @@ -0,0 +1,84 @@ +# +# Makefile for a Video Disk Recorder plugin +# +# $Id$ + +# The official name of this plugin. +# This name will be used in the '-P...' option of VDR to load the plugin. +# By default the main source file also carries this name. +# +PLUGIN = lcdproc + +### The version number of this plugin (taken from the main source file): + +VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g') + +### The directory environment: + +DVBDIR = ../../../../DVB/ost/include +VDRDIR = ../../.. +VDRINC = $(VDRDIR)/include +LIBDIR = ../../lib +TMPDIR = /tmp + +### The version number of VDR (taken from VDR's "config.h"): + +VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g') + +### The name of the distribution archive: + +ARCHIVE = $(PLUGIN)-$(VERSION) +PACKAGE = vdr-$(ARCHIVE) + +### Includes and Defines (add further entries here): + +INCLUDES = -I$(VDRINC) -I$(DVBDIR) + +DEFINES = -DPLUGIN_NAME_I18N='"$(PLUGIN)"' + +ifndef LCDTRANS +LCDTRANS = hd44780 +endif +DEFINES += -DLCD_$(LCDTRANS) + +### The object files (add further files here): + +OBJS = $(PLUGIN).o lcd.o sockets.o + +### The C++ compiler and options: + +CXX = g++ +CXXFLAGS = -g -O2 -Wall -Woverloaded-virtual -m486 + +### Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + +# Dependencies: + +MAKEDEP = g++ -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +### Targets: + +all: libvdr-$(PLUGIN).so + +libvdr-$(PLUGIN).so: $(OBJS) + $(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@ + @cp $@ $(LIBDIR)/$@.$(VDRVERSION) + +package: clean + @-rm -rf $(TMPDIR)/$(ARCHIVE) + @mkdir $(TMPDIR)/$(ARCHIVE) + @cp -a * $(TMPDIR)/$(ARCHIVE) + @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE) + @-rm -rf $(TMPDIR)/$(ARCHIVE) + @echo Distribution package created as $(PACKAGE).tgz + +clean: + @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ @@ -0,0 +1,78 @@ +This is a "plugin" for the Video Disk Recorder (VDR). + +Written by: Martin Hammerschmid <martin@hammerschmid.com> + +Project's homepage: home.pages.at/linux/dvb.html + +Latest version available at: http://home.pages.at/linux/dvb.html + +See the file COPYING for license information. + +Description: Output to LCD modules that are supported by LCDproc + +------------------------------------------------------------------------- + +vdr -Plcdproc or -P"lcdproc -h <host> -p <port>" ... makes vdr connect to a LCDd. + +Current channel info and menus are then displayed on the LCD too. + +I had a 4x20 character display in mind but it should +work with 4x16 up to 4x40. + +LCDd can be used in an xterm or console too, so it +might be useful even without having the hardware. +( ./LCDd -d curses ) + +lcdtranstbl-xxx.h is used to map characters for output to LCDd. +Depending on the LCD hardware some characters may not displayed +correctly, you can fix that by altering this table ... +use lcdtranstbl-nomap.h if you don't want anything mapped. +what table is used can be selected at compile time: +e.g. ... LCDTRANS=CFontz make plugins ... +values for LCDTRANS are 'hd44780', 'CFontz' and 'nomap' ('hd44780' is the default value). +Thanks to Stephan Schreiber <stephan@sschreiber.de> for lcdtranstbl-CFontz.h. + +LCDproc is available at http://lcdproc.omnipotent.net/ +or here http://sourceforge.net/projects/lcdproc/ + + What's needed to run a LCD? + + Hardware: + + I used a single 4x20 LCD that works with the hd44780 8-bit driver on + the printer port. + ( availible at http://www.conrad.com/ product ID: 187275 + or see http://www.lcd-module.de/eng/doma/standard.htm ) + + printer port LCD + ---------------------------------------------------------------------- + GND (1) (used the PC's power suppy (black cable)) + +5V (2) (used the PC's power suppy (red cable)) + Vadj (3) (contrast, conneced to GND works fine for me) + + D0 (2) D0 (7) + D1 (3) D1 (8) + D2 (4) D2 (9) + D3 (5) D3 (10) + D4 (6) D4 (11) + D5 (7) D5 (12) + D6 (8) D6 (13) + D7 (9) D7 (14) + nSTRB (1) EN (6) + INIT (16) RS (4) + RW (5) (connected to GND (1) of the LCD) + GND (18-25) + --- optional for LCDs with background illumination --- + + LED+ (15) (connected to +5V over a 100Ohm resisitor + to make it not too bright) + LED- (16) (connected to GND) + + Software: + + Last tested with lcdproc-0.4.1 ( http://prdownloads.sourceforge.net/lcdproc/lcdproc-0.4.1.tar.gz ) + LCDd -d HD44780 "-p 0x3bc -c winamp" + should run LCDd for the hardware described above conneceted to the + printer port (in my case the port's base address is 0x3bc). + +Martin @@ -0,0 +1,677 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> +#include <sys/time.h> +#include <vdr/config.h> +#include <vdr/i18n.h> +#include <vdr/tools.h> +#include "lcd.h" +#include "sockets.h" +#include "lcdkeyconf.h" + +// character mapping for output, see cLcd::Write +#ifdef LCD_hd44780 +#include "lcdtranstbl-hd44780.h" // hd44780 output +#endif +#ifdef LCD_CFontz +#include "lcdtranstbl-CFontz.h" // CFontz output thanks to Stephan Schreiber. +#endif +#ifdef LCD_nomap +#include "lcdtranstbl-nomap.h" // unmapped output (usable for curses output) +#endif + +#define LCDMENU 0 +#define LCDTITLE 1 +#define LCDREPLAY 2 +#define LCDMISC 3 +#define LCDVOL 4 + +// public: + +cLcd::cLcd() { + int i,j; + connected=false; ThreadStateData.showvolume=false; sock=wid=hgt=cellwid=cellhgt=0; + replayDvbApi=NULL; primaryDvbApi=NULL; + + for (i=0;i<LCDMAXSTATES;i++) for (j=0;j<4;j++) { + ThreadStateData.lcdbuffer[i][j][0]=' '; + ThreadStateData.lcdbuffer[i][j][1]='\0'; + ThreadStateData.lcddirty[i][j]=true; + } + ThreadStateData.State=Menu; + for (i=0;i<LCDMAXSTATEBUF;i++) LastState[i]=Title; LastStateP=0; + ThreadStateData.barx=1, ThreadStateData.bary=1, ThreadStateData.barl=0; + for (i=0;i<LCDMAXCARDS;i++) ThreadStateData.CardStat[i]=0; +} + +cLcd::~cLcd() { + if (connected) { /*cLcd::Stop();*/ cLcd::Close(); } //YYYY +} + +bool cLcd::Connect( char *host, unsigned int port ) { + + char istring[1024]; + unsigned int i=0; + + if ( ( sock = sock_connect(host,port) ) < 1) { + return connected=false; + } + + sock_send_string(sock, "hello\n"); + usleep(500000); // wait for a connect message + sock_recv(sock, istring, 1024); + + if ( strncmp("connect LCDproc",istring,15) != 0 ) { cLcd::Close(); return connected=false; } + + while ( (strncmp("lcd",istring+i,3) != 0 ) && (i<(strlen(istring)-5)) ) i++; + + if (sscanf( istring+i,"lcd wid %d hgt %d cellwid %d cellhgt %d" + , &wid, &hgt, &cellwid, &cellhgt) ) connected=true; + + if ((hgt < 4 ) || (wid < 16)) connected = false; // 4 lines are needed, may work with more than 4 though + if (!connected) { cLcd::Close(); return connected; } + + sock_send_string(sock,"screen_add VDR\n"); sock_recv(sock, istring, 1024); + sock_send_string(sock,"screen_set VDR -heartbeat off\n"); sock_recv(sock, istring, 1024); + sock_send_string(sock,"widget_add VDR line1 string\n"); sock_recv(sock, istring, 1024); + sock_send_string(sock,"widget_add VDR line2 string\n"); sock_recv(sock, istring, 1024); + sock_send_string(sock,"widget_add VDR line3 string\n"); sock_recv(sock, istring, 1024); + sock_send_string(sock,"widget_add VDR line4 string\n"); sock_recv(sock, istring, 1024); + sock_send_string(sock,"widget_add VDR prbar hbar\n"); sock_recv(sock, istring, 1024); + sock_send_string(sock,"widget_set VDR prbar 1 1 0\n"); sock_recv(sock, istring, 1024); + + for (i=0; i<LcdMaxKeys;i++) { + sprintf(istring,"client_add_key %c\n",LcdUsedKeys[i]); + sock_send_string(sock,istring); + sock_recv(sock, istring, 1024); + } + + cLcd::Start(); SetThreadState(Title); // Start thread + return connected; +} + +void cLcd::Close() { + sock_close(sock); + connected=false; sock=wid=hgt=cellwid=cellhgt=0; +} + +void cLcd::Info() { // just for testing ... + if (connected) + printf("sock %d, wid %d, hgt %d, cellwid %d, cellhgt %d\n",sock, wid, hgt, cellwid, cellhgt); + else + printf("not connected\n"); +} + +void cLcd::SetTitle( const char *string) { + if (!connected) return; + + unsigned int i; + char title[wid+1]; + const char *trstring=tr("Schedule - %s"); + int trstringlength=strlen(trstring)-3; + + if (strncmp(trstring,string,trstringlength)==0) { + title[0]='>'; snprintf( title+1, wid,"%s",string+trstringlength); + } else if (strlen(string) > (wid-1)) { + snprintf( title, wid+1,"%s",string); + } else { + memset(title,' ',wid/2+1); + snprintf(title + ( (wid-strlen(string))/2 ),wid-( (wid-strlen(string))/2 ),"%s",string); // center title + for (i=0;i<strlen(title);i++) title[i]=toupper(title[i]); // toupper + } + cLcd::SetLine(LCDMENU,0,title); +} + +void cLcd::SetMain( unsigned int n, const char *string) { + if (!connected) return; + + char line2[wid+1]; + char line3[wid+1]; + + if (string != NULL) { + cLcd::Copy(StringBuffer,string,2*wid); + cLcd::Split(StringBuffer,line2,line3); + } + cLcd::SetBuffer(n,NULL,line2,line3,NULL); +} + +void cLcd::SetHelp( unsigned int n, const char *Red, const char *Green, const char *Yellow, const char *Blue) { + if (!connected) return; + + char help[2*wid], red[wid+1], green[wid+1], yellow[wid+1], blue[wid+1]; + unsigned int allchars=0, i, empty=0, spacewid=1; + char *longest, *longest1, *longest2; + + if ( Red==NULL || Red[0]=='\0' ) { + empty++; red[0]=' '; red[1]='\0'; + } else { + strncpy(red,Red,wid); allchars+=strlen(red); + } + if ( Green==NULL || Green[0]=='\0' ) { + empty++; green[0]=' '; green[1]='\0'; + } else { + strncpy(green,Green,wid); allchars+=strlen(green); + } + if ( Yellow==NULL || Yellow[0]=='\0' ) { + empty++; yellow[0]=' '; yellow[1]='\0'; + } else { + strncpy(yellow,Yellow,wid); allchars+=strlen(yellow); + } + if ( Blue==NULL || Blue[0]=='\0' ) { + empty++; blue[0]=' '; blue[1]='\0'; + } else { + strncpy(blue,Blue,wid); allchars+=strlen(blue); + } + + while (allchars > (wid-empty-3)) { + longest1=( strlen(red) > strlen(green) ) ? red : green; + longest2=( strlen(yellow) > strlen(blue) ) ? yellow : blue; + longest =( strlen(longest1) > strlen(longest2) ) ? longest1: longest2; + longest[strlen(longest)-1]='\0'; allchars--; + } + + if (empty>0) { + spacewid=(wid-allchars-3)/empty; + if (spacewid<1) spacewid=1; + char spacer[spacewid+1]; memset(spacer,'-',spacewid); spacer[spacewid]='\0'; + if ( Red==NULL || Red[0]=='\0' ) strncpy(red,spacer,spacewid+1); + if ( Green==NULL || Green[0]=='\0' ) strncpy(green,spacer,spacewid+1); + if ( Yellow==NULL || Yellow[0]=='\0' ) strncpy(yellow,spacer,spacewid+1); + if ( Blue==NULL || Blue[0]=='\0' ) strncpy(blue,spacer,spacewid+1); + } + + #define MANYBLANKS "%s " + + snprintf(help,wid,MANYBLANKS,red); + snprintf(help+strlen(red)+1,wid,MANYBLANKS,green); + snprintf(help+wid-strlen(blue)-strlen(yellow)-1,wid,MANYBLANKS,yellow); + snprintf(help+wid-strlen(blue),strlen(blue)+1,"%s",blue); + for (i=0;i<strlen(help);i++) help[i]=toupper(help[i]); + cLcd::SetLine(n,3,help); +} + +void cLcd::SetStatus( const char *string) { + if (!connected) return; + + char statstring[2*wid+1]; + + if (string == NULL) { + cLcd::SetMain(LCDMENU,StringBuffer); + } else { + cLcd::Copy(statstring,string,2*wid); + cLcd::SetMain(LCDMENU,statstring); + } +} + +void cLcd::SetWarning( const char *string) { + if (!connected) return; + + char statstring[2*wid+1]; + + if (string != NULL) { + cLcd::Copy(statstring,string,2*wid); + cLcd::Clear(LCDMISC); + cLcd::SetMain(LCDMISC,statstring); + cLcd::SetThreadState(Misc); + } +} + +void cLcd::ShowVolume(unsigned int vol, bool muted ) { +if (!connected) return; + BeginMutualExclusion(); + ThreadStateData.volume=vol; + ThreadStateData.muted=muted; + ThreadStateData.showvolume=true; + EndMutualExclusion(); + if (ThreadStateData.muted) { + cLcd::SetLine(Vol,0," "); + cLcd::SetLine(Vol,1,tr("Mute")); + cLcd::SetLine(Vol,2," "); + cLcd::SetLine(Vol,3," "); + } else { + cLcd::SetLine(Vol,0,tr("Volume ")); + cLcd::SetLine(Vol,1,"|---|---|---|---|---|---|---|---|---|---"); + cLcd::SetLine(Vol,2," "); + cLcd::SetLine(Vol,3,"|---|---|---|---|---|---|---|---|---|---"); + } +} + +void cLcd::SetProgress(const char *begin, const char *end, int percent) { + if (!connected) return; + + char workstring[256]; + + if (percent>100) percent=100; if (percent<0) percent=0; + if (begin==NULL) { + BeginMutualExclusion(); + ThreadStateData.barx=1; ThreadStateData.bary=1; ThreadStateData.barl=0; + EndMutualExclusion(); + } else { + time_t t = time(NULL); + if (t != LastProgress) { // output only once a second + int beginw=strlen(begin); + int endw=strlen(end); + sprintf(workstring,"%s", begin); + memset(workstring+beginw,' ',wid-beginw-endw); + sprintf(workstring+wid-endw,"%s", end); + cLcd::SetLine(LCDREPLAY,3,workstring); + BeginMutualExclusion(); + ThreadStateData.barx=beginw+1; + ThreadStateData.bary=4; + ThreadStateData.barl=(percent*cellwid*(wid-beginw-endw))/100; + EndMutualExclusion(); + LastProgress = t; + } + } +} + +void cLcd::SetLine(unsigned int n, unsigned int l, const char *string) { + if (!connected) return; + + BeginMutualExclusion(); + if (string != NULL) strncpy(ThreadStateData.lcdbuffer[n][l],string,wid+1); + ThreadStateData.lcddirty[n][l]=true; + EndMutualExclusion(); +} + +void cLcd::SetLineC(unsigned int n, unsigned int l, const char *string) { + if (!connected) return; + + BeginMutualExclusion(); + if (string != NULL) cLcd::Copy(ThreadStateData.lcdbuffer[n][l],string,wid); + ThreadStateData.lcddirty[n][l]=true; + EndMutualExclusion(); +} + +void cLcd::SetBuffer(unsigned int n, const char *l1,const char *l2,const char *l3,const char *l4) { + if (!connected) return; + + BeginMutualExclusion(); + if (l1 != NULL) strncpy(ThreadStateData.lcdbuffer[n][0],l1,wid+1); ThreadStateData.lcddirty[n][0]=true; + if (l2 != NULL) strncpy(ThreadStateData.lcdbuffer[n][1],l2,wid+1); ThreadStateData.lcddirty[n][1]=true; + if (l3 != NULL) strncpy(ThreadStateData.lcdbuffer[n][2],l3,wid+1); ThreadStateData.lcddirty[n][2]=true; + if (l4 != NULL) strncpy(ThreadStateData.lcdbuffer[n][3],l4,wid+1); ThreadStateData.lcddirty[n][3]=true; + EndMutualExclusion(); +} + +void cLcd::SetRunning( bool nownext, const char *string1, const char *string2, const char *string3) { + if (!connected) return; + + char line[256]; + char line1[256]; + + snprintf(line,256,"%s %s%s%s", + (string1==NULL || string1[0]=='\0')?" ":string1, + (string2==NULL || string2[0]=='\0')?" ":string2, + (string3==NULL || string3[0]=='\0')?"":"|", + (string3==NULL || string3[0]=='\0')?" ":string3); + cLcd::Copy(line1,line,2*wid); + if (nownext) { + cLcd::Split(line1,ThreadStateData.lcdbuffer[LCDMISC][2],ThreadStateData.lcdbuffer[LCDMISC][3]); + ThreadStateData.lcddirty[LCDMISC][2]=true; ThreadStateData.lcddirty[LCDMISC][3]=true; + } else { + BeginMutualExclusion(); + cLcd::Split(line1,ThreadStateData.lcdbuffer[LCDTITLE][2],ThreadStateData.lcdbuffer[LCDTITLE][3]); + ThreadStateData.lcddirty[LCDTITLE][2]=true; ThreadStateData.lcddirty[LCDTITLE][3]=true; + EndMutualExclusion(); + cLcd::SetBuffer(LCDMISC,ThreadStateData.lcdbuffer[LCDTITLE][2],ThreadStateData.lcdbuffer[LCDTITLE][3],NULL,NULL); + } +} + +void cLcd::SummaryInit(char *string) { + SummaryText = string; + SummaryTextL = strlen(string); + SummaryCurrent=0; +} + +void cLcd::SummaryDown() { + if (!connected) return; + + SummaryCurrent=( (SummaryCurrent+4*wid) < SummaryTextL )?SummaryCurrent+4*wid:SummaryCurrent; +} + +void cLcd::SummaryUp() { + if (!connected) return; + + SummaryCurrent=( SummaryCurrent > 4*wid )?SummaryCurrent-4*wid:0; +} + +void cLcd::SummaryDisplay() { + if ( (!connected) || (SummaryTextL < 1) ) return; + + char workstring[256]; + unsigned int i, offset=0; + + for (i=0;i<4;i++) { + if (SummaryCurrent+offset < SummaryTextL) { + strncpy(workstring,SummaryText+SummaryCurrent+offset,wid+1); + workstring[wid]='\0'; + cLcd::SetLine(LCDMENU,i,workstring); + offset+=wid; + } else cLcd::SetLine(LCDMENU,i," "); + } +} + +void cLcd::SetCardStat(unsigned int card, unsigned int stat) { + if (!connected) return; + BeginMutualExclusion(); + ThreadStateData.CardStat[card]=stat; + EndMutualExclusion(); +} + +void cLcd::Clear( unsigned int n) { + if (!connected) return; + + cLcd::SetBuffer(n," "," "," "," "); +} + +void cLcd::SetThreadState( ThreadStates newstate ) { + if (!connected) return; + + BeginMutualExclusion(); + if (ThreadStateData.State != newstate) { + cLcd::LastState[(++LastStateP)%LCDMAXSTATEBUF]=newstate; + ThreadStateData.State=newstate; + ThreadStateData.barx=1, ThreadStateData.bary=1, ThreadStateData.barl=0; + } + EndMutualExclusion(); +} + +void cLcd::PopThreadState() { + BeginMutualExclusion(); + LastStateP=(LastStateP+LCDMAXSTATEBUF-1)%LCDMAXSTATEBUF; + ThreadStateData.State=cLcd::LastState[LastStateP]; + ThreadStateData.barx=1, ThreadStateData.bary=1, ThreadStateData.barl=0; + EndMutualExclusion(); +} + +void cLcd::SetReplayDevice(cControl *DvbApi) { + replayDvbApi=DvbApi; +} + +void cLcd::SetPrimaryDevice(cDevice *DvbApi) { + primaryDvbApi=DvbApi; +} + + +// private: + +// everything between BeginMutualExclusion(); and EndMutualExclusion(); +// should have exclusive access to ThreadStateData + +void cLcd::BeginMutualExclusion() { + CriticalArea.Lock(); +} + +void cLcd::EndMutualExclusion() { + cLcd::CriticalArea.Unlock(); +} + +void cLcd::Copy(char *to, const char *from, unsigned int max) { // eliminates tabs, double blanks ... + + unsigned int i=0 , out=0; + + if (from != NULL) { + while ((out < max) && (from[i] != '\0') ) { + to[out]=(isspace(from[i]))?' ':from[i]; + if ( (out>0) && (to[out-1]==' ') && ispunct(to[out]) ) {to[out-1]=to[out]; to[out]=' '; } + if (!(( (out==0) && (to[out]==' ') ) || + ( (out>0) && (to[out-1]==' ') && (to[out]==' ') ) || + ( (out>0) && ispunct(to[out-1]) && (to[out]==' ') ) + )) out++; + i++; + } + if (out==0) to[out++]=' '; + to[out]='\0'; + } else { + to[0]=' '; to[1]='\0'; + } +} + +void cLcd::Split(const char *string, char *string1, char *string2) { + + strncpy(string1,string,wid+1); + if ( strlen(string) >wid ) { + strncpy(string2,string+wid,wid+1); + } else { + string2[0]=' '; string2[1]='\0'; + } +} + +void cLcd::Write(int line, const char *string) { // used for any text output to LCDd + + char workstring[256]; + unsigned int i,out; + + sprintf(workstring,"widget_set VDR line%d 1 %d \"",line,line); + out=strlen(workstring); + for (i=0;(i<strlen(string)) && (i<wid);i++) + workstring[out++] = LcdTransTbl[ (unsigned char) string[i] ]; // char mapping see lcdtranstbl.h + workstring[out++] = '"'; workstring[out++] = '\n'; workstring[out] = '\0'; + sock_send_string(sock,workstring); +} + +#define FullCycle 10 // seconds +#define TimeCycle 7 // seconds + +void cLcd::GetTimeDateStat( char *string, unsigned int OutStateData[] ) { + time_t t; + struct tm *now; + unsigned int i; + const char States[] = ".-*>"; // '.' ... not present, '-' ... present, '*' ... recording, '>' ... replaying + bool ShowStates=false; + unsigned int offset; + + offset=(wid>36)?20:0; + for (i=0; i<LCDMAXCARDS && (!ShowStates) ; i++) ShowStates = ShowStates || (OutStateData[i]>1); + + t = time(NULL); + now = localtime(&t); + + if ( offset || !( ShowStates && ((t%FullCycle) >= TimeCycle) )) { + if (wid > 19) + snprintf(string,wid+1,"<%s %02d.%02d %02d:%02d:%02d>", + WeekDayName(now->tm_wday), now->tm_mday, now->tm_mon+1, now->tm_hour, now->tm_min,now->tm_sec); + else + snprintf(string,wid+1,"<%02d.%02d %02d:%02d:%02d>", + now->tm_mday, now->tm_mon+1, now->tm_hour, now->tm_min,now->tm_sec); + } + + if ( offset || ( ShowStates && ((t%FullCycle) >= TimeCycle) )) { + for (i=0; i<LCDMAXCARDS; i++) { + snprintf(string+offset,5," %d:%c", i,States[ OutStateData[i] ] ); + offset+=4; + } + } + +} + +#define WakeUpCycle 125000 // us +#define VolumeKeep 1500000 // us + +void cLcd::Action(void) { // LCD output thread + unsigned int i,j, barx=1, bary=1, barl=0; + int Current=0, Total=1; + struct timeval now, voltime; + char workstring[256]; + cLcd::ThreadStates PrevState=Menu; + struct cLcd::StateData OutStateData; + bool Lcddirty[LCDMAXSTATES][4]; + bool LcdShiftkeyPressed=false; + + syslog(LOG_INFO, "LCD output thread started (pid=%d), display size: %dx%d", getpid(),hgt,wid); + cLcd::Write(1," Welcome to V D R\0"); + cLcd::Write(2,"--------------------\0"); + cLcd::Write(3,"Video Disk Recorder\0"); + cLcd::Write(4,"Version: "VDRVERSION"\0"); + sleep(5); bool volume=false; OutStateData.showvolume=false; ThreadStateData.showvolume=false; + + if (primaryDvbApi) for (int k=0; k<primaryDvbApi->NumDevices() ; k++) SetCardStat(k,1); + + voltime.tv_sec=0; + for (i=0;i<LCDMAXSTATES;i++) for (j=0;j<4;j++) Lcddirty[i][j]=true; + time_t nextLcdUpdate = (time(NULL)/60)*60+60; + + while (true) { // main loop, wakes up every WakeUpCycle, any output to LCDd is done here + gettimeofday(&now,NULL); + + // epg update + + if ( time(NULL) > nextLcdUpdate ) { + const cEventInfo *Present = NULL; + cMutexLock MutexLock; + const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock); + if (Schedules) { + const cSchedule *Schedule = Schedules->GetSchedule(); + if (Schedule) { + const char *PresentTitle, *PresentSubtitle; + PresentTitle = NULL; PresentSubtitle = NULL; + if ((Present = Schedule->GetPresentEvent()) != NULL) { + nextLcdUpdate=Present->GetTime()+Present->GetDuration(); + PresentTitle = Present->GetTitle(); + PresentSubtitle = Present->GetSubtitle(); + if ( (!isempty(PresentTitle)) && (!isempty(PresentSubtitle)) ) + SetRunning(false,Present->GetTimeString(),PresentTitle,PresentSubtitle); + else if (!isempty(PresentTitle)) SetRunning(false,Present->GetTimeString(),PresentTitle); + } + if ((Present = Schedule->GetFollowingEvent()) != NULL) + nextLcdUpdate=(Present->GetTime()<nextLcdUpdate)?Present->GetTime():nextLcdUpdate; + } + } + if ( nextLcdUpdate <= time(NULL) ) + nextLcdUpdate=(time(NULL)/60)*60+60; + else if ( nextLcdUpdate > time(NULL)+60 ) + nextLcdUpdate=(time(NULL)/60)*60+60; + } + + // replaying + + if ( (now.tv_usec < WakeUpCycle) && (replayDvbApi) ) { + char tempbuffer[16]; + replayDvbApi->GetIndex(Current, Total, false); + sprintf(tempbuffer,IndexToHMSF(Total)); + SetProgress(IndexToHMSF(Current),tempbuffer, (100 * Current) / Total); + } + + // copy + + BeginMutualExclusion(); // all data needed for output are copied here + memcpy(&OutStateData,&ThreadStateData, sizeof (cLcd::StateData)); + ThreadStateData.showvolume=false; + for (i=0;i<LCDMAXSTATES;i++) for (j=0;j<4;j++) { + ThreadStateData.lcddirty[i][j]=false; + Lcddirty[i][j]= Lcddirty[i][j] || OutStateData.lcddirty[i][j]; + } + EndMutualExclusion(); + + // volume + + if (OutStateData.showvolume) gettimeofday(&voltime,NULL); + if ( voltime.tv_sec != 0) { // volume + if ( ((now.tv_sec - voltime.tv_sec)*1000000+now.tv_usec-voltime.tv_usec ) > 1500000 ) { + voltime.tv_sec=0; + OutStateData.barx=1; OutStateData.bary=1; OutStateData.barl=0; volume=false; + } else { + volume=true; + OutStateData.barx=1; OutStateData.bary=3; + OutStateData.barl=(cellwid*wid*OutStateData.volume)/255; + } + } + if (volume) OutStateData.State = Vol; + // modes + + switch (OutStateData.State) { + + case Menu: // display menu = 0 + if (PrevState != Menu) for (i=0;i<4;i++) Lcddirty[LCDMENU][i]=true; + for (i=0;i<4;i++) if (Lcddirty[LCDMENU][i]) { + cLcd::Write(i+1,OutStateData.lcdbuffer[LCDMENU][i]); + Lcddirty[LCDMENU][i]=false; + } + PrevState=Menu; + break; + + case Title: // Display 'titlescsreen' = 1 + if ( (now.tv_usec < WakeUpCycle) || (PrevState != Title) ) { + cLcd::GetTimeDateStat(workstring,OutStateData.CardStat); + cLcd::Write(1,workstring); + } + if (PrevState != Title) for (i=1;i<4;i++) Lcddirty[LCDTITLE][i]=true; + for (i=1;i<4;i++) if (Lcddirty[LCDTITLE][i]) { + cLcd::Write(i+1,OutStateData.lcdbuffer[LCDTITLE][i]); + Lcddirty[LCDTITLE][i]=false; + } + PrevState = Title; + break; + + case Replay: // Display date/time during replaying = 2 + if ( (now.tv_usec < WakeUpCycle) || (PrevState != Replay) ) { + cLcd::GetTimeDateStat(workstring,OutStateData.CardStat); + cLcd::Write(1,workstring); + } + if (PrevState != Replay) for (i=1;i<4;i++) Lcddirty[LCDREPLAY][i]=true; + for (i=1;i<4;i++) if (Lcddirty[LCDREPLAY][i]) { + cLcd::Write(i+1,OutStateData.lcdbuffer[LCDREPLAY][i]); + Lcddirty[LCDREPLAY][i]=false; + } + PrevState = Replay; + break; + + case Misc: // Display messages = 3 + if (PrevState != Misc) for (i=0;i<4;i++) Lcddirty[LCDMISC][i]=true; + for (i=0;i<4;i++) if (Lcddirty[LCDMISC][i]) { + cLcd::Write(i+1,OutStateData.lcdbuffer[LCDMISC][i]); + Lcddirty[LCDMISC][i]=false; + } + PrevState = Misc; + break; + + case Vol: // Display Volume = 4 + if (PrevState != Vol) for (i=0;i<4;i++) Lcddirty[LCDVOL][i]=true; + for (i=0;i<4;i++) if (Lcddirty[LCDVOL][i]) { + cLcd::Write(i+1,OutStateData.lcdbuffer[LCDVOL][i]); + Lcddirty[LCDVOL][i]=false; + } + PrevState = Vol; + break; + + default: // quite impossible :) + break; + } + + // bargraph + if ( (OutStateData.barx != barx) || (OutStateData.bary != bary) || (OutStateData.barl != barl) ) { + sprintf(workstring,"widget_set VDR prbar %d %d %d\n",OutStateData.barx,OutStateData.bary,OutStateData.barl); + sock_send_string(sock,workstring); + barx=OutStateData.barx; bary=OutStateData.bary; barl=OutStateData.barl; + } + + // keys + workstring[0]='\0'; sock_recv(sock, workstring, 256); + if ( strlen(workstring) > 4 ) { + for (i=0; i < (strlen(workstring)-4); i++ ) { + if (workstring[i]=='k' && workstring[i+1]=='e' && workstring[i+2]=='y' && workstring[i+3]==' ') { + if (workstring[i+4] == LcdShiftKey) { + LcdShiftkeyPressed = ! LcdShiftkeyPressed; + if (LcdShiftkeyPressed) + sock_send_string(sock,"screen_set VDR -heartbeat on\n"); + else + sock_send_string(sock,"screen_set VDR -heartbeat off\n"); + } + if ( (workstring[i+4] != LcdShiftKey) ) { + if (LcdShiftkeyPressed) { + syslog(LOG_INFO, "shiftkey pressed: %c", workstring[i+4] ); + LcdShiftkeyPressed=false; + sock_send_string(sock,"screen_set VDR -heartbeat off\n"); + } else { + syslog(LOG_INFO, "normalkey pressed: %c", workstring[i+4] ); + } + } + } + } + } + + usleep(WakeUpCycle-(now.tv_usec%WakeUpCycle)); // sync to systemtime for nicer time output + } +} @@ -0,0 +1,75 @@ +#ifndef __LCD_H +#define __LCD_H + +#include <vdr/thread.h> +#include <vdr/device.h> +#include <vdr/player.h> +#include <vdr/dvbplayer.h> + +#define LCDPORT 13666 +#define LCDHOST "localhost" +#define LCDMAXSTATES 5 +#define LCDMAXSTATEBUF 5 +#define LCDMAXWID 40 +#define LCDMAXCARDS 4 + +class cLcd : public cThread { + public: + cControl *replayDvbApi; + cDevice *primaryDvbApi; + enum ThreadStates {Menu=0, Title=1, Replay=2, Misc=3, Vol=4}; + ThreadStates LastState[LCDMAXSTATEBUF]; + int LastStateP; + struct StateData { + char lcdbuffer[LCDMAXSTATES][4][LCDMAXWID+1]; + bool lcddirty[LCDMAXSTATES][4], muted, showvolume; + ThreadStates State; + unsigned int barx, bary, barl, volume; + unsigned int CardStat[LCDMAXCARDS]; + }; + cLcd(); + ~cLcd(); + bool Connect( char *host = LCDHOST , unsigned int port = LCDPORT ); + void Close(); + void Info(); + void SetTitle( const char *string); + void SetMain( unsigned int n, const char *string); + void SetHelp( unsigned int n, const char *Red, const char *Green, const char *Yellow, const char *Blue); + void SetStatus( const char *string); + void SetWarning( const char *string); + void ShowVolume(unsigned int vol, bool muted ); + void SetProgress(const char *begin=NULL, const char *end=NULL, int percent=0); + void SetLine(unsigned int n, unsigned int l, const char *string); + void SetLineC(unsigned int n, unsigned int l, const char *string); + void SetBuffer(unsigned int n,const char *l1=NULL,const char *l2=NULL,const char *l3=NULL,const char *l4=NULL); + void SetRunning(bool nownext, const char *string1="\0", const char *string2="\0", const char *string3="\0"); + void SummaryInit(char *string); + void SummaryUp(); + void SummaryDown(); + void SummaryDisplay(); + void SetCardStat(unsigned int card, unsigned int stat); + void Clear(unsigned int n); + void SetThreadState( ThreadStates newstate ); + void PopThreadState(); + void SetReplayDevice(cControl *DvbApi); + void SetPrimaryDevice(cDevice *DvbApi); + private: + char *SummaryText; + unsigned int SummaryTextL; + unsigned int SummaryCurrent; + bool connected; + struct StateData ThreadStateData; + time_t LastProgress; + cMutex CriticalArea; + unsigned int sock, wid, hgt, cellwid, cellhgt; + char StringBuffer[2*LCDMAXWID+1]; + void BeginMutualExclusion(); + void EndMutualExclusion(); + void Copy(char *to, const char *from, unsigned int max); + void Split(const char *string, char *string1, char *string2); + void Write(int line, const char *string); + void GetTimeDateStat( char *string, unsigned int OutStateData[] ); + void Action(void); +}; + +#endif //__LCD_H diff --git a/lcdkeyconf.h b/lcdkeyconf.h new file mode 100644 index 0000000..ee4f843 --- /dev/null +++ b/lcdkeyconf.h @@ -0,0 +1,7 @@ +// LCDproc keys + +const unsigned int LcdMaxKeys = 5; +const unsigned char LcdShiftKey = '#'; +const unsigned char LcdUsedKeys[LcdMaxKeys] = {'0', '3', '6', 'A', '#'}; +//const eKeys LcdNormalMap[LcdMaxKeys] = { kBack, kLeft, kPower, kVolDn, kMute}; +//const eKeys LcdShiftMap[LcdMaxKeys] = { k1, k2, kOk, k4, k8}; diff --git a/lcdproc.c b/lcdproc.c new file mode 100644 index 0000000..d20ff80 --- /dev/null +++ b/lcdproc.c @@ -0,0 +1,299 @@ +/* + * status.c: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id$ + */ + +#include <getopt.h> +#include <ctype.h> +#include <vdr/plugin.h> +#include <vdr/status.h> +#include <vdr/recording.h> +#include "lcd.h" + +static const char *VERSION = "0.0.1"; +static const char *MAINMENUENTRY = NULL; +#ifdef LCD_hd44780 +static const char *DESCRIPTION = "LCDproc using hd44780 output-mapping"; +#endif +#ifdef LCD_CFontz +static const char *DESCRIPTION = "LCDproc using CFontz output-mapping"; +#endif +#ifdef LCD_nomap +static const char *DESCRIPTION = "LCDproc using no output-mapping"; +#endif + +cLcd *LCDproc = new cLcd; +bool replaymode=false; +bool menumode=false; +bool switched=false; +bool group=false; +char tempstringbuffer[80]; +char *LCDprocHOST=LCDHOST; +unsigned int LCDprocPORT=LCDPORT; + +// --- + +class cLcdFeed : public cStatus { +protected: + virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber); + virtual void Recording(const cDevice *Device, const char *Name); + virtual void Replaying(const cControl *DvbPlayerControl, const char *Name); + virtual void SetVolume(int Volume, bool Absolute); + virtual void OsdClear(void); + virtual void OsdTitle(const char *Title); + virtual void OsdStatusMessage(const char *Message); + virtual void OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue); + virtual void OsdCurrentItem(const char *Text); + virtual void OsdTextItem(const char *Text, bool Scroll); + virtual void OsdChannel(const char *Text); + virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle); + }; + + +void cLcdFeed::ChannelSwitch(const cDevice *Device, int ChannelNumber) +{ + syslog(LOG_INFO, "lcdproc: cLcdFeed::ChannelSwitch %d %d", Device->CardIndex(), ChannelNumber); + if (ChannelNumber) { + LCDproc->SetLine(1,2," "); + LCDproc->SetLine(1,3," "); + switched = true; + } else switched = false; + if (Device) LCDproc->SetPrimaryDevice( (cDevice *) Device ); +} + +void cLcdFeed::Recording(const cDevice *Device, const char *Name) +{ + syslog(LOG_INFO, "lcdproc: cLcdFeed::Recording %d %s", Device->CardIndex(), Name); + if (Name) + LCDproc->SetCardStat(Device->CardIndex(),2); + else + LCDproc->SetCardStat(Device->CardIndex(),1); +} + +void cLcdFeed::Replaying(const cControl *DvbPlayerControl, const char *Name) +{ + syslog(LOG_INFO, "lcdproc: cLcdFeed::Replaying %s", Name); + replaymode=(Name)?true:false; + if ( replaymode ) { + LCDproc->SetReplayDevice( (cDvbPlayerControl *) DvbPlayerControl); + LCDproc->SetMain(2, Name); + LCDproc->SetThreadState( (cLcd::ThreadStates) 2); // Replaying + } else { + LCDproc->SetReplayDevice(NULL); + LCDproc->SetProgress(NULL); + LCDproc->SetLineC(1,1,tempstringbuffer); + LCDproc->SetThreadState( (cLcd::ThreadStates) 1); // Title + } + menumode=false; +} + +void cLcdFeed::SetVolume(int Volume, bool Absolute) +{ + syslog(LOG_INFO, "lcdproc: cLcdFeed::SetVolume %d %d", Volume, Absolute); + LCDproc->ShowVolume( Volume, Absolute ); +} + +void cLcdFeed::OsdClear(void) +{ + syslog(LOG_INFO, "lcdproc: cLcdFeed::OsdClear"); + + if (replaymode) + LCDproc->SetThreadState( (cLcd::ThreadStates) 2); // Replaying + else + LCDproc->SetThreadState( (cLcd::ThreadStates) 1); // Title + menumode=false; + if (group) {LCDproc->SetLineC(1,1,tempstringbuffer); group=false; } +} + +void cLcdFeed::OsdTitle(const char *Title) +{ + syslog(LOG_INFO, "lcdproc: cLcdFeed::OsdTitle '%s'", Title); + LCDproc->Clear(0); + LCDproc->SetTitle(Title); + LCDproc->SetThreadState( (cLcd::ThreadStates) 0); // MENU + menumode=true; +} + +void cLcdFeed::OsdStatusMessage(const char *Message) +{ + syslog(LOG_INFO, "lcdproc: cLcdFeed::OsdStatusMessage '%s'", Message); + if ( Message ) + if ( menumode ) + LCDproc->SetStatus(Message); + else + LCDproc->SetWarning(Message); +} + +void cLcdFeed::OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue) +{ + syslog(LOG_INFO, "lcdproc: cLcdFeed::OsdHelpKeys %s - %s - %s - %s", Red, Green, Yellow, Blue); + LCDproc->SetHelp(0,Red, Green, Yellow, Blue); +} + +void cLcdFeed::OsdCurrentItem(const char *Text) +{ + syslog(LOG_INFO, "lcdproc: cLcdFeed::OsdCurrentItem %s", Text); + LCDproc->SetMain(0,Text); +} + +void cLcdFeed::OsdTextItem(const char *Text, bool Scroll) +{ + syslog(LOG_INFO, "lcdproc: cLcdFeed::OsdTextItem %s %d", Text, Scroll); + if (Text) + LCDproc->SummaryInit( (char *) Text); + else if (Scroll) + LCDproc->SummaryUp(); + else + LCDproc->SummaryDown(); + LCDproc->SummaryDisplay(); +} + +void cLcdFeed::OsdChannel(const char *Text) +{ + syslog(LOG_INFO, "lcdproc: cLcdFeed::OsdChannel %s", Text); + LCDproc->SetLineC(1,1,Text); + + bool switching = group = !isdigit(Text[0]); + if (!group) strcpy(tempstringbuffer,Text); + for (unsigned int i=0; ( i<strlen(Text)-1 ) && !switching ; i++) { + switching= isdigit(Text[i]) && Text[i+1]=='-' ; + } + + if (switched || switching) + LCDproc->SetThreadState( (cLcd::ThreadStates) 1); // TITLE + else + LCDproc->SetThreadState( (cLcd::ThreadStates) 3); // MISC + + switched=false; menumode=false; +} + +void cLcdFeed::OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle) +{ + char buffer[25]; + struct tm tm_r; + syslog(LOG_INFO, "lcdproc: cLcdFeed::OsdProgramme"); + strftime(buffer, sizeof(buffer), "%R", localtime_r(&PresentTime, &tm_r)); + syslog(LOG_INFO, "%5s %s", buffer, PresentTitle); + syslog(LOG_INFO, "%5s %s", "", PresentSubtitle); + + + if ( (!isempty(PresentTitle)) && (!isempty(PresentSubtitle)) ) + LCDproc->SetRunning(false,buffer,PresentTitle,PresentSubtitle); + else if (!isempty(PresentTitle)) LCDproc->SetRunning(false,buffer,PresentTitle); + + + strftime(buffer, sizeof(buffer), "%R", localtime_r(&FollowingTime, &tm_r)); + syslog(LOG_INFO, "%5s %s", buffer, FollowingTitle); + syslog(LOG_INFO, "%5s %s", "", FollowingSubtitle); + + if ( (!isempty(FollowingTitle)) && (!isempty(FollowingSubtitle)) ) + LCDproc->SetRunning(true,buffer,FollowingTitle,FollowingSubtitle); + else if (!isempty(FollowingTitle)) LCDproc->SetRunning(true,buffer,FollowingTitle); + +} + +// --- + +class cPluginLcd : public cPlugin { +private: + // Add any member variables or functions you may need here. + cLcdFeed *lcdFeed; +public: + cPluginLcd(void); + virtual ~cPluginLcd(); + virtual const char *Version(void) { return VERSION; } + virtual const char *Description(void) { return DESCRIPTION; } + virtual const char *CommandLineHelp(void); + virtual bool ProcessArgs(int argc, char *argv[]); + virtual bool Start(void); + virtual void Housekeeping(void); + virtual const char *MainMenuEntry(void) { return MAINMENUENTRY; } + virtual cOsdMenu *MainMenuAction(void); + virtual cMenuSetupPage *SetupMenu(void); + virtual bool SetupParse(const char *Name, const char *Value); + }; + +cPluginLcd::cPluginLcd(void) +{ + // Initialize any member varaiables here. + // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL + // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT! + lcdFeed = NULL; + +} + +cPluginLcd::~cPluginLcd() +{ + // Clean up after yourself! + delete lcdFeed; + delete LCDproc; +} + +const char *cPluginLcd::CommandLineHelp(void) +{ + // Return a string that describes all known command line options. + return " -h <host>, --host <host> LCDproc host (default=localhost)\n -p <port>, --port <port> LCDproc port (default=13666)\n"; + +} + +bool cPluginLcd::ProcessArgs(int argc, char *argv[]) +{ + // Implement command line argument processing here if applicable. + + static struct option long_options[] = { + { "host", required_argument, NULL, 'h' }, + { "port", required_argument, NULL, 'p' }, + { NULL } + }; + + int c; + while ((c = getopt_long(argc, argv, "h:p:", long_options, NULL)) != -1) { + switch (c) { + case 'h': LCDprocHOST=optarg; + break; + case 'p': LCDprocPORT=atoi(optarg); + break; + default: return false; + } + } + return true; +} + +bool cPluginLcd::Start(void) +{ + // Start any background activities the plugin shall perform. + lcdFeed = new cLcdFeed; + if ( LCDproc->Connect(LCDprocHOST,LCDprocPORT) ) { + syslog(LOG_INFO, "connection to LCDd at %s:%d established.",LCDprocHOST,LCDprocPORT); + return true; + } + return false; +} + +void cPluginLcd::Housekeeping(void) +{ + // Perform any cleanup or other regular tasks. +} + +cOsdMenu *cPluginLcd::MainMenuAction(void) +{ + // Perform the action when selected from the main VDR menu. + return NULL; +} + +cMenuSetupPage *cPluginLcd::SetupMenu(void) +{ + // Return a setup menu in case the plugin supports one. + return NULL; +} + +bool cPluginLcd::SetupParse(const char *Name, const char *Value) +{ + // Parse your own setup parameters and store their values. + return false; +} + +VDRPLUGINCREATOR(cPluginLcd); // Don't touch this! diff --git a/lcdtranstbl-CFontz.h b/lcdtranstbl-CFontz.h new file mode 100644 index 0000000..0086a33 --- /dev/null +++ b/lcdtranstbl-CFontz.h @@ -0,0 +1,265 @@ +/* +lcdtranstbl-CFontz.h +this table is used to map characters for output to +a Crystal Fontz LCD to display some special characters correctly. +newline,tab and friends are mapped to ' ' +*/ + +const unsigned char LcdTransTbl[256]={ +/* 0 ( '^@') */ (unsigned char) 0, +/* 1 ( '^A') */ (unsigned char) 1, +/* 2 ( '^B') */ (unsigned char) 2, +/* 3 ( '^C') */ (unsigned char) 3, +/* 4 ( '^D') */ (unsigned char) 4, +/* 5 ( '^E') */ (unsigned char) 5, +/* 6 ( '^F') */ (unsigned char) 6, +/* 7 ( '^G') */ (unsigned char) 7, +/* 8 ( '^H') */ (unsigned char) 8, +/* 9 ( '' ) */ (unsigned char) 32, +/* 10 ( '' ) */ (unsigned char) 32, +/* 11 ( '^K') */ (unsigned char) 32, +/* 12 ( '^L') */ (unsigned char) 32, +/* 13 ( '^M') */ (unsigned char) 32, +/* 14 ( '^N') */ (unsigned char) 14, +/* 15 ( '^O') */ (unsigned char) 15, +/* 16 ( '^P') */ (unsigned char) 16, +/* 17 ( '^Q') */ (unsigned char) 17, +/* 18 ( '^R') */ (unsigned char) 18, +/* 19 ( '^S') */ (unsigned char) 19, +/* 20 ( '^T') */ (unsigned char) 20, +/* 21 ( '^U') */ (unsigned char) 21, +/* 22 ( '^V') */ (unsigned char) 22, +/* 23 ( '^W') */ (unsigned char) 23, +/* 24 ( '^X') */ (unsigned char) 24, +/* 25 ( '^Y') */ (unsigned char) 25, +/* 26 ( '^Z') */ (unsigned char) 26, +/* 27 ( '^[') */ (unsigned char) 27, +/* 28 ( '^\') */ (unsigned char) 28, +/* 29 ( '^]') */ (unsigned char) 29, +/* 30 ( '^^') */ (unsigned char) 30, +/* 31 ( '^_') */ (unsigned char) 31, +/* 32 ( ' ' ) */ (unsigned char) 32, +/* 33 ( '!' ) */ (unsigned char) 33, +/* 34 ( '"' ) */ (unsigned char) 39, +/* 35 ( '#' ) */ (unsigned char) 35, +/* 36 ( '$' ) */ (unsigned char) 36, +/* 37 ( '%' ) */ (unsigned char) 37, +/* 38 ( '&' ) */ (unsigned char) 38, +/* 39 ( ''' ) */ (unsigned char) 39, +/* 40 ( '(' ) */ (unsigned char) 40, +/* 41 ( ')' ) */ (unsigned char) 41, +/* 42 ( '*' ) */ (unsigned char) 42, +/* 43 ( '+' ) */ (unsigned char) 43, +/* 44 ( ',' ) */ (unsigned char) 44, +/* 45 ( '-' ) */ (unsigned char) 45, +/* 46 ( '.' ) */ (unsigned char) 46, +/* 47 ( '/' ) */ (unsigned char) 47, +/* 48 ( '0' ) */ (unsigned char) 48, +/* 49 ( '1' ) */ (unsigned char) 49, +/* 50 ( '2' ) */ (unsigned char) 50, +/* 51 ( '3' ) */ (unsigned char) 51, +/* 52 ( '4' ) */ (unsigned char) 52, +/* 53 ( '5' ) */ (unsigned char) 53, +/* 54 ( '6' ) */ (unsigned char) 54, +/* 55 ( '7' ) */ (unsigned char) 55, +/* 56 ( '8' ) */ (unsigned char) 56, +/* 57 ( '9' ) */ (unsigned char) 57, +/* 58 ( ':' ) */ (unsigned char) 58, +/* 59 ( ';' ) */ (unsigned char) 59, +/* 60 ( '<' ) */ (unsigned char) 60, +/* 61 ( '=' ) */ (unsigned char) 61, +/* 62 ( '>' ) */ (unsigned char) 62, +/* 63 ( '?' ) */ (unsigned char) 63, +/* 64 ( '@' ) */ (unsigned char) 160, +/* 65 ( 'A' ) */ (unsigned char) 65, +/* 66 ( 'B' ) */ (unsigned char) 66, +/* 67 ( 'C' ) */ (unsigned char) 67, +/* 68 ( 'D' ) */ (unsigned char) 68, +/* 69 ( 'E' ) */ (unsigned char) 69, +/* 70 ( 'F' ) */ (unsigned char) 70, +/* 71 ( 'G' ) */ (unsigned char) 71, +/* 72 ( 'H' ) */ (unsigned char) 72, +/* 73 ( 'I' ) */ (unsigned char) 73, +/* 74 ( 'J' ) */ (unsigned char) 74, +/* 75 ( 'K' ) */ (unsigned char) 75, +/* 76 ( 'L' ) */ (unsigned char) 76, +/* 77 ( 'M' ) */ (unsigned char) 77, +/* 78 ( 'N' ) */ (unsigned char) 78, +/* 79 ( 'O' ) */ (unsigned char) 79, +/* 80 ( 'P' ) */ (unsigned char) 80, +/* 81 ( 'Q' ) */ (unsigned char) 81, +/* 82 ( 'R' ) */ (unsigned char) 82, +/* 83 ( 'S' ) */ (unsigned char) 83, +/* 84 ( 'T' ) */ (unsigned char) 84, +/* 85 ( 'U' ) */ (unsigned char) 85, +/* 86 ( 'V' ) */ (unsigned char) 86, +/* 87 ( 'W' ) */ (unsigned char) 87, +/* 88 ( 'X' ) */ (unsigned char) 88, +/* 89 ( 'Y' ) */ (unsigned char) 89, +/* 90 ( 'Z' ) */ (unsigned char) 90, +/* 91 ( '[' ) */ (unsigned char) 250, +/* 92 ( '\' ) */ (unsigned char) 251, +/* 93 ( ']' ) */ (unsigned char) 252, +/* 94 ( '^' ) */ (unsigned char) 222, +/* 95 ( '_' ) */ (unsigned char) 196, +/* 96 ( '`' ) */ (unsigned char) 39, +/* 97 ( 'a' ) */ (unsigned char) 97, +/* 98 ( 'b' ) */ (unsigned char) 98, +/* 99 ( 'c' ) */ (unsigned char) 99, +/* 100 ( 'd' ) */ (unsigned char) 100, +/* 101 ( 'e' ) */ (unsigned char) 101, +/* 102 ( 'f' ) */ (unsigned char) 102, +/* 103 ( 'g' ) */ (unsigned char) 103, +/* 104 ( 'h' ) */ (unsigned char) 104, +/* 105 ( 'i' ) */ (unsigned char) 105, +/* 106 ( 'j' ) */ (unsigned char) 106, +/* 107 ( 'k' ) */ (unsigned char) 107, +/* 108 ( 'l' ) */ (unsigned char) 108, +/* 109 ( 'm' ) */ (unsigned char) 109, +/* 110 ( 'n' ) */ (unsigned char) 110, +/* 111 ( 'o' ) */ (unsigned char) 111, +/* 112 ( 'p' ) */ (unsigned char) 112, +/* 113 ( 'q' ) */ (unsigned char) 113, +/* 114 ( 'r' ) */ (unsigned char) 114, +/* 115 ( 's' ) */ (unsigned char) 115, +/* 116 ( 't' ) */ (unsigned char) 116, +/* 117 ( 'u' ) */ (unsigned char) 117, +/* 118 ( 'v' ) */ (unsigned char) 118, +/* 119 ( 'w' ) */ (unsigned char) 119, +/* 120 ( 'x' ) */ (unsigned char) 120, +/* 121 ( 'y' ) */ (unsigned char) 121, +/* 122 ( 'z' ) */ (unsigned char) 122, +/* 123 ( '{' ) */ (unsigned char) 253, +/* 124 ( '|' ) */ (unsigned char) 221, +/* 125 ( '}' ) */ (unsigned char) 255, +/* 126 ( '~' ) */ (unsigned char) 206, +/* 127 ( '^?') */ (unsigned char) 127, +/* 128 ( '~@') */ (unsigned char) 128, +/* 129 ( '~A') */ (unsigned char) 129, +/* 130 ( '~B') */ (unsigned char) 130, +/* 131 ( '~C') */ (unsigned char) 131, +/* 132 ( '~D') */ (unsigned char) 132, +/* 133 ( '~E') */ (unsigned char) 133, +/* 134 ( '~F') */ (unsigned char) 134, +/* 135 ( '~G') */ (unsigned char) 135, +/* 136 ( '~H') */ (unsigned char) 136, +/* 137 ( '~I') */ (unsigned char) 137, +/* 138 ( '~J') */ (unsigned char) 138, +/* 139 ( '~K') */ (unsigned char) 139, +/* 140 ( '~L') */ (unsigned char) 140, +/* 141 ( '~M') */ (unsigned char) 141, +/* 142 ( '~N') */ (unsigned char) 142, +/* 143 ( '~O') */ (unsigned char) 143, +/* 144 ( '~P') */ (unsigned char) 144, +/* 145 ( '~Q') */ (unsigned char) 145, +/* 146 ( '~R') */ (unsigned char) 146, +/* 147 ( '~S') */ (unsigned char) 147, +/* 148 ( '~T') */ (unsigned char) 148, +/* 149 ( '~U') */ (unsigned char) 149, +/* 150 ( '~V') */ (unsigned char) 150, +/* 151 ( '~W') */ (unsigned char) 151, +/* 152 ( '~X') */ (unsigned char) 152, +/* 153 ( '~Y') */ (unsigned char) 153, +/* 154 ( '~Z') */ (unsigned char) 154, +/* 155 ( '~[') */ (unsigned char) 155, +/* 156 ( '~\') */ (unsigned char) 156, +/* 157 ( '~]') */ (unsigned char) 157, +/* 158 ( '~^') */ (unsigned char) 158, +/* 159 ( '~_') */ (unsigned char) 159, +/* 160 ( '| ') */ (unsigned char) 160, +/* 161 ( '¡' ) */ (unsigned char) 64, +/* 162 ( '¢' ) */ (unsigned char) 177, +/* 163 ( '£' ) */ (unsigned char) 161, +/* 164 ( '¤' ) */ (unsigned char) 36, +/* 165 ( '¥' ) */ (unsigned char) 163, +/* 166 ( '¦' ) */ (unsigned char) 254, +/* 167 ( '§' ) */ (unsigned char) 95, +/* 168 ( '¨' ) */ (unsigned char) 221, +/* 169 ( '©' ) */ (unsigned char) 171, +/* 170 ( 'ª' ) */ (unsigned char) 170, +/* 171 ( '«' ) */ (unsigned char) 171, +/* 172 ( '¬' ) */ (unsigned char) 172, +/* 173 ( '' ) */ (unsigned char) 173, +/* 174 ( '®' ) */ (unsigned char) 174, +/* 175 ( '¯' ) */ (unsigned char) 175, +/* 176 ( '°' ) */ (unsigned char) 207, +/* 177 ( '±' ) */ (unsigned char) 140, +/* 178 ( '²' ) */ (unsigned char) 130, +/* 179 ( '³' ) */ (unsigned char) 131, +/* 180 ( '´' ) */ (unsigned char) 39, +/* 181 ( 'µ' ) */ (unsigned char) 143, +/* 182 ( '¶' ) */ (unsigned char) 182, +/* 183 ( '·' ) */ (unsigned char) 183, +/* 184 ( '¸' ) */ (unsigned char) 184, +/* 185 ( '¹' ) */ (unsigned char) 129, +/* 186 ( 'º' ) */ (unsigned char) 221, +/* 187 ( '»' ) */ (unsigned char) 187, +/* 188 ( '¼' ) */ (unsigned char) 139, +/* 189 ( '½' ) */ (unsigned char) 138, +/* 190 ( '¾' ) */ (unsigned char) 190, +/* 191 ( '¿' ) */ (unsigned char) 96, +/* 192 ( 'À' ) */ (unsigned char) 65, +/* 193 ( 'Á' ) */ (unsigned char) 226, +/* 194 ( 'Â' ) */ (unsigned char) 65, +/* 195 ( 'Ã' ) */ (unsigned char) 65, +/* 196 ( 'Ä' ) */ (unsigned char) 91, +/* 197 ( 'Å' ) */ (unsigned char) 174, +/* 198 ( 'Æ' ) */ (unsigned char) 188, +/* 199 ( 'Ç' ) */ (unsigned char) 169, +/* 200 ( 'È' ) */ (unsigned char) 197, +/* 201 ( 'É' ) */ (unsigned char) 191, +/* 202 ( 'Ê' ) */ (unsigned char) 198, +/* 203 ( 'Ë' ) */ (unsigned char) 69, +/* 204 ( 'Ì' ) */ (unsigned char) 73, +/* 205 ( 'Í' ) */ (unsigned char) 227, +/* 206 ( 'Î' ) */ (unsigned char) 73, +/* 207 ( 'Ï' ) */ (unsigned char) 73, +/* 208 ( 'Ð' ) */ (unsigned char) 68, +/* 209 ( 'Ñ' ) */ (unsigned char) 43, +/* 210 ( 'Ò' ) */ (unsigned char) 168, +/* 211 ( 'Ó' ) */ (unsigned char) 228, +/* 212 ( 'Ô' ) */ (unsigned char) 236, +/* 213 ( 'Õ' ) */ (unsigned char) 79, +/* 214 ( 'Ö' ) */ (unsigned char) 92, +/* 215 ( '×' ) */ (unsigned char) 120, +/* 216 ( 'Ø' ) */ (unsigned char) 171, +/* 217 ( 'Ù' ) */ (unsigned char) 85, +/* 218 ( 'Ú' ) */ (unsigned char) 229, +/* 219 ( 'Û' ) */ (unsigned char) 85, +/* 220 ( 'Ü' ) */ (unsigned char) 94, +/* 221 ( 'Ý' ) */ (unsigned char) 250, +/* 222 ( 'Þ' ) */ (unsigned char) 178, +/* 223 ( 'ß' ) */ (unsigned char) 190, +/* 224 ( 'à' ) */ (unsigned char) 127, +/* 225 ( 'á' ) */ (unsigned char) 231, +/* 226 ( 'â' ) */ (unsigned char) 97, +/* 227 ( 'ã' ) */ (unsigned char) 97, +/* 228 ( 'ä' ) */ (unsigned char) 123, +/* 229 ( 'å' ) */ (unsigned char) 175, +/* 230 ( 'æ' ) */ (unsigned char) 189, +/* 231 ( 'ç' ) */ (unsigned char) 200, +/* 232 ( 'è' ) */ (unsigned char) 164, +/* 233 ( 'é' ) */ (unsigned char) 165, +/* 234 ( 'ê' ) */ (unsigned char) 199, +/* 235 ( 'ë' ) */ (unsigned char) 101, +/* 236 ( 'ì' ) */ (unsigned char) 167, +/* 237 ( 'í' ) */ (unsigned char) 232, +/* 238 ( 'î' ) */ (unsigned char) 105, +/* 239 ( 'ï' ) */ (unsigned char) 105, +/* 240 ( 'ð' ) */ (unsigned char) 158, +/* 241 ( 'ñ' ) */ (unsigned char) 125, +/* 242 ( 'ò' ) */ (unsigned char) 168, +/* 243 ( 'ó' ) */ (unsigned char) 228, +/* 244 ( 'ô' ) */ (unsigned char) 237, +/* 245 ( 'õ' ) */ (unsigned char) 237, +/* 246 ( 'ö' ) */ (unsigned char) 124, +/* 247 ( '÷' ) */ (unsigned char) 47, +/* 248 ( 'ø' ) */ (unsigned char) 172, +/* 249 ( 'ù' ) */ (unsigned char) 166, +/* 250 ( 'ú' ) */ (unsigned char) 234, +/* 251 ( 'û' ) */ (unsigned char) 239, +/* 252 ( 'ü' ) */ (unsigned char) 126, +/* 253 ( 'ý' ) */ (unsigned char) 235, +/* 254 ( 'þ' ) */ (unsigned char) 178, +/* 255 ( 'ÿ' ) */ (unsigned char) 183}; + diff --git a/lcdtranstbl-hd44780.h b/lcdtranstbl-hd44780.h new file mode 100644 index 0000000..783836a --- /dev/null +++ b/lcdtranstbl-hd44780.h @@ -0,0 +1,265 @@ +/* +lcdtranstbl-hd44780.h +this table is used to map characters for output to +a hd44780 LCD to display some special characters correctly. +newline,tab and friends are mapped to ' ' +*/ + +const unsigned char LcdTransTbl[256]={ +/* 0 ( '^@') */ (unsigned char) 0, +/* 1 ( '^A') */ (unsigned char) 1, +/* 2 ( '^B') */ (unsigned char) 2, +/* 3 ( '^C') */ (unsigned char) 3, +/* 4 ( '^D') */ (unsigned char) 4, +/* 5 ( '^E') */ (unsigned char) 5, +/* 6 ( '^F') */ (unsigned char) 6, +/* 7 ( '^G') */ (unsigned char) 7, +/* 8 ( '^H') */ (unsigned char) 8, +/* 9 ( '' ) */ (unsigned char) 32, +/* 10 ( '' ) */ (unsigned char) 32, +/* 11 ( '^K') */ (unsigned char) 32, +/* 12 ( '^L') */ (unsigned char) 32, +/* 13 ( '^M') */ (unsigned char) 32, +/* 14 ( '^N') */ (unsigned char) 14, +/* 15 ( '^O') */ (unsigned char) 15, +/* 16 ( '^P') */ (unsigned char) 16, +/* 17 ( '^Q') */ (unsigned char) 17, +/* 18 ( '^R') */ (unsigned char) 18, +/* 19 ( '^S') */ (unsigned char) 19, +/* 20 ( '^T') */ (unsigned char) 20, +/* 21 ( '^U') */ (unsigned char) 21, +/* 22 ( '^V') */ (unsigned char) 22, +/* 23 ( '^W') */ (unsigned char) 23, +/* 24 ( '^X') */ (unsigned char) 24, +/* 25 ( '^Y') */ (unsigned char) 25, +/* 26 ( '^Z') */ (unsigned char) 26, +/* 27 ( '^[') */ (unsigned char) 27, +/* 28 ( '^\') */ (unsigned char) 28, +/* 29 ( '^]') */ (unsigned char) 29, +/* 30 ( '^^') */ (unsigned char) 30, +/* 31 ( '^_') */ (unsigned char) 31, +/* 32 ( ' ' ) */ (unsigned char) 32, +/* 33 ( '!' ) */ (unsigned char) 33, +/* 34 ( '"' ) */ (unsigned char) 39, +/* 35 ( '#' ) */ (unsigned char) 35, +/* 36 ( '$' ) */ (unsigned char) 36, +/* 37 ( '%' ) */ (unsigned char) 37, +/* 38 ( '&' ) */ (unsigned char) 38, +/* 39 ( ''' ) */ (unsigned char) 39, +/* 40 ( '(' ) */ (unsigned char) 40, +/* 41 ( ')' ) */ (unsigned char) 41, +/* 42 ( '*' ) */ (unsigned char) 42, +/* 43 ( '+' ) */ (unsigned char) 43, +/* 44 ( ',' ) */ (unsigned char) 44, +/* 45 ( '-' ) */ (unsigned char) 45, +/* 46 ( '.' ) */ (unsigned char) 46, +/* 47 ( '/' ) */ (unsigned char) 47, +/* 48 ( '0' ) */ (unsigned char) 48, +/* 49 ( '1' ) */ (unsigned char) 49, +/* 50 ( '2' ) */ (unsigned char) 50, +/* 51 ( '3' ) */ (unsigned char) 51, +/* 52 ( '4' ) */ (unsigned char) 52, +/* 53 ( '5' ) */ (unsigned char) 53, +/* 54 ( '6' ) */ (unsigned char) 54, +/* 55 ( '7' ) */ (unsigned char) 55, +/* 56 ( '8' ) */ (unsigned char) 56, +/* 57 ( '9' ) */ (unsigned char) 57, +/* 58 ( ':' ) */ (unsigned char) 58, +/* 59 ( ';' ) */ (unsigned char) 59, +/* 60 ( '<' ) */ (unsigned char) 60, +/* 61 ( '=' ) */ (unsigned char) 61, +/* 62 ( '>' ) */ (unsigned char) 62, +/* 63 ( '?' ) */ (unsigned char) 63, +/* 64 ( '@' ) */ (unsigned char) 64, +/* 65 ( 'A' ) */ (unsigned char) 65, +/* 66 ( 'B' ) */ (unsigned char) 66, +/* 67 ( 'C' ) */ (unsigned char) 67, +/* 68 ( 'D' ) */ (unsigned char) 68, +/* 69 ( 'E' ) */ (unsigned char) 69, +/* 70 ( 'F' ) */ (unsigned char) 70, +/* 71 ( 'G' ) */ (unsigned char) 71, +/* 72 ( 'H' ) */ (unsigned char) 72, +/* 73 ( 'I' ) */ (unsigned char) 73, +/* 74 ( 'J' ) */ (unsigned char) 74, +/* 75 ( 'K' ) */ (unsigned char) 75, +/* 76 ( 'L' ) */ (unsigned char) 76, +/* 77 ( 'M' ) */ (unsigned char) 77, +/* 78 ( 'N' ) */ (unsigned char) 78, +/* 79 ( 'O' ) */ (unsigned char) 79, +/* 80 ( 'P' ) */ (unsigned char) 80, +/* 81 ( 'Q' ) */ (unsigned char) 81, +/* 82 ( 'R' ) */ (unsigned char) 82, +/* 83 ( 'S' ) */ (unsigned char) 83, +/* 84 ( 'T' ) */ (unsigned char) 84, +/* 85 ( 'U' ) */ (unsigned char) 85, +/* 86 ( 'V' ) */ (unsigned char) 86, +/* 87 ( 'W' ) */ (unsigned char) 87, +/* 88 ( 'X' ) */ (unsigned char) 88, +/* 89 ( 'Y' ) */ (unsigned char) 89, +/* 90 ( 'Z' ) */ (unsigned char) 90, +/* 91 ( '[' ) */ (unsigned char) 91, +/* 92 ( '\' ) */ (unsigned char) 92, +/* 93 ( ']' ) */ (unsigned char) 93, +/* 94 ( '^' ) */ (unsigned char) 94, +/* 95 ( '_' ) */ (unsigned char) 95, +/* 96 ( '`' ) */ (unsigned char) 96, +/* 97 ( 'a' ) */ (unsigned char) 97, +/* 98 ( 'b' ) */ (unsigned char) 98, +/* 99 ( 'c' ) */ (unsigned char) 99, +/* 100 ( 'd' ) */ (unsigned char) 100, +/* 101 ( 'e' ) */ (unsigned char) 101, +/* 102 ( 'f' ) */ (unsigned char) 102, +/* 103 ( 'g' ) */ (unsigned char) 103, +/* 104 ( 'h' ) */ (unsigned char) 104, +/* 105 ( 'i' ) */ (unsigned char) 105, +/* 106 ( 'j' ) */ (unsigned char) 106, +/* 107 ( 'k' ) */ (unsigned char) 107, +/* 108 ( 'l' ) */ (unsigned char) 108, +/* 109 ( 'm' ) */ (unsigned char) 109, +/* 110 ( 'n' ) */ (unsigned char) 110, +/* 111 ( 'o' ) */ (unsigned char) 111, +/* 112 ( 'p' ) */ (unsigned char) 112, +/* 113 ( 'q' ) */ (unsigned char) 113, +/* 114 ( 'r' ) */ (unsigned char) 114, +/* 115 ( 's' ) */ (unsigned char) 115, +/* 116 ( 't' ) */ (unsigned char) 116, +/* 117 ( 'u' ) */ (unsigned char) 117, +/* 118 ( 'v' ) */ (unsigned char) 118, +/* 119 ( 'w' ) */ (unsigned char) 119, +/* 120 ( 'x' ) */ (unsigned char) 120, +/* 121 ( 'y' ) */ (unsigned char) 121, +/* 122 ( 'z' ) */ (unsigned char) 122, +/* 123 ( '{' ) */ (unsigned char) 123, +/* 124 ( '|' ) */ (unsigned char) 124, +/* 125 ( '}' ) */ (unsigned char) 125, +/* 126 ( '~' ) */ (unsigned char) 126, +/* 127 ( '^?') */ (unsigned char) 127, +/* 128 ( '~@') */ (unsigned char) 128, +/* 129 ( '~A') */ (unsigned char) 129, +/* 130 ( '~B') */ (unsigned char) 130, +/* 131 ( '~C') */ (unsigned char) 131, +/* 132 ( '~D') */ (unsigned char) 132, +/* 133 ( '~E') */ (unsigned char) 133, +/* 134 ( '~F') */ (unsigned char) 134, +/* 135 ( '~G') */ (unsigned char) 135, +/* 136 ( '~H') */ (unsigned char) 136, +/* 137 ( '~I') */ (unsigned char) 137, +/* 138 ( '~J') */ (unsigned char) 138, +/* 139 ( '~K') */ (unsigned char) 139, +/* 140 ( '~L') */ (unsigned char) 140, +/* 141 ( '~M') */ (unsigned char) 141, +/* 142 ( '~N') */ (unsigned char) 142, +/* 143 ( '~O') */ (unsigned char) 143, +/* 144 ( '~P') */ (unsigned char) 144, +/* 145 ( '~Q') */ (unsigned char) 145, +/* 146 ( '~R') */ (unsigned char) 146, +/* 147 ( '~S') */ (unsigned char) 147, +/* 148 ( '~T') */ (unsigned char) 148, +/* 149 ( '~U') */ (unsigned char) 149, +/* 150 ( '~V') */ (unsigned char) 150, +/* 151 ( '~W') */ (unsigned char) 151, +/* 152 ( '~X') */ (unsigned char) 152, +/* 153 ( '~Y') */ (unsigned char) 153, +/* 154 ( '~Z') */ (unsigned char) 154, +/* 155 ( '~[') */ (unsigned char) 155, +/* 156 ( '~\') */ (unsigned char) 156, +/* 157 ( '~]') */ (unsigned char) 157, +/* 158 ( '~^') */ (unsigned char) 158, +/* 159 ( '~_') */ (unsigned char) 159, +/* 160 ( '| ') */ (unsigned char) 160, +/* 161 ( '¡' ) */ (unsigned char) 161, +/* 162 ( '¢' ) */ (unsigned char) 162, +/* 163 ( '£' ) */ (unsigned char) 163, +/* 164 ( '¤' ) */ (unsigned char) 164, +/* 165 ( '¥' ) */ (unsigned char) 92, +/* 166 ( '¦' ) */ (unsigned char) 166, +/* 167 ( '§' ) */ (unsigned char) 167, +/* 168 ( '¨' ) */ (unsigned char) 168, +/* 169 ( '©' ) */ (unsigned char) 67, +/* 170 ( 'ª' ) */ (unsigned char) 170, +/* 171 ( '«' ) */ (unsigned char) 171, +/* 172 ( '¬' ) */ (unsigned char) 172, +/* 173 ( '' ) */ (unsigned char) 173, +/* 174 ( '®' ) */ (unsigned char) 174, +/* 175 ( '¯' ) */ (unsigned char) 175, +/* 176 ( '°' ) */ (unsigned char) 223, +/* 177 ( '±' ) */ (unsigned char) 177, +/* 178 ( '²' ) */ (unsigned char) 50, +/* 179 ( '³' ) */ (unsigned char) 51, +/* 180 ( '´' ) */ (unsigned char) 180, +/* 181 ( 'µ' ) */ (unsigned char) 228, +/* 182 ( '¶' ) */ (unsigned char) 182, +/* 183 ( '·' ) */ (unsigned char) 183, +/* 184 ( '¸' ) */ (unsigned char) 184, +/* 185 ( '¹' ) */ (unsigned char) 185, +/* 186 ( 'º' ) */ (unsigned char) 223, +/* 187 ( '»' ) */ (unsigned char) 187, +/* 188 ( '¼' ) */ (unsigned char) 188, +/* 189 ( '½' ) */ (unsigned char) 189, +/* 190 ( '¾' ) */ (unsigned char) 190, +/* 191 ( '¿' ) */ (unsigned char) 191, +/* 192 ( 'À' ) */ (unsigned char) 65, +/* 193 ( 'Á' ) */ (unsigned char) 65, +/* 194 ( 'Â' ) */ (unsigned char) 65, +/* 195 ( 'Ã' ) */ (unsigned char) 65, +/* 196 ( 'Ä' ) */ (unsigned char) 225, +/* 197 ( 'Å' ) */ (unsigned char) 65, +/* 198 ( 'Æ' ) */ (unsigned char) 225, +/* 199 ( 'Ç' ) */ (unsigned char) 67, +/* 200 ( 'È' ) */ (unsigned char) 69, +/* 201 ( 'É' ) */ (unsigned char) 69, +/* 202 ( 'Ê' ) */ (unsigned char) 69, +/* 203 ( 'Ë' ) */ (unsigned char) 69, +/* 204 ( 'Ì' ) */ (unsigned char) 73, +/* 205 ( 'Í' ) */ (unsigned char) 73, +/* 206 ( 'Î' ) */ (unsigned char) 73, +/* 207 ( 'Ï' ) */ (unsigned char) 73, +/* 208 ( 'Ð' ) */ (unsigned char) 68, +/* 209 ( 'Ñ' ) */ (unsigned char) 78, +/* 210 ( 'Ò' ) */ (unsigned char) 79, +/* 211 ( 'Ó' ) */ (unsigned char) 79, +/* 212 ( 'Ô' ) */ (unsigned char) 79, +/* 213 ( 'Õ' ) */ (unsigned char) 79, +/* 214 ( 'Ö' ) */ (unsigned char) 239, +/* 215 ( '×' ) */ (unsigned char) 88, +/* 216 ( 'Ø' ) */ (unsigned char) 48, +/* 217 ( 'Ù' ) */ (unsigned char) 85, +/* 218 ( 'Ú' ) */ (unsigned char) 85, +/* 219 ( 'Û' ) */ (unsigned char) 85, +/* 220 ( 'Ü' ) */ (unsigned char) 245, +/* 221 ( 'Ý' ) */ (unsigned char) 89, +/* 222 ( 'Þ' ) */ (unsigned char) 222, +/* 223 ( 'ß' ) */ (unsigned char) 226, +/* 224 ( 'à' ) */ (unsigned char) 97, +/* 225 ( 'á' ) */ (unsigned char) 97, +/* 226 ( 'â' ) */ (unsigned char) 97, +/* 227 ( 'ã' ) */ (unsigned char) 97, +/* 228 ( 'ä' ) */ (unsigned char) 225, +/* 229 ( 'å' ) */ (unsigned char) 97, +/* 230 ( 'æ' ) */ (unsigned char) 230, +/* 231 ( 'ç' ) */ (unsigned char) 99, +/* 232 ( 'è' ) */ (unsigned char) 101, +/* 233 ( 'é' ) */ (unsigned char) 101, +/* 234 ( 'ê' ) */ (unsigned char) 101, +/* 235 ( 'ë' ) */ (unsigned char) 101, +/* 236 ( 'ì' ) */ (unsigned char) 105, +/* 237 ( 'í' ) */ (unsigned char) 105, +/* 238 ( 'î' ) */ (unsigned char) 105, +/* 239 ( 'ï' ) */ (unsigned char) 105, +/* 240 ( 'ð' ) */ (unsigned char) 100, +/* 241 ( 'ñ' ) */ (unsigned char) 110, +/* 242 ( 'ò' ) */ (unsigned char) 111, +/* 243 ( 'ó' ) */ (unsigned char) 111, +/* 244 ( 'ô' ) */ (unsigned char) 111, +/* 245 ( 'õ' ) */ (unsigned char) 111, +/* 246 ( 'ö' ) */ (unsigned char) 239, +/* 247 ( '÷' ) */ (unsigned char) 253, +/* 248 ( 'ø' ) */ (unsigned char) 248, +/* 249 ( 'ù' ) */ (unsigned char) 117, +/* 250 ( 'ú' ) */ (unsigned char) 117, +/* 251 ( 'û' ) */ (unsigned char) 117, +/* 252 ( 'ü' ) */ (unsigned char) 245, +/* 253 ( 'ý' ) */ (unsigned char) 121, +/* 254 ( 'þ' ) */ (unsigned char) 254, +/* 255 ( 'ÿ' ) */ (unsigned char) 121}; + diff --git a/lcdtranstbl-nomap.h b/lcdtranstbl-nomap.h new file mode 100644 index 0000000..a232640 --- /dev/null +++ b/lcdtranstbl-nomap.h @@ -0,0 +1,264 @@ +/* +lcdtranstbl-nomap.h +nothing except '"' is mapped here, seems that somone does not understand '\"' ... +newline,tab and friends are mapped to ' ' +*/ + +const unsigned char LcdTransTbl[256]={ +/* 0 ( '^@') */ (unsigned char) 0, +/* 1 ( '^A') */ (unsigned char) 1, +/* 2 ( '^B') */ (unsigned char) 2, +/* 3 ( '^C') */ (unsigned char) 3, +/* 4 ( '^D') */ (unsigned char) 4, +/* 5 ( '^E') */ (unsigned char) 5, +/* 6 ( '^F') */ (unsigned char) 6, +/* 7 ( '^G') */ (unsigned char) 7, +/* 8 ( '^H') */ (unsigned char) 8, +/* 9 ( '' ) */ (unsigned char) 32, +/* 10 ( '' ) */ (unsigned char) 32, +/* 11 ( '^K') */ (unsigned char) 32, +/* 12 ( '^L') */ (unsigned char) 32, +/* 13 ( '^M') */ (unsigned char) 32, +/* 14 ( '^N') */ (unsigned char) 14, +/* 15 ( '^O') */ (unsigned char) 15, +/* 16 ( '^P') */ (unsigned char) 16, +/* 17 ( '^Q') */ (unsigned char) 17, +/* 18 ( '^R') */ (unsigned char) 18, +/* 19 ( '^S') */ (unsigned char) 19, +/* 20 ( '^T') */ (unsigned char) 20, +/* 21 ( '^U') */ (unsigned char) 21, +/* 22 ( '^V') */ (unsigned char) 22, +/* 23 ( '^W') */ (unsigned char) 23, +/* 24 ( '^X') */ (unsigned char) 24, +/* 25 ( '^Y') */ (unsigned char) 25, +/* 26 ( '^Z') */ (unsigned char) 26, +/* 27 ( '^[') */ (unsigned char) 27, +/* 28 ( '^\') */ (unsigned char) 28, +/* 29 ( '^]') */ (unsigned char) 29, +/* 30 ( '^^') */ (unsigned char) 30, +/* 31 ( '^_') */ (unsigned char) 31, +/* 32 ( ' ' ) */ (unsigned char) 32, +/* 33 ( '!' ) */ (unsigned char) 33, +/* 34 ( '"' ) */ (unsigned char) 39, +/* 35 ( '#' ) */ (unsigned char) 35, +/* 36 ( '$' ) */ (unsigned char) 36, +/* 37 ( '%' ) */ (unsigned char) 37, +/* 38 ( '&' ) */ (unsigned char) 38, +/* 39 ( ''' ) */ (unsigned char) 39, +/* 40 ( '(' ) */ (unsigned char) 40, +/* 41 ( ')' ) */ (unsigned char) 41, +/* 42 ( '*' ) */ (unsigned char) 42, +/* 43 ( '+' ) */ (unsigned char) 43, +/* 44 ( ',' ) */ (unsigned char) 44, +/* 45 ( '-' ) */ (unsigned char) 45, +/* 46 ( '.' ) */ (unsigned char) 46, +/* 47 ( '/' ) */ (unsigned char) 47, +/* 48 ( '0' ) */ (unsigned char) 48, +/* 49 ( '1' ) */ (unsigned char) 49, +/* 50 ( '2' ) */ (unsigned char) 50, +/* 51 ( '3' ) */ (unsigned char) 51, +/* 52 ( '4' ) */ (unsigned char) 52, +/* 53 ( '5' ) */ (unsigned char) 53, +/* 54 ( '6' ) */ (unsigned char) 54, +/* 55 ( '7' ) */ (unsigned char) 55, +/* 56 ( '8' ) */ (unsigned char) 56, +/* 57 ( '9' ) */ (unsigned char) 57, +/* 58 ( ':' ) */ (unsigned char) 58, +/* 59 ( ';' ) */ (unsigned char) 59, +/* 60 ( '<' ) */ (unsigned char) 60, +/* 61 ( '=' ) */ (unsigned char) 61, +/* 62 ( '>' ) */ (unsigned char) 62, +/* 63 ( '?' ) */ (unsigned char) 63, +/* 64 ( '@' ) */ (unsigned char) 64, +/* 65 ( 'A' ) */ (unsigned char) 65, +/* 66 ( 'B' ) */ (unsigned char) 66, +/* 67 ( 'C' ) */ (unsigned char) 67, +/* 68 ( 'D' ) */ (unsigned char) 68, +/* 69 ( 'E' ) */ (unsigned char) 69, +/* 70 ( 'F' ) */ (unsigned char) 70, +/* 71 ( 'G' ) */ (unsigned char) 71, +/* 72 ( 'H' ) */ (unsigned char) 72, +/* 73 ( 'I' ) */ (unsigned char) 73, +/* 74 ( 'J' ) */ (unsigned char) 74, +/* 75 ( 'K' ) */ (unsigned char) 75, +/* 76 ( 'L' ) */ (unsigned char) 76, +/* 77 ( 'M' ) */ (unsigned char) 77, +/* 78 ( 'N' ) */ (unsigned char) 78, +/* 79 ( 'O' ) */ (unsigned char) 79, +/* 80 ( 'P' ) */ (unsigned char) 80, +/* 81 ( 'Q' ) */ (unsigned char) 81, +/* 82 ( 'R' ) */ (unsigned char) 82, +/* 83 ( 'S' ) */ (unsigned char) 83, +/* 84 ( 'T' ) */ (unsigned char) 84, +/* 85 ( 'U' ) */ (unsigned char) 85, +/* 86 ( 'V' ) */ (unsigned char) 86, +/* 87 ( 'W' ) */ (unsigned char) 87, +/* 88 ( 'X' ) */ (unsigned char) 88, +/* 89 ( 'Y' ) */ (unsigned char) 89, +/* 90 ( 'Z' ) */ (unsigned char) 90, +/* 91 ( '[' ) */ (unsigned char) 91, +/* 92 ( '\' ) */ (unsigned char) 92, +/* 93 ( ']' ) */ (unsigned char) 93, +/* 94 ( '^' ) */ (unsigned char) 94, +/* 95 ( '_' ) */ (unsigned char) 95, +/* 96 ( '`' ) */ (unsigned char) 96, +/* 97 ( 'a' ) */ (unsigned char) 97, +/* 98 ( 'b' ) */ (unsigned char) 98, +/* 99 ( 'c' ) */ (unsigned char) 99, +/* 100 ( 'd' ) */ (unsigned char) 100, +/* 101 ( 'e' ) */ (unsigned char) 101, +/* 102 ( 'f' ) */ (unsigned char) 102, +/* 103 ( 'g' ) */ (unsigned char) 103, +/* 104 ( 'h' ) */ (unsigned char) 104, +/* 105 ( 'i' ) */ (unsigned char) 105, +/* 106 ( 'j' ) */ (unsigned char) 106, +/* 107 ( 'k' ) */ (unsigned char) 107, +/* 108 ( 'l' ) */ (unsigned char) 108, +/* 109 ( 'm' ) */ (unsigned char) 109, +/* 110 ( 'n' ) */ (unsigned char) 110, +/* 111 ( 'o' ) */ (unsigned char) 111, +/* 112 ( 'p' ) */ (unsigned char) 112, +/* 113 ( 'q' ) */ (unsigned char) 113, +/* 114 ( 'r' ) */ (unsigned char) 114, +/* 115 ( 's' ) */ (unsigned char) 115, +/* 116 ( 't' ) */ (unsigned char) 116, +/* 117 ( 'u' ) */ (unsigned char) 117, +/* 118 ( 'v' ) */ (unsigned char) 118, +/* 119 ( 'w' ) */ (unsigned char) 119, +/* 120 ( 'x' ) */ (unsigned char) 120, +/* 121 ( 'y' ) */ (unsigned char) 121, +/* 122 ( 'z' ) */ (unsigned char) 122, +/* 123 ( '{' ) */ (unsigned char) 123, +/* 124 ( '|' ) */ (unsigned char) 124, +/* 125 ( '}' ) */ (unsigned char) 125, +/* 126 ( '~' ) */ (unsigned char) 126, +/* 127 ( '^?') */ (unsigned char) 127, +/* 128 ( '~@') */ (unsigned char) 128, +/* 129 ( '~A') */ (unsigned char) 129, +/* 130 ( '~B') */ (unsigned char) 130, +/* 131 ( '~C') */ (unsigned char) 131, +/* 132 ( '~D') */ (unsigned char) 132, +/* 133 ( '~E') */ (unsigned char) 133, +/* 134 ( '~F') */ (unsigned char) 134, +/* 135 ( '~G') */ (unsigned char) 135, +/* 136 ( '~H') */ (unsigned char) 136, +/* 137 ( '~I') */ (unsigned char) 137, +/* 138 ( '~J') */ (unsigned char) 138, +/* 139 ( '~K') */ (unsigned char) 139, +/* 140 ( '~L') */ (unsigned char) 140, +/* 141 ( '~M') */ (unsigned char) 141, +/* 142 ( '~N') */ (unsigned char) 142, +/* 143 ( '~O') */ (unsigned char) 143, +/* 144 ( '~P') */ (unsigned char) 144, +/* 145 ( '~Q') */ (unsigned char) 145, +/* 146 ( '~R') */ (unsigned char) 146, +/* 147 ( '~S') */ (unsigned char) 147, +/* 148 ( '~T') */ (unsigned char) 148, +/* 149 ( '~U') */ (unsigned char) 149, +/* 150 ( '~V') */ (unsigned char) 150, +/* 151 ( '~W') */ (unsigned char) 151, +/* 152 ( '~X') */ (unsigned char) 152, +/* 153 ( '~Y') */ (unsigned char) 153, +/* 154 ( '~Z') */ (unsigned char) 154, +/* 155 ( '~[') */ (unsigned char) 155, +/* 156 ( '~\') */ (unsigned char) 156, +/* 157 ( '~]') */ (unsigned char) 157, +/* 158 ( '~^') */ (unsigned char) 158, +/* 159 ( '~_') */ (unsigned char) 159, +/* 160 ( '| ') */ (unsigned char) 160, +/* 161 ( '¡' ) */ (unsigned char) 161, +/* 162 ( '¢' ) */ (unsigned char) 162, +/* 163 ( '£' ) */ (unsigned char) 163, +/* 164 ( '¤' ) */ (unsigned char) 164, +/* 165 ( '¥' ) */ (unsigned char) 165, +/* 166 ( '¦' ) */ (unsigned char) 166, +/* 167 ( '§' ) */ (unsigned char) 167, +/* 168 ( '¨' ) */ (unsigned char) 168, +/* 169 ( '©' ) */ (unsigned char) 169, +/* 170 ( 'ª' ) */ (unsigned char) 170, +/* 171 ( '«' ) */ (unsigned char) 171, +/* 172 ( '¬' ) */ (unsigned char) 172, +/* 173 ( '' ) */ (unsigned char) 173, +/* 174 ( '®' ) */ (unsigned char) 174, +/* 175 ( '¯' ) */ (unsigned char) 175, +/* 176 ( '°' ) */ (unsigned char) 176, +/* 177 ( '±' ) */ (unsigned char) 177, +/* 178 ( '²' ) */ (unsigned char) 178, +/* 179 ( '³' ) */ (unsigned char) 179, +/* 180 ( '´' ) */ (unsigned char) 180, +/* 181 ( 'µ' ) */ (unsigned char) 181, +/* 182 ( '¶' ) */ (unsigned char) 182, +/* 183 ( '·' ) */ (unsigned char) 183, +/* 184 ( '¸' ) */ (unsigned char) 184, +/* 185 ( '¹' ) */ (unsigned char) 185, +/* 186 ( 'º' ) */ (unsigned char) 186, +/* 187 ( '»' ) */ (unsigned char) 187, +/* 188 ( '¼' ) */ (unsigned char) 188, +/* 189 ( '½' ) */ (unsigned char) 189, +/* 190 ( '¾' ) */ (unsigned char) 190, +/* 191 ( '¿' ) */ (unsigned char) 191, +/* 192 ( 'À' ) */ (unsigned char) 192, +/* 193 ( 'Á' ) */ (unsigned char) 193, +/* 194 ( 'Â' ) */ (unsigned char) 194, +/* 195 ( 'Ã' ) */ (unsigned char) 195, +/* 196 ( 'Ä' ) */ (unsigned char) 196, +/* 197 ( 'Å' ) */ (unsigned char) 197, +/* 198 ( 'Æ' ) */ (unsigned char) 198, +/* 199 ( 'Ç' ) */ (unsigned char) 199, +/* 200 ( 'È' ) */ (unsigned char) 200, +/* 201 ( 'É' ) */ (unsigned char) 201, +/* 202 ( 'Ê' ) */ (unsigned char) 202, +/* 203 ( 'Ë' ) */ (unsigned char) 203, +/* 204 ( 'Ì' ) */ (unsigned char) 204, +/* 205 ( 'Í' ) */ (unsigned char) 205, +/* 206 ( 'Î' ) */ (unsigned char) 206, +/* 207 ( 'Ï' ) */ (unsigned char) 207, +/* 208 ( 'Ð' ) */ (unsigned char) 208, +/* 209 ( 'Ñ' ) */ (unsigned char) 209, +/* 210 ( 'Ò' ) */ (unsigned char) 210, +/* 211 ( 'Ó' ) */ (unsigned char) 211, +/* 212 ( 'Ô' ) */ (unsigned char) 212, +/* 213 ( 'Õ' ) */ (unsigned char) 213, +/* 214 ( 'Ö' ) */ (unsigned char) 214, +/* 215 ( '×' ) */ (unsigned char) 215, +/* 216 ( 'Ø' ) */ (unsigned char) 216, +/* 217 ( 'Ù' ) */ (unsigned char) 217, +/* 218 ( 'Ú' ) */ (unsigned char) 218, +/* 219 ( 'Û' ) */ (unsigned char) 219, +/* 220 ( 'Ü' ) */ (unsigned char) 220, +/* 221 ( 'Ý' ) */ (unsigned char) 221, +/* 222 ( 'Þ' ) */ (unsigned char) 222, +/* 223 ( 'ß' ) */ (unsigned char) 223, +/* 224 ( 'à' ) */ (unsigned char) 224, +/* 225 ( 'á' ) */ (unsigned char) 225, +/* 226 ( 'â' ) */ (unsigned char) 226, +/* 227 ( 'ã' ) */ (unsigned char) 227, +/* 228 ( 'ä' ) */ (unsigned char) 228, +/* 229 ( 'å' ) */ (unsigned char) 229, +/* 230 ( 'æ' ) */ (unsigned char) 230, +/* 231 ( 'ç' ) */ (unsigned char) 231, +/* 232 ( 'è' ) */ (unsigned char) 232, +/* 233 ( 'é' ) */ (unsigned char) 233, +/* 234 ( 'ê' ) */ (unsigned char) 234, +/* 235 ( 'ë' ) */ (unsigned char) 235, +/* 236 ( 'ì' ) */ (unsigned char) 236, +/* 237 ( 'í' ) */ (unsigned char) 237, +/* 238 ( 'î' ) */ (unsigned char) 238, +/* 239 ( 'ï' ) */ (unsigned char) 239, +/* 240 ( 'ð' ) */ (unsigned char) 240, +/* 241 ( 'ñ' ) */ (unsigned char) 241, +/* 242 ( 'ò' ) */ (unsigned char) 242, +/* 243 ( 'ó' ) */ (unsigned char) 243, +/* 244 ( 'ô' ) */ (unsigned char) 244, +/* 245 ( 'õ' ) */ (unsigned char) 245, +/* 246 ( 'ö' ) */ (unsigned char) 246, +/* 247 ( '÷' ) */ (unsigned char) 247, +/* 248 ( 'ø' ) */ (unsigned char) 248, +/* 249 ( 'ù' ) */ (unsigned char) 249, +/* 250 ( 'ú' ) */ (unsigned char) 250, +/* 251 ( 'û' ) */ (unsigned char) 251, +/* 252 ( 'ü' ) */ (unsigned char) 252, +/* 253 ( 'ý' ) */ (unsigned char) 253, +/* 254 ( 'þ' ) */ (unsigned char) 254, +/* 255 ( 'ÿ' ) */ (unsigned char) 255}; + diff --git a/sockets.c b/sockets.c new file mode 100644 index 0000000..5a9bb15 --- /dev/null +++ b/sockets.c @@ -0,0 +1,230 @@ +/******************************** +this file was taken from the +LCDproc source see +http://lcdproc.omnipotent.net/ +for more info. +*********************************/ + +#include <unistd.h> +#include <stddef.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <netdb.h> +#include <arpa/inet.h> +#include <fcntl.h> +#include "sockets.h" + +/************************************************** + LCDproc client sockets code... + + Feel free to use this in your own clients... :) +**************************************************/ + +// Length of longest transmission allowed at once... +#define MAXMSG 8192 + +typedef struct sockaddr_in sockaddr_in; + +static int +sock_init_sockaddr (sockaddr_in * name, const char *hostname, unsigned short int port) +{ + struct hostent *hostinfo; + + name->sin_family = AF_INET; + name->sin_port = htons (port); + hostinfo = gethostbyname (hostname); + if (hostinfo == NULL) { + fprintf (stderr, "sock_init_sockaddr: Unknown host %s.\n", hostname); + return -1; + } + name->sin_addr = *(struct in_addr *) hostinfo->h_addr; + + return 0; + +} + + // Client functions... +int +sock_connect (char *host, unsigned short int port) +{ + struct sockaddr_in servername; + int sock; + int err = 0; + + //debug ("sock_connect: Creating socket\n"); + sock = socket (PF_INET, SOCK_STREAM, 0); + if (sock < 0) { + perror ("sock_connect: Error creating socket"); + return sock; + } + //debug ("sock_connect: Created socket (%i)\n", sock); + + sock_init_sockaddr (&servername, host, port); + + err = connect (sock, (struct sockaddr *) &servername, sizeof (servername)); + if (err < 0) { + perror ("sock_connect: connect failed"); + shutdown (sock, 2); + return 0; // Normal exit if server doesn't exist... + } + + fcntl (sock, F_SETFL, O_NONBLOCK); + + return sock; +} + +int +sock_close (int fd) +{ + int err; + + err = shutdown (fd, 2); + if (!err) + close (fd); + + return err; +} + +// Send/receive lines of text +int +sock_send_string (int fd, char *string) +{ + int len; + int offset = 0; + + if (!string) + return -1; + + len = strlen (string) ; + while (offset != len) { + // write isn't guaranteed to send the entire string at once, + // so we have to sent it in a loop like this + int sent = write (fd, string + offset, len - offset); + if (sent == -1) { + if (errno != EAGAIN) { + perror ("sock_send_string: socket write error"); + printf ("Message was: %s\n", string); + //shutdown(fd, 2); + return sent; + } + continue; + } else if (sent == 0) { + // when this returns zero, it generally means + // we got disconnected + return sent + offset; + } + + offset += sent; + } + + return offset; +} + +// Recv gives only one line per call... +int +sock_recv_string (int fd, char *dest, size_t maxlen) +{ + char *ptr = dest; + unsigned int recv = 0; + + if (!dest) + return -1; + if (maxlen <= 0) + return 0; + + while (1) { + int err = read (fd, ptr, 1); + if (err == -1) { + if (errno == EAGAIN) { + if (recv) { + // We've begun to read a string, but no bytes are + // available. Loop. + continue; + } + return 0; + } else { + perror ("sock_recv_string: socket read error"); + return err; + } + } else if (err == 0) { + return recv; + } + + recv++; + + if (recv == maxlen || *ptr == 0 || *ptr == 10) { + *ptr = 0; + break; + } + ptr++; + } + + if (recv == 1 && dest[0] == 0) { + // Don't return a null string + return 0; + } + + if (recv < maxlen - 1) { + dest[recv] = 0; + } + + return recv; +} + +// Send/receive raw data +int +sock_send (int fd, void *src, size_t size) +{ + unsigned int offset = 0; + + if (!src) + return -1; + + while (offset != size) { + // write isn't guaranteed to send the entire string at once, + // so we have to sent it in a loop like this + int sent = write (fd, ((char *) src) + offset, size - offset); + if (sent == -1) { + if (errno != EAGAIN) { + perror ("sock_send: socket write error"); + //shutdown(fd, 2); + return sent; + } + continue; + } else if (sent == 0) { + // when this returns zero, it generally means + // we got disconnected + return sent + offset; + } + + offset += sent; + } + + return offset; +} + +int +sock_recv (int fd, void *dest, size_t maxlen) +{ + int err; + + if (!dest) + return -1; + if (maxlen <= 0) + return 0; + + err = read (fd, dest, maxlen); + if (err < 0) { + //fprintf (stderr,"sock_recv: socket read error\n"); + //shutdown(fd, 2); + return err; + } + //debug("sock_recv: Got message \"%s\"\n", (char *)dest); + + return err; +} diff --git a/sockets.h b/sockets.h new file mode 100644 index 0000000..86df31f --- /dev/null +++ b/sockets.h @@ -0,0 +1,92 @@ +/******************************** +this file was taken from the +LCDproc source see +http://lcdproc.omnipotent.net/ +for more info. +*********************************/ + +#ifndef SOCKETS_H +#define SOCKETS_H + +#include <stdlib.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef LCDPORT +#define LCDPORT 13666 +#endif + +/* + Socket functions available to server and clients... + (ignore the rest of the comments... I was babbling out random ideas) + + This should have stuff to read/write sockets, open/close them, etc... + */ + +// Client functions... +int sock_connect (char *host, unsigned short int port); +int sock_close (int fd); +// Send/receive lines of text +int sock_send_string (int fd, char *string); +// Recv gives only one line per call... +int sock_recv_string (int fd, char *dest, size_t maxlen); +// Send/receive raw data +int sock_send (int fd, void *src, size_t size); +int sock_recv (int fd, void *dest, size_t maxlen); + +// Er, ignore the rest of this file. I'll clean it up sometime... + +/***************************************************************** + LCDproc command line interface?: (while running) + + -command + Tells LCDproc to interpret stdin as raw commands to send through + the socket. Input must be formatted as above, in socket interface. + -function f + Runs LCDproc external function f, where f is one of the predefined + functions which can be assigned to keypad keys. (like NEXTMODE, etc) + -key x + Simulates keypad press of key 'x', where 'x' is (A-Z). + -print [time] + Prints stdin on LCD one line at a time, with no line-wrapping (raw), + with [time] frames between updates (lines). + -wrap [time] + Prints stdin as with "-print", but with line wrapping when possible. + -contrast xxx + Sets contrast to xxx (decimal) + -backlight [on/off] + Turns backlight [on/off/auto], or toggles it. + If [off], stays off. + If [on], stays on. + If [auto], LCDproc controls backlight based on load, etc... + -exit + -quit + Duh... :) + +******************************************************************/ + +/***************************************************************** + LCDproc stuff supported in config file (loose approximation): + + Grammar is tcl-style. I.e., "command arg1 arg2 ...". + Spaces are used as argument separators, *until* it thinks it has the final + argument. So, "function thing shell myprogram arg1 arg2 arg3" would be + split into "function", "thing", "shell", and "myprogram arg1 arg2 arg3". + + User-definable functions (use built-in's to create new ones?): + Function mp3NextSong Shell /usr/local/bin/mp3player -next + Function MySequence Sequence cpu mem xload + Function OtherSequence Sequence time cd xload + + Keypad keys can be bound to any _function_: + Key A mp3NextSong + Key B HaltSystem + Key C Menu + Key D Next/+ + Key E OtherSequence + +******************************************************************/ + +#endif |