# HG changeset patch # User root@rika # Date 1202319175 0 # Node ID df6a40031aa5e39e04edbf852f18c0213255dea0 # Parent d0e62fc47285738a2efd6d14f82c41e1e56ebafe added graphlcd-base diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/COPYING --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/COPYING Wed Feb 06 17:32:55 2008 +0000 @@ -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. + + + Copyright (C) + + 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. + + , 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. diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/HISTORY --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/HISTORY Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,151 @@ +GraphLCD base package Revision History +-------------------------------------- + +2007-02-25: Version 0.1.5 +- added missing include path definition (thanks to Wolfgang Astleitner) +- replaced unsigned long long with uint64_t +- added missing includes +- increased VER_MAJOR for glcdgraphics library as interface changed in an incompatible way (thanks to Tobias Grimm) +- changed type of fbp (framebuffer pointer) to void*. Compare fbp against MAP_FAILED to test for success of mmap. This should fix a x86_64 compile error. +- ks0108: clear data lines after display refresh to fix problems with display contrast that occur under some conditions. + + +2007-02-04: Version 0.1.4 +- added missing include of stdint.h in several files +- added -fPIC compiler option to library Makefiles +- graphlcd.conf: added missing "Driver=serdisp" in serdisp section (thanks to Jörn Hermann) +- graphlcd.conf: changed default value for sleep method to gettimeofday +- glcdgraphics library changes: + - Added cBitmap::DrawSlope function that draws a slope of the given type + - added class for loading and saving PBM (portable bitmap) files + - made loading of GLCD files platform independent (hopefully) + - added copy constructor to cBitmap class + - removed the friend class stuff from cImage, instead added some functions to set members + - new class cImageFile that acts as a base class for image format load/save classes like cGLCDFile or cPBMFile + - removed const qualifier from cImage::GetBitmap + - added added Invert method to cBitmap + - added methods to set font parameter (height, ascent, ...) to cFont class + - made loading of FNT files platform independent (hopefully) + - return false in cGLCDFile::Open and ::Save when opening of file failed + - added trim function to cut leading and trailing spaces from strings + - added WrapText method to cFont class + - fixed missing last line in cFont::WrapText + - fixed WrapText when Height is zero + - fixed font loading bug for graphlcd's FNT format + - fixed missing addition of spaceBetween in cFont::WrapText that caused too long lines with some fonts + - fixed loading of GLCD animations (thanks to Malte Schröder) +- glcddrivers library changes: + - only config.h, driver.h and drivers.h are needed for applications + - added driver for g15daemon (thanks to Mike) + - added driver for noritake gu126x64D-K610A4 display (thanks to Alexander Rieger) + - gu140x32: fix seqfault if fonts.conf missed (thanks to Andreas Brachold) + - t6963c: added support for Serial wiring using an industry version with a serial to parallel converter (thanks to Torsten Lang) + - avrctl: adapted to changed commands PC -> AVR + - avrctl: implemented SetBrightness method + - avrctl: changed type of some parameters to SetColData to uint16_t + - avrctl: allow sizes below 256x128. Buffer sent to controller is still 256x128. + - framebuffer: fixed compiler error on 64bit systems (thanks to Malte Schröder) + - serdisp: updated serdisplib driver (thanks to Wolfgang Astleitner) + - added simple network driver (not complete) that sends the current display content as and hey string to connected clients + - link against libpthread + - fixed some default values to be consistent with comments in graphlcd.conf +- tools changes: + - convpic: adapted to changes related to new base class cImageFile + - convpic: use classes from glcdgraphics lib for glcd file conversion + - convpic: added pbm support + - crtfont: use cFont class methods to save in FNT format + - genfont: use cFont class methods to load freetype2 supported fonts + - genfont: use cFont class methods to save in FNT format + - showpic: call SetBrightness method + - showpic: changed setting of brightness to use value from config structure + - new tool lcdtestpattern to display a test pattern on a LCD (thanks to Alexander Rieger) + + +2006-01-15: Version 0.1.3 +- Added a major.minor.micro version to the libraries starting with 1.0.0 +- Moved usage of DESTDIR from serveral Makefiles to Make.config (thanks to + Lucian Muresan). +- Moved Freetype2 dependency from Make.config to Makefile of libglcdgraphics + (thanks to Tobias Grimm). +- Creating an additional symlink for the library files to be found during + making the tools that need them (thanks to Tobias Grimm). +- Updated serdisplib driver (thanks to Wolfgang Astleitner). +- KS0108 driver: Added an alternative way of setting the display control lines + (same as in old versions). It is selectable through graphlcd configfile + parameter "Control". +- Using default values for width and height in case they are zero, too + (thanks to Tobias Grimm). +- Added cSerialPort class. +- Added driver for my AVR controlled display. + + +2005-09-17: Version 0.1.2 +- split off drivers from graphlcd plugin to GraphLCD driver library + (libglcddrivers) +- split off graphics and font handling from graphlcd plugin to GraphLCD + graphics library (libglcdgraphics) +- split off tools from graphlcd plugin to GraphLCD base package +- almost completely rewritten graphics and font handling +- added configuration file to hold the driver-specific options +- changed driver interface +- adopted the tools' code to use the new driver and graphics API +- glcddrivers: new driver noritake800 for Noritake 800(A) series + displays (thanks to Lucian Muresan) +- glcdgraphics: fixed a NULL-pointer exception in cBitmap::DrawCharacter + when skipPixels is equal to width of the character and SubBitmap + returns NULL, which was not tested for (thanks to Malte Schröder for + reporting this one) +- glcdgraphics: fixed a wrong return value in cBitmap::DrawCharacter in + case skipPixels > 0 which prevented scrolling from working right. +- now compiles with gcc 2.95 and gcc 3.x +- added missing #includes +- new tool showtext: allows showing a text on the LCD, see + README.showtext for details. +- glcddrivers: fixed a too early port release in sed1330 driver (thanks + to Matthias Huber) +- glcddrivers: sed1330: added missing horizontal scrolling + initialization. Now, there should be no displaced display any longer. + (thanks to Wolfgang Astleitner) +- glcddrivers: Now serdisplib is loaded dynamically using libdl. So, no + INCLUDE_SERDISPLIB define is needed any longer (thanks to Wolfgang + Astleitner) +- glcddrivers: fixed gu256x64-3900 driver: Now sizes other than 256x64 + should work. (thanks to Detlef Ruge and Ralf Müller) +- glcdgraphics: fixed a bug in cBitmap::DrawText that prevented scrolling + from working. +- glcdgraphics: fixed a bug in cBitmap::SubBitmap. +- glcdgraphics: changed the interface of DrawText and DrawCharacter of + cBitmap class. +- glcdgraphics: extended font attributes to better support converted true + type fonts. Also changed font file format to support this attributes. +- glcdgraphics: the lastChange attribute of cImage now is 64 bits wide. +- crtfont: extended it to support the new font attributes +- crtfont: changed file format of description files. Now the font + attributes are given by its names, p. e. lineheight:20. Look in + README.crtfont for details. +- new tool genfont: allows converting of true type fonts to GraphLCD + fonts using freetype2 library. You have to uncomment HAVE_FREETYPE2 in + Make.config to use it. +- added new fonts verdana and verdana bold in sizes 9 to 29 converted by + genfont. +- glcdgraphics: Added additional type casts to std::min calls to make it + compile on x86-64 (thanks to Stefan Bergler). +- glcddrivers: fixed a bug in serdisp.c. When using direct IO the port + string was truncated (thanks to Stefan Bergler). +- glcddrivers: Added method cConfig::GetConfigIndex for getting a + configuration by its name (thanks to Lucian Muresan). +- Added some $(DESTDIR) all over the Makefiles (thanks to Lucian Muresan). +- glcddrivers: sed1330: Added setting of CS line in 6800 mode (thanks to + Wolfgang Astleitner). +- glcdgraphics: Added FreeType2 support based on patch by Lucian Muresan. + - You have to set HAVE_FREETYPE2 in Make.config to enable this + - Added some helper functions to GLCD::cFont class +- glcddrivers: ks0108: Improved timings: Made setting of display control + lines like defined in the controller's data sheet. This fixes problems + with some display types. Thanks to Matthias Breitbach for providing a + LCD of that type. +- glcddrivers: gu256x64-3900: + - Corrected calculation of m_nTimingAdjustCmd. + - Added a test for RefreshDisplay config value to prevent a floating + point exception to occur when it is set to zero. + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/Make.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/Make.config Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,36 @@ +# +# User defined Makefile options for graphlcd daemon and tools + +### The C compiler and options: + +CC = gcc +CFLAGS = -O2 + +CXX = g++ +CXXFLAGS = -g -O2 -Wall -Woverloaded-virtual +#CXXFLAGS = -g -ggdb -O0 -Wall -Woverloaded-virtual + +#LDFLAGS = -g -ggdb -O0 + +LDCONFIG = ldconfig + +### The directory environment: + +ifndef $(DESTDIR) +DESTDIR = /usr/local +endif + +BINDIR = $(DESTDIR)/bin +LIBDIR = $(DESTDIR)/lib +INCDIR = $(DESTDIR)/include +MANDIR = $(DESTDIR)/man + +### Includes and defines + +#INCLUDES += -I + +DEFINES += -D_GNU_SOURCE + +# comment this variable out if you don't want to use FreeType2 font rendering +HAVE_FREETYPE2=1 + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/Makefile Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,41 @@ +# +# Makefile for the GraphLCD driver library, graphics library and tools +# + +PROJECT = graphlcd-base +VERSION = 0.1.5 +ARCHIVE = $(PROJECT)-$(VERSION) +PACKAGE = $(ARCHIVE) +TMPDIR = /tmp + +### Targets: + +all: + @$(MAKE) -C glcdgraphics all + @$(MAKE) -C glcddrivers all + @$(MAKE) -C tools all + +install: + @$(MAKE) -C glcdgraphics install + @$(MAKE) -C glcddrivers install + @$(MAKE) -C tools install + +uninstall: + @$(MAKE) -C glcdgraphics uninstall + @$(MAKE) -C glcddrivers uninstall + @$(MAKE) -C tools uninstall + +clean: + @-rm -f *.tgz + @$(MAKE) -C glcdgraphics clean + @$(MAKE) -C glcddrivers clean + @$(MAKE) -C tools clean + +dist: clean + @-rm -rf $(TMPDIR)/$(ARCHIVE) + @mkdir $(TMPDIR)/$(ARCHIVE) + @cp -a * $(TMPDIR)/$(ARCHIVE) + @tar czf $(PACKAGE).tgz --exclude .svn --exclude *.cbp --exclude *.layout -C $(TMPDIR) $(ARCHIVE) + @-rm -rf $(TMPDIR)/$(ARCHIVE) + @echo Distribution package created as $(PACKAGE).tgz + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/README Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,97 @@ +This is the base package of the GraphLCD project. It contains + - GraphLCD driver library - libglcddrivers + - GraphLCD graphics library - libglcdgraphics + - GraphLCD tools (crtfont, convpic, showpic, showtext) + - GraphLCD media files (pictures and splash screens in GLCD format, fonts) + +written by Andreas Regel (andreas.regel AT powarman.de) + +based on the graphlcd plugin for the Video Disc Recorder + written by Carsten Siebholz (c.siebholz AT t-online.de) + from 0.0.8 on maintained by Andreas Regel (andreas.regel AT powarman.de) + gu140x32f driver by Andreas Brachold (vdr04 AT deltab.de) + gu256x64-372 driver by Andreas Weinberger (vdr AT smue.org) + gu256x64-3xx0 driver by Ralf Mueller (ralf AT bj-ig.de) + gu126x64D-K610A4 driver by Alexander Rieger (Alexander.Rieger AT inka.de) + image driver by Andreas Regel (andreas.regel AT powarman.de) + ks0108 driver by Andreas Weinberger (vdr AT smue.org) + sed1330 driver by Roland Praml (praml.roland AT t-online.de) + Heinz Gressenberger (heinz.gressenberger AT stmk.gv.at) + sed1520 driver by Andreas Weinberger (vdr AT smue.org) + framebuffer driver by Stephan Skrodzki (skrodzki AT stevekist.de) + serdisplib driver by Wolfgang Astleitner (mrwastl AT users.sourceforge.net) + t6963c driver by Andreas Regel (andreas.regel AT powarman.de) + noritake800 drider by Lucian Muresan (lucianm AT users.sourceforge.net) + + +Project's homepage: http://graphlcd.berlios.de/ + + +See the file COPYING for license information. + + +Description +----------- +The GraphLCD base is a project to support graphical LC displays. It is +mainly used by the graphlcd plugin for the Video Disc Recorder to +display its information. + +The GraphLCD driver library supports the following LCD +controllers/modules: + - Hitachi HD61830 + - Toshiba T6963 + - Samsung KS0108 + - Epson SED1520 (only tested with DIP122 lcd module) + - Epson SED1330 + - Noritake GU140X32F-7806 + - Noritake GU256X64-372 + - Noritake GU256X64-3XX0 (serial or parallel) + - Noritake GU126x64D-K610A4 displays (parallel) + - Noritake 800 series displays + - all controllers supported by serdisplib (http://serdisplib.sourceforge.net) + +Other controllers might be supported in the future. + +Additionally the GraphLCD driver library includes some special drivers: + - framebuffer, for devices that are connected to the VGA connector + - image, for writing image sequences in PBM (Portable Bit Map) format that + show the plugin's output. + + +Installation and Configuration: +------------------------------- +1. Unpack the tarball to an arbitrary directory. + + tar xzf graphlcd-base-0.1.2.tgz + +2. Configure if you want FreeType2 support by commenting/uncommenting + HAVE_FREETYPE2 in Make.config. + +3. Compile the libraries and tools. + + make all (from the package's directory) + +4. Install the libraries and tools. + + make install (from the package's directory) + +5. Edit the configuration file graphlcd.conf to fit your needs. + +6. Copy it to the GraphLCD's default configuration search path (/etc). + + cp graphlcd.conf /etc + + +Notes about FreeType2: +---------------------- +If the HAVE_FREETYPE2 variable is defined, then the new method +cFont::LoadFT2(..) from the graphics library will load a FreeType2-supported +font (only TTFs tested so far) and render it into the raster font structure +that cFont uses normally. The method is also defined if no FT2 support is +compiled in, only then it will return false afer logging an error message in +the system log, telling that graphlcd-base has been compiled without FT2 +support. This way, applications using this library (vdrplugin-graphlcd, or the +wrapper LCDproc "meta-driver" glcdprocdriver for example, can treat this case +and have a fallback to the glcdraphics-native raster font if FT2 is not +supported, or the TTF font could not be loaded for some reason. + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.framebuffer --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.framebuffer Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,44 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The Framebuffer driver +--------------------------------------------------------------------- + +Description +----------- +The Framebuffer driver writes the output to the framebuffer device at +/dev/fb0. + +The driver is optimized for a 640x480x16 framebuffer. To use it, have +a kernel with a framebuffer device (e.g. vesa fb) and add e.g. +vga=0311 to the kernel init parameters (e.g. in lilo.conf). + + +Configuration Parameters +------------------------ +The Framebuffer driver supports the following parameters in config +file: + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 320 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 240 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +Zoom + Determines if pixels should be drawn double sized. + Possible values: 0, 1 + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.gu126x64D-K610A4 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.gu126x64D-K610A4 Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,111 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The GU126X64-K610A4 driver +--------------------------------------------------------------------- + +Description +----------- +The GU126X64-K610A4 driver supports Noritake GU126X64D-K610A4 VFD +display. + +The VFD is connected to a single PC parallel port. + +Wirings +------- +The GU126X64-K610A4 driver supports the following connections on a +parallel port: + + + printerport LCD other + ----------- ---------------- ------- + 5V (Con1.1) VCC (Power supply 5V) + ACK (10) MB (Con1.9) (Module Busy) + 0V (Con1.5) GND (Ground) + + GND (18) 0V (Con2.1) (Ground) + INIT (16) ENABLE (Con2.2) (ENABLE) + D0 (02) PA0 (Con2.3) (DataBit 0) + D1 (03) PA1 (Con2.4) (DataBit 1) + D2 (04) PA2 (Con2.5) (DataBit 2) + D3 (05) PA3 (Con2.6) (DataBit 3) + D4 (06) PA4 (Con2.7) (DataBit 4) + D5 (07) PA5 (Con2.8) (DataBit 5) + D6 (08) PA6 (Con2.9) (DataBit 6) + D7 (09) PA7 (Con2.10) (DataBit 7) + +The Display is configured to parallel port mode with "Clock Input" +to "Falling Edge". + +================================================================ + +Configuration Parameters +------------------------ +The GU126X64-K610A4 driver supports the following parameters in +config file: + +Device + Instead of using the direct output via port address (see Port), you + can use the parport device (/dev/parportX). The advantage over the + direct output via port address is that this works for non-root users + also. But it's a little bit slower. The modules ppdev.o, parport.o + and parport_pc.o must be loaded or compiled into the kernel. + +Port + Sets the port address of the parallel port. If this parameter is not + given, 0x378 is used. To use this direct output, the program that + uses the driver library has to be started with user 'root'. + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 256 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 64 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +Brightness + Sets the brightness of your display's backlight. + Possible values: 0 <= x <= 100) + Default value: 100 + +AdjustTiming + To get a timing that is as accurate as possible, the drivers measure + the time for port commands (see: benchmark in syslog). You might + decrease or increase the time to wait after port commands with this + parameter. Normally, there is no need to change this parameter. + Possible values: -50 <= x <= 50 + Default value: 0 + +RefreshDisplay + Normally, most of the drivers do not update the whole display, but + only the areas that have changed since last update. So it might be, + that some faulty pixels would stay a longer time. To avoid this, the + plugin makes a complete refresh from time to time. This parameter + defines how often a complete refresh will be done. + e.g.: A value of 5 means, that the plugin will make a complete + refresh on every 5th update. + A value of 0 completely disables complete refreshs. + Possible values: 0 <= x <= 50 + Default value: 0 + +Debug + Prints debugging information of some methods of the driver. + (add the values of interest) + + 1: show a log at the start of a refresh + 2: show a log at the end of a refresh with timing information + 4: show the rows (8 pixel) refreshed + 8: show every commands/bytes sent to the display + 16: log every unsuccessful waiting for display acknowledge diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.gu140x32f --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.gu140x32f Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,126 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The GU140X32F driver +--------------------------------------------------------------------- + +Description +----------- +The GU140X32F driver supports Noritake GU140x32-F7806 VFD displays. +The VFD is operating in its 8 bit-mode connected to a PC's parallel +port. + + +Wirings +------- +The GU140x32F driver supports the following connections on a parallel +port: + - Standard + - Windows + +Standard wiring: + + printerport LCD other + ----------- ---------- ---------- + GND (01) GND (Ground) + VCC (02) VCC (+5VDC 500mA) + NC (03) + nSTRB (01) RS (04) (Register Select) + nAUTO (14) RW (05) (Read/Write) + INIT (16) EN (06) (Chip Enable) + D0 (02) D0 (07) (Data Bit 0) + D1 (03) D1 (08) (Data Bit 1) + D2 (04) D2 (09) (Data Bit 2) + D3 (05) D3 (10) (Data Bit 3) + D4 (06) D4 (11) (Data Bit 4) + D5 (07) D5 (12) (Data Bit 5) + D6 (08) D6 (13) (Data Bit 6) + D7 (09) D7 (14) (Data Bit 7) + +Windows wiring: + + printerport LCD other + ----------- ---------- ---------- + GND (01) GND (Ground) + VCC (02) VCC (+5VDC 500mA) + NC (03) + INIT (16) RS (04) (Register Select) + nAUTO (14) RW (05) (Read/Write) + nSTRB (01) EN (06) (Chip Enable) + D0 (02) D0 (07) (Data Bit 0) + D1 (03) D1 (08) (Data Bit 1) + D2 (04) D2 (09) (Data Bit 2) + D3 (05) D3 (10) (Data Bit 3) + D4 (06) D4 (11) (Data Bit 4) + D5 (07) D5 (12) (Data Bit 5) + D6 (08) D6 (13) (Data Bit 6) + D7 (09) D7 (14) (Data Bit 7) + +Note: The pin numbering may vary with other displays. + + +Configuration Parameters +------------------------ +The GU140x32F driver supports the following parameters in config file: + +Device + Instead of using the direct output via port address (see Port), you + can use the parport device (/dev/parportX). The advantage over the + direct output via port address is that this works for non-root users + also. But it's a little bit slower. The modules ppdev.o, parport.o + and parport_pc.o must be loaded or compiled into the kernel. + +Port + Sets the port address of the parallel port. If this parameter is not + given, 0x378 is used. To use this direct output, the program that + uses the driver library has to be started with user 'root'. + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 140 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 32 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +Brightness + Sets the brightness of your display's backlight. + Possible values: 0 <= x <= 100) + Default value: 100 + +AdjustTiming + To get a timing that is as accurate as possible, the drivers measure + the time for port commands (see: benchmark in syslog). You might + decrease or increase the time to wait after port commands with this + parameter. Normally, there is no need to change this parameter. + Possible values: -50 <= x <= 50 + Default value: 0 + +RefreshDisplay + Normally, most of the drivers do not update the whole display, but + only the areas that have changed since last update. So it might be, + that some faulty pixels would stay a longer time. To avoid this, the + plugin makes a complete refresh from time to time. This parameter + defines how often a complete refresh will be done. + e.g.: A value of 5 means, that the plugin will make a complete + refresh on every 5th update. + A value of 0 completely disables complete refreshs. + Possible values: 0 <= x <= 50 + Default value: 5 + +Wiring + Select the type of wiring your display is connected with. + Possible values: 'Standard', 'Windows' + Default value: 'Standard' + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.gu256x64-372 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.gu256x64-372 Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,96 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The GU256X64-372 driver +--------------------------------------------------------------------- + +Description +----------- +The GU256X64-372 driver supports Noritake GU256x64-372 VFD displays. +The VFD is operating in its 8 bit-mode connected to a PC's parallel +port. + + +Wiring +------ +The GU256x64-372 driver supports the following connection on a parallel +port: + + printerport LCD other + ----------- ---------- ---------- + D0 (02) D0 (15) (Data Bit 0) + D1 (03) D1 (13) (Data Bit 1) + D2 (04) D2 (11) (Data Bit 2) + D3 (05) D3 (09) (Data Bit 3) + D4 (06) D4 (07) (Data Bit 4) + D5 (07) D5 (05) (Data Bit 5) + D6 (08) D6 (03) (Data Bit 6) + D7 (09) D7 (01) (Data Bit 7) + INIT (16) nWR (17) (Write) + nSEL (17) R/S (19) (Register Select, C/D) + GND (18) nRD (21) (Read) + GND (18) CSS (23) (Chip Select) + GND (18) GND (02) (Ground) + + +Configuration Parameters +------------------------ +The GU256x64-372 driver supports the following parameters in config +file: + +Device + Instead of using the direct output via port address (see Port), you + can use the parport device (/dev/parportX). The advantage over the + direct output via port address is that this works for non-root users + also. But it's a little bit slower. The modules ppdev.o, parport.o + and parport_pc.o must be loaded or compiled into the kernel. + +Port + Sets the port address of the parallel port. If this parameter is not + given, 0x378 is used. To use this direct output, the program that + uses the driver library has to be started with user 'root'. + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 256 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 64 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +Brightness + Sets the brightness of your display's backlight. + Possible values: 0 <= x <= 100) + Default value: 100 + +AdjustTiming + To get a timing that is as accurate as possible, the drivers measure + the time for port commands (see: benchmark in syslog). You might + decrease or increase the time to wait after port commands with this + parameter. Normally, there is no need to change this parameter. + Possible values: -50 <= x <= 50 + Default value: 0 + +RefreshDisplay + Normally, most of the drivers do not update the whole display, but + only the areas that have changed since last update. So it might be, + that some faulty pixels would stay a longer time. To avoid this, the + plugin makes a complete refresh from time to time. This parameter + defines how often a complete refresh will be done. + e.g.: A value of 5 means, that the plugin will make a complete + refresh on every 5th update. + A value of 0 completely disables complete refreshs. + Possible values: 0 <= x <= 50 + Default value: 5 + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.gu256x64-3900 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.gu256x64-3900 Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,176 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The GU256X64-3900 driver +--------------------------------------------------------------------- + +Description +----------- +The GU256X64-3900 driver supports Noritake GU256X64-3900 VFD displays. +The VFD is either operating in 8 bit-mode connected to a single PC +parallel port or in serial mode connected to a single PC serial port. + + +Wirings +------- +The GU256X64-3900 driver supports the following connections on a +parallel port: + - Standard + - Satyr + +Standard wiring: + + printerport LCD other + ----------- ---------- ---------- + D0 (02) DB0 (08) (DataBit 0) + D1 (03) DB1 (07) (DataBit 1) + D2 (04) DB2 (06) (DataBit 2) + D3 (05) DB3 (05) (DataBit 3) + D4 (06) DB4 (04) (DataBit 4) + D5 (07) DB5 (03) (DataBit 5) + D6 (08) DB6 (02) (DataBit 6) + D7 (09) DB7 (01) (DataBit 7) + ACK (10) RDY (12) (Display Ready) + INIT (16) nWR (10) (Write) + GND (18) GND (09) GND (Ground) + GND (19) GND (11) GND (Ground) + GND (20) GND (13) GND (Ground) + GND (21) GND (14) GND (Ground) + VCC (15) VCC (Power supply 5V) + VCC (16) VCC (Power supply 5V) + +Satyr Wiring: + + printerport LCD other + ----------- ---------- ---------- + nSTRB (01) nWR (10) (Write) + D0 (02) DB0 (08) (DataBit 0) + D1 (03) DB1 (07) (DataBit 1) + D2 (04) DB2 (06) (DataBit 2) + D3 (05) DB3 (05) (DataBit 3) + D4 (06) DB4 (04) (DataBit 4) + D5 (07) DB5 (03) (DataBit 5) + D6 (08) DB6 (02) (DataBit 6) + D7 (09) DB7 (01) (DataBit 7) + BUSY (11) RDY (12) (Display Ready) + GND (18) GND (09) GND (Ground) + GND (19) GND (11) GND (Ground) + GND (20) GND (13) GND (Ground) + GND (21) GND (14) GND (Ground) + VCC (15) VCC (Power supply 5V) + VCC (16) VCC (Power supply 5V) + +Note: The pin numbering may vary with other displays. + + +The GU256X64-3900 driver supports the following connection on a +serial port: + + serialport LCD other + ---------- ---------- ---------- + DCD (01) DTR (02) + RxD (02) TxD (04) + TxD (03) RxD (01) + DTR (04) DSR (03) + GND (05) GND (07) GND (Ground) + DSR (06) DTR (02) + VCC (06) VCC (Power supply 5V) + +Note: The pin numbering may vary with other displays. + +On display switches: + SW No. Function Default + ------ -------- ------- + 1 Display address select Off + 2 Display address select Off + 3 Display address select Off + 4 Display address select Off + 5 Baud rate select Off + 6 Command mode select Off switch DMA On/Off + 7 Operating mode select Off + 8 Protocol Select Off + +Serial access to GU256X64C-3xx0 is nearly as fast as normal parallel +access but doesn't create the high system load of the parallel +approach. So for me serial access is preferred over normal parallel +mode. Even better is the DMA parallel mode. For DMA mode you have to +switch SW6 on the display to ON. + + +Configuration Parameters +------------------------ +The GU256X64-3900 driver supports the following parameters in config +file: + +Device + Instead of using the direct output via port address (see Port), you + can use the parport device (/dev/parportX). The advantage over the + direct output via port address is that this works for non-root users + also. But it's a little bit slower. The modules ppdev.o, parport.o + and parport_pc.o must be loaded or compiled into the kernel. + +Port + Sets the port address of the parallel port. If this parameter is not + given, 0x378 is used. To use this direct output, the program that + uses the driver library has to be started with user 'root'. + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 256 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 64 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +Brightness + Sets the brightness of your display's backlight. + Possible values: 0 <= x <= 100) + Default value: 100 + +AdjustTiming + To get a timing that is as accurate as possible, the drivers measure + the time for port commands (see: benchmark in syslog). You might + decrease or increase the time to wait after port commands with this + parameter. Normally, there is no need to change this parameter. + Possible values: -50 <= x <= 50 + Default value: 0 + +RefreshDisplay + Normally, most of the drivers do not update the whole display, but + only the areas that have changed since last update. So it might be, + that some faulty pixels would stay a longer time. To avoid this, the + plugin makes a complete refresh from time to time. This parameter + defines how often a complete refresh will be done. + e.g.: A value of 5 means, that the plugin will make a complete + refresh on every 5th update. + A value of 0 completely disables complete refreshs. + Possible values: 0 <= x <= 50 + Default value: 5 + +Wiring + Select the type of wiring your display is connected with. + Possible values: 'Standard', 'Satyr' + Default value: 'Standard' + +Interface + Select the interface your display is connnected to. + Possible values: 'Parallel', 'Serial' + Default value: 'Parallel' + +DMA + Enables/disables the usage of the controller's DMA mode which + increases writing speed. This only works in parallel interface mode. + Possible values: 'yes', 'no' + Default value: 'yes' + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.hd61830 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.hd61830 Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,96 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The HD61830 driver +--------------------------------------------------------------------- + +Description +----------- +The HD61830 driver supports LC displays that use the Hitachi HD61830 +controller, connected to the parallel port of your PC. + + +Wirings +------- +The HD61830 driver supports the following connection on a parallel +port: + + printerport LCD other + ----------- ---------- ---------- + GND (18) GND (01) GND (Ground) + VDD (02) +5V (V Controller) + V0 (03) +5V..-15V (Contrast) + INIT (16) RS (04) (Register Select) + nAUTO (14) R/W (05) (Read 1/Write 0) + nSTRB (01) EN (06) (Enable) + D0 (02) D0 (07) (DataBit0) + D1 (03) D1 (08) (DataBit1) + D2 (04) D2 (09) (DataBit2) + D3 (05) D3 (10) (DataBit3) + D4 (06) D4 (11) (DataBit4) + D5 (07) D5 (12) (DataBit5) + D6 (08) D6 (13) (DataBit6) + D7 (09) D7 (14) (DataBit7) + nCS (15) GND (Chip Select) + nRES (16) +5V (Reset) + VEE (17) -12V (V LCD) + nDO (18) (not connected) + +Note: The pin numbering may vary with other displays. + + +Configuration Parameters +------------------------ +The HD61830 driver supports the following parameters in config file: + +Device + Instead of using the direct output via port address (see Port), you + can use the parport device (/dev/parportX). The advantage over the + direct output via port address is that this works for non-root users + also. But it's a little bit slower. The modules ppdev.o, parport.o + and parport_pc.o must be loaded or compiled into the kernel. + +Port + Sets the port address of the parallel port. If this parameter is not + given, 0x378 is used. To use this direct output, the program that + uses the driver library has to be started with user 'root'. + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 240 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 128 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +AdjustTiming + To get a timing that is as accurate as possible, the drivers measure + the time for port commands (see: benchmark in syslog). You might + decrease or increase the time to wait after port commands with this + parameter. Normally, there is no need to change this parameter. + Possible values: -50 <= x <= 50 + Default value: 0 + +RefreshDisplay + Normally, most of the drivers do not update the whole display, but + only the areas that have changed since last update. So it might be, + that some faulty pixels would stay a longer time. To avoid this, the + plugin makes a complete refresh from time to time. This parameter + defines how often a complete refresh will be done. + e.g.: A value of 5 means, that the plugin will make a complete + refresh on every 5th update. + A value of 0 completely disables complete refreshs. + Possible values: 0 <= x <= 50 + Default value: 5 + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.image --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.image Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,36 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The Image driver +--------------------------------------------------------------------- + +Description +----------- +The Image driver writes image sequences in PBM (Portable Bit Map) +format showing the output that you would normally see on a LCD e.g. +from the graphlcd plugin. + + +Configuration Parameters +------------------------ +The Image driver supports the following parameters in config file: + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 240 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 128 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.ks0108 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.ks0108 Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,124 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The KS0108 driver +--------------------------------------------------------------------- + +Description +----------- +The KS0108 driver supports LC displays that use the Samsung KS0108 +controller, connected to the parallel port of your PC. + + +Wirings +------- +The KS0108 driver supports the following connection on a parallel +port: + + printerport LCD other + ----------- ---------- ---------- + GND (18) GND (01) GND (Ground) + Vdd (02) +5V + Vo (03) (LCD Contrast In) + nSEL (17) R/S (04) (Register Select) + R/W (05) GND (Read/Write) + nSTRB (01) EN (06) (Enable) + D0 (02) D0 (07) (DataBit0) + D1 (03) D1 (08) (DataBit1) + D2 (04) D2 (09) (DataBit2) + D3 (05) D3 (10) (DataBit3) + D4 (06) D4 (11) (DataBit4) + D5 (07) D5 (12) (DataBit5) + D6 (08) D6 (13) (DataBit6) + D7 (09) D7 (14) (DataBit7) + nAUTO (14) CS1 (15) (ChipSelect Controller 1) + INIT (16) CS2 (16) (ChipSelect Controller 2) + RESET (17) +5V (Controller Reset) + Vout (18) (Contrast Out) + LED+ (19) +4V (Backlight) + LED- (20) GND (Backlight GND) + +Note: The pin numbering may vary with other displays. + +If you want to connect a 192x64 or 256x64 display (with 3 or 4 +ChipSelects) or two 128x64 displays, you must add a binary decoder for +the ChipSelect lines. The mode ist auto-selected based on the width and +height parameters. + + nAUTO (14) + | INIT (16) + Vdd | | GND GND + | | | | | + 16 15 14 13 12 11 10 09 + -------------------------------- + | | + > | + | | + -------------------------------- + 01 02 03 04 05 06 07 08 + | | | | | + CS1 | | | GND + CS2 | CS4 (CS2 second LCD) + CS3 (CS1 second LCD) + + +Configuration Parameters +------------------------ +The KS0108 driver supports the following parameters in config file: + +Device + Instead of using the direct output via port address (see Port), you + can use the parport device (/dev/parportX). The advantage over the + direct output via port address is that this works for non-root users + also. But it's a little bit slower. The modules ppdev.o, parport.o + and parport_pc.o must be loaded or compiled into the kernel. + +Port + Sets the port address of the parallel port. If this parameter is not + given, 0x378 is used. To use this direct output, the program that + uses the driver library has to be started with user 'root'. + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 128 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 64 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +AdjustTiming + To get a timing that is as accurate as possible, the drivers measure + the time for port commands (see: benchmark in syslog). You might + decrease or increase the time to wait after port commands with this + parameter. Normally, there is no need to change this parameter. + Possible values: -50 <= x <= 50 + Default value: 0 + +RefreshDisplay + Normally, most of the drivers do not update the whole display, but + only the areas that have changed since last update. So it might be, + that some faulty pixels would stay a longer time. To avoid this, the + plugin makes a complete refresh from time to time. This parameter + defines how often a complete refresh will be done. + e.g.: A value of 5 means, that the plugin will make a complete + refresh on every 5th update. + A value of 0 completely disables complete refreshs. + Possible values: 0 <= x <= 50 + Default value: 5 + +Control + Sets the variant of setting the display control lines. + Possible values: 0, 1 + Default value: 1 + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.noritake800 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.noritake800 Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,115 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The Noritake 800(A) series driver +--------------------------------------------------------------------- + +Description +----------- +The Noritake 800(A) series driver supports following VFD displays manufactured +by Noritake (see http://www.noritake-itron.com on the link "Medium 0.6 dot"): + - GU128X64-800A; + - GU256X32-800A; + - GU128X32-800A; + - GU160X16-800A; + - GU160X32-800A; + - GU192X16-800A. + +Wirings +------- +The VFD should be connected to a parallel port of the PC + +printer port LIQUIDMP3 MZ other? +--------------------------------------------- + +Data lines D0...D7 connected straight in all wirings + +Strobe (1) CSS (23) WR (17) +Linefeed (14) RD (21) RD (21) +Init (16) WR (17) CSS (23) +Select (17) C/D (19) C/D (19) + +Printer port pins 18 .... 25 connected to GND; +VFD *ONLY EVEN* pins 2 .... 24 connected to GND +Everything else is *NOT CONNECTED* + +Further wirings might work and then for sure very easyly added to the code. +Just extend N800LptWiringMask(..) accordingly. This method is called in a +loop over all 16 (4 wires for now) possibilities in the constructor, so the +results are cached for the actual writes to the LPT control port, very +similar to ReverseBits(..) for data. + +The driver should also work for "WIRING_MZ", just report if there are +problems. +Feel free to add support for "Parallel #2 Interface" or "Serial interface". + +Tested only on my own GU128x64-800(A) so far, just with the default 8-bit +mode parallel wiring (referred as WIRING_LIQUIDMP3 or "0" in this code, or +"Parallel #1 Interface"in the data sheet). I can't actually test the other +wiring (as the display is already mounted in my HTPC, and the cable soldered), +or even the other modes from the datasheet ("Parallel #2 Interface", or +"Serial interface"), for those, my display lacks the necessary jumpers on +it's PCB) + + +Configuration Parameters +------------------------ +The Noritake 800(A) series driver supports the following parameters in config +file: + +Device + Instead of using the direct output via port address (see Port), you + can use the parport device (/dev/parportX). The advantage over the + direct output via port address is that this works for non-root users + also. But it's a little bit slower. The modules ppdev.o, parport.o + and parport_pc.o must be loaded or compiled into the kernel. + +Port + Sets the port address of the parallel port. If this parameter is not + given, 0x378 is used. To use this direct output, the program that + uses the driver library has to be started with user 'root'. + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 256 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 64 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +Brightness + Sets the brightness of your display's backlight. + Possible values: 0 <= x <= 100) + Default value: 100 + +AdjustTiming ---> not used in this driver (if there are problems, please report) + To get a timing that is as accurate as possible, the drivers measure + the time for port commands (see: benchmark in syslog). You might + decrease or increase the time to wait after port commands with this + parameter. Normally, there is no need to change this parameter. + Possible values: -50 <= x <= 50 + Default value: 0 + +RefreshDisplay ---> not used in this driver (if there are problems, please report) + Normally, most of the drivers do not update the whole display, but + only the areas that have changed since last update. So it might be, + that some faulty pixels would stay a longer time. To avoid this, the + plugin makes a complete refresh from time to time. This parameter + defines how often a complete refresh will be done. + e.g.: A value of 5 means, that the plugin will make a complete + refresh on every 5th update. + A value of 0 completely disables complete refreshs. + Possible values: 0 <= x <= 50 + Default value: 5 + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.sed1330 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.sed1330 Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,223 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The SED1330 driver +--------------------------------------------------------------------- + +Description +----------- +The SED1330 driver supports LC displays that use the Epson +SED1330/1335 controller, connected to the parallel port of your PC. + + +Wirings +------- +The SED1330 driver supports the following connections on a parallel +port: + - Original + - PowerLCD + - LCDProc + - Tweakers + - YASEDW + +Original wiring: + + printerport LCD other function in 6800 mode 8080 mode + ----------- ---------- ---------- --------------------- ----------- + /RES (01) +5V /RES (Reset) + nSTRB (01) /RD (02) E (Enable) /RD (Read) + nAUTO (14) /WR (03) R/W (Read/Write) /WR (Write) + SEL2 (04) GND Interface select 2 + SEL1 (05) +5V Interface select 1 + nSEL (17) /CS (06) GND /CS (Chip select) + INIT (16) A0 (07) A0 (Access type) + D0 (02) DB0 (08) D0 (Data bus 0) + D1 (03) DB1 (09) D1 (Data bus 1) + D2 (04) DB2 (10) D2 (Data bus 2) + D3 (05) DB3 (11) D3 (Data bus 3) + D4 (06) DB4 (12) D4 (Data bus 4) + D5 (07) DB5 (13) D5 (Data bus 5) + D6 (08) DB6 (14) D6 (Data bus 6) + D7 (09) DB7 (15) D7 (Data bus 7) + VDD (16) +5V VDD (Logic power supply) + GND (18) VSS (17) GND GND (Ground) + V0 (18) +5V..-22V V0 (LCD contrast) + VLC (19) -22V VEE (LCD drive voltage) + FGND (20) GND Frame ground + +PowerLCD wiring: + + printerport LCD other function in 6800 mode 8080 mode + ----------- ---------- ---------- --------------------- ----------- + /RES (01) +5V /RES (Reset) + nSEL (17) /RD (02) E (Enable) /RD (Read) + nSTRB (01) /WR (03) R/W (Read/Write) /WR (Write) + SEL2 (04) GND Interface select 2 + SEL1 (05) +5V Interface select 1 + nAUTO (14) /CS (06) GND /CS (Chip select) + INIT (16) A0 (07) A0 (Access type) + D0 (02) DB0 (08) D0 (Data bus 0) + D1 (03) DB1 (09) D1 (Data bus 1) + D2 (04) DB2 (10) D2 (Data bus 2) + D3 (05) DB3 (11) D3 (Data bus 3) + D4 (06) DB4 (12) D4 (Data bus 4) + D5 (07) DB5 (13) D5 (Data bus 5) + D6 (08) DB6 (14) D6 (Data bus 6) + D7 (09) DB7 (15) D7 (Data bus 7) + VDD (16) +5V VDD (Logic power supply) + GND (18) VSS (17) GND GND (Ground) + V0 (18) +5V..-22V V0 (LCD contrast) + VLC (19) -22V VEE (LCD drive voltage) + FGND (20) GND Frame ground + +LCDProc wiring: + + printerport LCD other function in 6800 mode 8080 mode + ----------- ---------- ---------- --------------------- ----------- + /RES (01) +5V /RES (Reset) + INIT (16) /RD (02) E (Enable) /RD (Read) + nAUTO (14) /WR (03) R/W (Read/Write) /WR (Write) + SEL2 (04) GND Interface select 2 + SEL1 (05) +5V Interface select 1 + nSTRB (01) /CS (06) GND /CS (Chip select) + nSEL (17) A0 (07) A0 (Access type) + D0 (02) DB0 (08) D0 (Data bus 0) + D1 (03) DB1 (09) D1 (Data bus 1) + D2 (04) DB2 (10) D2 (Data bus 2) + D3 (05) DB3 (11) D3 (Data bus 3) + D4 (06) DB4 (12) D4 (Data bus 4) + D5 (07) DB5 (13) D5 (Data bus 5) + D6 (08) DB6 (14) D6 (Data bus 6) + D7 (09) DB7 (15) D7 (Data bus 7) + VDD (16) +5V VDD (Logic power supply) + GND (18) VSS (17) GND GND (Ground) + V0 (18) +5V..-22V V0 (LCD contrast) + VLC (19) -22V VEE (LCD drive voltage) + FGND (20) GND Frame ground + +Tweakers wiring: + + printerport LCD other function in 6800 mode 8080 mode + ----------- ---------- ---------- --------------------- ----------- + /RES (01) +5V /RES (Reset) + nAUTO (14) /RD (02) E (Enable) /RD (Read) + INIT (16) /WR (03) R/W (Read/Write) /WR (Write) + SEL2 (04) GND Interface select 2 + SEL1 (05) +5V Interface select 1 + nSTRB (01) /CS (06) GND /CS (Chip select) + nSEL (17) A0 (07) A0 (Access type) + D0 (02) DB0 (08) D0 (Data bus 0) + D1 (03) DB1 (09) D1 (Data bus 1) + D2 (04) DB2 (10) D2 (Data bus 2) + D3 (05) DB3 (11) D3 (Data bus 3) + D4 (06) DB4 (12) D4 (Data bus 4) + D5 (07) DB5 (13) D5 (Data bus 5) + D6 (08) DB6 (14) D6 (Data bus 6) + D7 (09) DB7 (15) D7 (Data bus 7) + VDD (16) +5V VDD (Logic power supply) + GND (18) VSS (17) GND GND (Ground) + V0 (18) +5V..-22V V0 (LCD contrast) + VLC (19) -22V VEE (LCD drive voltage) + FGND (20) GND Frame ground + +YASEDW wiring: + + printerport LCD other function in 6800 mode 8080 mode + ----------- ---------- ---------- --------------------- ----------- + /RES (01) +5V /RES (Reset) + INIT (16) /RD (02) E (Enable) /RD (Read) + nSTRB (01) /WR (03) R/W (Read/Write) /WR (Write) + SEL2 (04) GND Interface select 2 + SEL1 (05) +5V Interface select 1 + nSEL (17) /CS (06) GND /CS (Chip select) + nAUTO (14) A0 (07) A0 (Access type) + D0 (02) DB0 (08) D0 (Data bus 0) + D1 (03) DB1 (09) D1 (Data bus 1) + D2 (04) DB2 (10) D2 (Data bus 2) + D3 (05) DB3 (11) D3 (Data bus 3) + D4 (06) DB4 (12) D4 (Data bus 4) + D5 (07) DB5 (13) D5 (Data bus 5) + D6 (08) DB6 (14) D6 (Data bus 6) + D7 (09) DB7 (15) D7 (Data bus 7) + VDD (16) +5V VDD (Logic power supply) + GND (18) VSS (17) GND GND (Ground) + V0 (18) +5V..-22V V0 (LCD contrast) + VLC (19) -22V VEE (LCD drive voltage) + FGND (20) GND Frame ground + +Note: The pin numbering may vary with other displays. + +SEL1 on GND selects 8080 mode, SEL1 on VDD selects 6800 mode. + + +Configuration Parameters +------------------------ +The SED1330 driver supports the following parameters in config file: + +Device + Instead of using the direct output via port address (see Port), you + can use the parport device (/dev/parportX). The advantage over the + direct output via port address is that this works for non-root users + also. But it's a little bit slower. The modules ppdev.o, parport.o + and parport_pc.o must be loaded or compiled into the kernel. + +Port + Sets the port address of the parallel port. If this parameter is not + given, 0x378 is used. To use this direct output, the program that + uses the driver library has to be started with user 'root'. + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 320 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 240 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +AdjustTiming + To get a timing that is as accurate as possible, the drivers measure + the time for port commands (see: benchmark in syslog). You might + decrease or increase the time to wait after port commands with this + parameter. Normally, there is no need to change this parameter. + Possible values: -50 <= x <= 50 + Default value: 0 + +RefreshDisplay + Normally, most of the drivers do not update the whole display, but + only the areas that have changed since last update. So it might be, + that some faulty pixels would stay a longer time. To avoid this, the + plugin makes a complete refresh from time to time. This parameter + defines how often a complete refresh will be done. + e.g.: A value of 5 means, that the plugin will make a complete + refresh on every 5th update. + A value of 0 completely disables complete refreshs. + Possible values: 0 <= x <= 50 + Default value: 5 + +Wiring + Select the type of wiring your display is connected with. + Possible values: 'Original', 'PowerLCD', 'LCDProc', 'Tweakers', + 'YASEDW' + Default value: 'Original' + +OscillatorFrequency + Select the frequency the oscillator on your LCD board uses in kHz. + Possible values: 1000 <= x <= 15000) + Default value: 9600 + +Interface + Select the interface mode your display is connected with. + Possible values: '6800', '8080' + Default value: '6800' + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.sed1520 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.sed1520 Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,98 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The SED1520 driver +--------------------------------------------------------------------- + +Description +----------- +The SED1520 driver supports LC displays that use the Epson SED1520 +controller, connected to the parallel port of your PC. + + +Wirings +------- +The SED1520 driver supports the following connection on a parallel +port: + + printerport LCD other + ----------- ---------- ---------- + GND (18) GND (01) GND (Ground) + Vdd (02) +5V + Vo (03) (LCD Contrast In -4V) + nSEL (17) R/S (04) (Register Select) + R/W (05) GND (Read/Write) + nSTRB (01) EN1 (06) (Enable Left) + D0 (02) D0 (07) (DataBit0) + D1 (03) D1 (08) (DataBit1) + D2 (04) D2 (09) (DataBit2) + D3 (05) D3 (10) (DataBit3) + D4 (06) D4 (11) (DataBit4) + D5 (07) D5 (12) (DataBit5) + D6 (08) D6 (13) (DataBit6) + D7 (09) D7 (14) (DataBit7) + INIT (16) EN2 (15) (Enable Right) + RESET (16) +5V (Controller Reset) + LED+ (17) +4V/150mA (Backlight with 6,4Ohm Resistor to +5V) + nAUTO (14) LED- (18) GND (Backlight GND [via BS170]) + + See also http://www.usblcd.de/lcdproc/sed1520-dip.php4 ... + +Note: The pin numbering may vary with other displays. + + +Configuration Parameters +------------------------ +The SED1520 driver supports the following parameters in config file: + +Device + Instead of using the direct output via port address (see Port), you + can use the parport device (/dev/parportX). The advantage over the + direct output via port address is that this works for non-root users + also. But it's a little bit slower. The modules ppdev.o, parport.o + and parport_pc.o must be loaded or compiled into the kernel. + +Port + Sets the port address of the parallel port. If this parameter is not + given, 0x378 is used. To use this direct output, the program that + uses the driver library has to be started with user 'root'. + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 120 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 32 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +AdjustTiming + To get a timing that is as accurate as possible, the drivers measure + the time for port commands (see: benchmark in syslog). You might + decrease or increase the time to wait after port commands with this + parameter. Normally, there is no need to change this parameter. + Possible values: -50 <= x <= 50 + Default value: 0 + +RefreshDisplay + Normally, most of the drivers do not update the whole display, but + only the areas that have changed since last update. So it might be, + that some faulty pixels would stay a longer time. To avoid this, the + plugin makes a complete refresh from time to time. This parameter + defines how often a complete refresh will be done. + e.g.: A value of 5 means, that the plugin will make a complete + refresh on every 5th update. + A value of 0 completely disables complete refreshs. + Possible values: 0 <= x <= 50 + Default value: 5 + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.serdisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.serdisp Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,61 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The serdisp driver +--------------------------------------------------------------------- + +Description +----------- +The serdisp driver supports LC displays that are supported by +serdisplib (http://serdisplib.sourceforge.net). + + +Configuration Parameters +------------------------ +The serdisp driver supports the following parameters in config file: + +Controller + Select the controller your LCD uses named like in serdisplib. + Possible values: See README in serdisplib package + +Device + Instead of using the direct output via port address (see Port), you + can use the parport device (/dev/parportX). The advantage over the + direct output via port address is that this works for non-root users + also. But it's a little bit slower. The modules ppdev.o, parport.o + and parport_pc.o must be loaded or compiled into the kernel. + +Port + Sets the port address of the parallel port. If this parameter is not + given, 0x378 is used. To use this direct output, the program that + uses the driver library has to be started with user 'root'. + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value according to the selected controller is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value according to the selected controller is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +Contrast + Sets the contrast of your display. + Possible values: 0 <= x <= 10 + Default value: 5 + +Backlight + Switches the backlight of your display on and off. + Possible values: 'yes', 'no' + Default value: 'yes' + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.simlcd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.simlcd Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,36 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The SimLCD driver +--------------------------------------------------------------------- + +Description +----------- +The Image driver writes a file including the output that you would +normally see on a LCD e.g. from the graphlcd plugin. You can use the +SimLCD tool to view this file. + + +Configuration Parameters +------------------------ +The SimLCD driver supports the following parameters in config file: + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 240 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 128 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/DRIVER.t6963c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/DRIVER.t6963c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,159 @@ +--------------------------------------------------------------------- +GraphLCD driver library + +The T6963C driver +--------------------------------------------------------------------- + +Description +----------- +The T6963C driver supports LC displays that use the Toshiba T6963C +controller, connected to the parallel port of your PC. + + +Wirings +------- +The T6963C driver supports the following connections on a parallel +port: + - Standard (used by LCDproc) + - Windows (used by many windows programs) + +Standard wiring: + + printerport LCD other + ----------- ---------- ---------- + GND (18) GND (01) GND (Ground) + nSTRB (01) WR (06) (Write) + nAUTO (14) CE (15) (Chip Enable) + INIT (16) C/D (04) (Command/Data) + nSEL (17) RD (05) (Read) + D0 (02) D0 (07) (Data Bit 0) + D1 (03) D1 (08) (Data Bit 1) + D2 (04) D2 (09) (Data Bit 2) + D3 (05) D3 (10) (Data Bit 3) + D4 (06) D4 (11) (Data Bit 4) + D5 (07) D5 (12) (Data Bit 5) + D6 (08) D6 (13) (Data Bit 6) + D7 (09) D7 (14) (Data Bit 7) + +Windows wiring: + + printerport LCD other + ----------- ---------- ---------- + GND (18) GND (01) GND (Ground) + nSTRB (01) CE (15) (Chip Enable) + nAUTO (14) RD (05) (Read) + INIT (16) WR (06) (Write) + nSEL (17) C/D (04) (Command/Data) + D0 (02) D0 (07) (Data Bit 0) + D1 (03) D1 (08) (Data Bit 1) + D2 (04) D2 (09) (Data Bit 2) + D3 (05) D3 (10) (Data Bit 3) + D4 (06) D4 (11) (Data Bit 4) + D5 (07) D5 (12) (Data Bit 5) + D6 (08) D6 (13) (Data Bit 6) + D7 (09) D7 (14) (Data Bit 7) + +Serial wiring using a industry version with a serial to parallel +converter: + + printerport LCD + ----------- ---------- + nAuto (14) nCE (03) + nSTRB (01) nSCK (07) + INIT (16) nC/D (08) + INIT (16) nSDAT (08) + GND (25) GND (01) + + +Note: The pin numbering may vary with other displays. + +The LCD must operate in the 6x8 or 8x8 font mode. Usually, there is a +pin to choose 6x8 or 8x8 font mode. + +There are Displays that have a pin to select the number of characters +per line. In that case, you have to select (width (in pixels) / 6) or +(width (in pixels) / 8) characters per line. + +Attention: You have to tie these pins to +5V or GND. Don't leave them +open circuit or you will get unpredictable results. + +Because the T6963 driver reads the status of the display, it might be +neccessary to enable the bidirectional mode in the BIOS and to enable +bidirectional mode in the Linux kernel: + <*> Parallel port support + <*> PC-style hardware + [*] IEEE 1284 transfer modes + + +Configuration Parameters +------------------------ +The T6963C driver supports the following parameters in config file: + +Device + Instead of using the direct output via port address (see Port), you + can use the parport device (/dev/parportX). The advantage over the + direct output via port address is that this works for non-root users + also. But it's a little bit slower. The modules ppdev.o, parport.o + and parport_pc.o must be loaded or compiled into the kernel. + +Port + Sets the port address of the parallel port. If this parameter is not + given, 0x378 is used. To use this direct output, the program that + uses the driver library has to be started with user 'root'. + +Width + Sets the horizontal size of the display. If this parameter is not + given, a default value of 240 pixels is used. + +Height + Sets the vertical size of the display. If this parameter is not + given, a default value of 128 pixels is used. + +UpsideDown + Rotates the display output by 180 degrees. This might be useful, if + the LCD is mounted upside-down. + Possible values: 'yes', 'no' + Default value: 'no' + +Invert + Inverts the display. + Possible values: 'yes', 'no' + Default value: 'no' + +RefreshDisplay + Normally, most of the drivers do not update the whole display, but + only the areas that have changed since last update. So it might be, + that some faulty pixels would stay a longer time. To avoid this, the + plugin makes a complete refresh from time to time. This parameter + defines how often a complete refresh will be done. + e.g.: A value of 5 means, that the plugin will make a complete + refresh on every 5th update. + A value of 0 completely disables complete refreshs. + Possible values: 0 <= x <= 50 + Default value: 5 + +Wiring + Select the type of wiring your display is connected with. + Possible values: 'Standard', 'Windows' + Default value: 'Standard' + +FontSelect + Select the font width your display uses for text mode. In most cases + this is selectable through one of the pins of your LCD board + Possible values: '6', '8' + Default value: '6' + +AutoMode + Enables or disables the usage of T6963C's auto mode which doubles + writing speed when enabled. + Possible values: 'yes', 'no' + Default value: 'yes' + +StatusCheck + Enables or disables the usage of T6963C's status check. When using a + shielded cable for connecting your display, the disabling may be + possible. This results in doubling the speed of writing data to the + LCD. + Possible values: 'yes', 'no' + Default value: 'yes' + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/README.convpic --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/README.convpic Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,42 @@ +This is the README of the crtfont tool, which is part of the GraphLCD +base package. + +written by Carsten Siebholz + Andreas Brachold + +See the file COPYING for license information. + + +Description: +------------ +convpic is a program to convert images to an own simple format (*.glcd) +that is used by the GraphLCD graphics library. + + +Installation and Configuration: +------------------------------- +see the file README in the base package's root directory. + + +Using convpic: +-------------- +Usage: convpic [-n] [-d x] -i infile [more files] -o outfile + + -n --invert inverts the output (default: no) + -i --infile specifies the name of the input file + -o --outfile specifies the name of the output file + -d --delay specifies the delay delay between multiple images + +supported formats: + TIFF: file is an uncompressed RGB-encoded 2-color TIFF + BMP : file is an uncompressed RGB-encoded 2-color Windows BMP + ANI : file is an uncompressed multi-frame from tuxbox-aniplay + GLCD: file is the own format used by the GraphLCD graphics library + +example: convpic -i vdr-logo.bmp -o vdr-logo.glcd + + +Known Problems: +--------------- + Export of TIFF isn't supported. + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/README.crtfont --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/README.crtfont Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,61 @@ +This is the README of the crtfont tool, which is part of the GraphLCD +base package. + +written by Andreas Regel (andreas.regel AT powarman.de) + +based on crtfont from the graphlcd plugin for the Video Disc Recorder +written by Carsten Siebholz (c.siebholz AT t-online.de) + +See the file COPYING for license information. + + +Description: +------------ +crtfont is a program to create fonts for the GraphLCD graphics library. + + +Installation and Configuration: +------------------------------- +see the file README in the base package's root directory. + + +Using crtfont: +-------------- +To create a font, 2 source files are required: +- an image, that contains the characters as a bitmap. This image might + be in: + - Portable Bit Map (PBM) format. +- a description file (*.desc), that contains informations about the + positions of each character in the image. + The format of the description file: + - The first line contains the version of the description file format: + version:1 + - The next lines contain the font attributes in the format + :, one attribute per line. Possible attributes + are: + fontheight: the total height of the font + fontascent: the vertical distance from the horizontal baseline to + the highest character coordinate. + lineheight: the baseline-to-baseline distance + spacebetween: additional space between characters in a text + spacewidth: the width of the space character. If this value is + greater than zero, all characters will be compressed + horizontally to their active pixels. + - All other lines define the characters and their positions in the + image. The syntax is like: + PosX_1 Char_1 PosX_2 Char_2 PosX_3 ... PosX_n Char_n EndX + where PosX_x specifies the horizontal position of the leftmost + pixel of the character. Char_x might be the character itself + (A, B, ...) or it's decimal ASCII value (65, 66, ...) + +Usage: crtfont -f -b -d -o + + -f --format specifies the format of the bitmap. Possible values + are: + PBM: file is an Portable Bit Map + -b --bmpfile specifies the name of the bitmap file (*.pbm) + -d --descfile specifies the name of the description file (*.desc) + -o --outfile specifies the name of the output file (*.fnt) + + example: crtfont -f PBM -b f12.pbm -d f12.desc -o f12.fnt + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/README.showpic --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/README.showpic Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,38 @@ +This is the README of the showpic tool, which is part of the GraphLCD +base package. + +written by Andreas Regel (andreas.regel AT powarman.de) + +based on showpic from the graphlcd plugin for the Video Disc Recorder +written by Carsten Siebholz (c.siebholz AT t-online.de) + +See the file COPYING for license information. + + +Description: +------------ +showpic is a program to show an image on a graphical LC Display. It +support all controller the GraphLCD driver library supports. + +The images must be in an own format (*.glcd), which can be created with +the convpic tool. + + +Using showpic: +-------------- + showpic [-c CONFIGFILE] [-d DISPLAY] [-s SLEEP] [-uie] file [more files] + + -c --config specifies the location of the config file + (default: /etc/graphlcd.conf) + -d --display specifies the output display + (default: the first one in config file) + -u --upsidedown rotates the output by 180 degrees (default: no) + -i --invert inverts the output (default: no) + -e --endless show all images in endless loop (default: no) + -s --sleep set sleeptime between two images [ms] + -b --brightness set brightness for display if driver support it + (default: config file value) + +examples: showpic -c /etc/graphlcd.conf vdr-logo.glcd + showpic -c /etc/graphlcd.conf -d LCD_T6963 -u -i vdr-logo.glcd + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/docs/README.showtext --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/docs/README.showtext Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,35 @@ +This is the README of the showtext tool, which is part of the GraphLCD +base package. + +written by Andreas Regel (andreas.regel AT powarman.de) + +See the file COPYING for license information. + + +Description: +------------ +showtext is a program to show a user defined text with a user defined +font on a graphical LC Display. It supports all controllers the GraphLCD +driver library supports. + +The font must be in a special format (*.fnt), which can be created with +the crtfont tool. + + +Using showtext: +-------------- + showtext [-c CONFIGFILE] [-d DISPLAY] [-f FONT] [-x XPOS] [-y YPOS] [-uib] text [more text] + + -c --config specifies the location of the config file + (default: /etc/graphlcd.conf) + -d --display specifies the output display + (default: the first one in config file) + -f --font specifies the font that is used for the text output + -x --xpos specifies the x-position where the text starts + -y --ypos specifies the y-position where the text starts + -u --upsidedown rotates the output by 180 degrees (default: no) + -i --invert inverts the output (default: no) + -b --brightness set brightness for display if driver support it [%] + (default: config file value) + + example: showtext -c /etc/graphlcd.conf -f f17.fnt "Line1" "Line2" diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/Makefile Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,60 @@ +# +# Makefile for the GraphLCD driver library +# + +-include ../Make.config + +CXXFLAGS += -fPIC + +VERMAJOR = 1 +VERMINOR = 0 +VERMICRO = 0 + +BASENAME = libglcddrivers.so + +LIBNAME = $(BASENAME).$(VERMAJOR).$(VERMINOR).$(VERMICRO) + +OBJS = common.o config.o driver.o drivers.o port.o simlcd.o framebuffer.o gu140x32f.o gu256x64-372.o gu256x64-3900.o hd61830.o ks0108.o image.o sed1330.o sed1520.o t6963c.o noritake800.o serdisp.o avrctl.o g15daemon.o network.o gu126x64D-K610A4.o + +HEADERS = config.h driver.h drivers.h + + +### 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: $(LIBNAME) + +$(LIBNAME): $(OBJS) + $(CXX) $(CXXFLAGS) -shared $(OBJS) $(LIBS) -ldl -lpthread -Wl,-soname="$(BASENAME).$(VERMAJOR)" -o $@ + ln -sf $(LIBNAME) $(BASENAME) + +install: all + install -d $(LIBDIR) + install -m 755 $(LIBNAME) $(LIBDIR)/ + install -d $(INCDIR)/glcddrivers + install -m 644 $(HEADERS) $(INCDIR)/glcddrivers/ + ( cd $(LIBDIR); ln -sf $(LIBNAME) $(BASENAME).$(VERMAJOR); ln -sf $(LIBNAME) $(BASENAME) ) + +uninstall: + rm -f $(LIBDIR)/$(BASENAME) + rm -f $(LIBDIR)/$(BASENAME).$(VERMAJOR) + rm -f $(LIBDIR)/$(LIBNAME) + (for i in $(HEADERS); do rm -f $(INCDIR)/glcddrivers/$$i; done) + rmdir $(INCDIR)/glcddrivers + +clean: + rm -f $(OBJS) $(DEPFILE) $(LIBNAME) $(BASENAME) *~ + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/avrctl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/avrctl.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,355 @@ +/* + * GraphLCD driver library + * + * avrctl.c - AVR controlled LCD driver class + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2005 Andreas Regel + */ + +#include +#include + +#include "common.h" +#include "config.h" +#include "port.h" +#include "avrctl.h" + + +namespace GLCD +{ + +/* command header: +** 8 bits sync byte (0xAA for sent commands, 0x55 for received commands) +** 8 bits command id +** 16 bits command length (excluding header) +*/ +const unsigned char CMD_HDR_SYNC = 0; +const unsigned char CMD_HDR_COMMAND = 1; +const unsigned char CMD_HDR_LENGTH = 2; +const unsigned char CMD_DATA_START = 4; + +const unsigned char CMD_SYNC_SEND = 0xAA; +const unsigned char CMD_SYNC_RECV = 0x55; + +const unsigned char CMD_SYS_SYNC = 0x00; +const unsigned char CMD_SYS_ACK = 0x01; + +const unsigned char CMD_DISP_CLEAR_SCREEN = 0x10; +const unsigned char CMD_DISP_SWITCH_SCREEN = 0x11; +const unsigned char CMD_DISP_SET_BRIGHTNESS = 0x12; +const unsigned char CMD_DISP_SET_COL_DATA = 0x13; +const unsigned char CMD_DISP_SET_ROW_DATA = 0x14; +const unsigned char CMD_DISP_UPDATE = 0x15; + +const int kBufferWidth = 256; +const int kBufferHeight = 128; + + +cDriverAvrCtl::cDriverAvrCtl(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); + + port = new cSerialPort(); + + //width = config->width; + //height = config->height; + refreshCounter = 0; +} + +cDriverAvrCtl::~cDriverAvrCtl() +{ + delete port; + delete oldConfig; +} + +int cDriverAvrCtl::Init() +{ + int x; + + width = config->width; + if (width <= 0) + width = 256; + height = config->height; + if (height <= 0) + height = 128; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "") + { + } + } + + // setup lcd array (wanted state) + newLCD = new unsigned char*[kBufferWidth]; + if (newLCD) + { + for (x = 0; x < kBufferWidth; x++) + { + newLCD[x] = new unsigned char[(kBufferHeight + 7) / 8]; + memset(newLCD[x], 0, (kBufferHeight + 7) / 8); + } + } + // setup lcd array (current state) + oldLCD = new unsigned char*[kBufferWidth]; + if (oldLCD) + { + for (x = 0; x < kBufferWidth; x++) + { + oldLCD[x] = new unsigned char[(kBufferHeight + 7) / 8]; + memset(oldLCD[x], 0, (kBufferHeight + 7) / 8); + } + } + + if (config->device == "") + { + return -1; + } + if (port->Open(config->device.c_str()) != 0) + return -1; + + *oldConfig = *config; + + // clear display + Clear(); + + syslog(LOG_INFO, "%s: AvrCtl initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverAvrCtl::DeInit() +{ + int x; + // free lcd array (wanted state) + if (newLCD) + { + for (x = 0; x < kBufferWidth; x++) + { + delete[] newLCD[x]; + } + delete[] newLCD; + } + // free lcd array (current state) + if (oldLCD) + { + for (x = 0; x < kBufferWidth; x++) + { + delete[] oldLCD[x]; + } + delete[] oldLCD; + } + + if (port->Close() != 0) + return -1; + return 0; +} + +int cDriverAvrCtl::CheckSetup() +{ + if (config->device != oldConfig->device || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +void cDriverAvrCtl::Clear() +{ + for (int x = 0; x < kBufferWidth; x++) + memset(newLCD[x], 0, (kBufferHeight + 7) / 8); +} + +void cDriverAvrCtl::Set8Pixels(int x, int y, unsigned char data) +{ + if (x >= width || y >= height) + return; + + if (!config->upsideDown) + { + int offset = 7 - (y % 8); + for (int i = 0; i < 8; i++) + { + newLCD[x + i][y / 8] |= ((data >> (7 - i)) << offset) & (1 << offset); + } + } + else + { + x = width - 1 - x; + y = height - 1 - y; + int offset = 7 - (y % 8); + for (int i = 0; i < 8; i++) + { + newLCD[x - i][y / 8] |= ((data >> (7 - i)) << offset) & (1 << offset); + } + } +} + +void cDriverAvrCtl::Refresh(bool refreshAll) +{ + int x; + int y; + int i; + int num = kBufferWidth / 2; + unsigned char data[16*num]; + + if (CheckSetup() == 1) + refreshAll = true; + + if (config->refreshDisplay > 0) + { + refreshCounter = (refreshCounter + 1) % config->refreshDisplay; + if (!refreshAll && !refreshCounter) + refreshAll = true; + } + + refreshAll = true; + if (refreshAll) + { + for (x = 0; x < kBufferWidth; x += num) + { + for (i = 0; i < num; i++) + { + for (y = 0; y < (kBufferHeight + 7) / 8; y++) + { + data[i * ((kBufferHeight + 7) / 8) + y] = (newLCD[x + i][y]) ^ (config->invert ? 0xff : 0x00); + } + memcpy(oldLCD[x + i], newLCD[x + i], (kBufferHeight + 7) / 8); + } + CmdDispSetColData(x, 0, 16 * num, data); + } + CmdDispUpdate(); + CmdDispSwitchScreen(); + // and reset RefreshCounter + refreshCounter = 0; + } + else + { + // draw only the changed bytes + } +} + +void cDriverAvrCtl::SetBrightness(unsigned int percent) +{ + CmdDispSetBrightness(percent); +} + +int cDriverAvrCtl::WaitForAck(void) +{ + uint8_t cmd[4]; + int len; + int timeout = 10000; + + len = 0; + while (len < 4 && timeout > 0) + { + len += port->ReadData(&cmd[len]); + timeout--; + } + if (timeout == 0) + return 0; + return 1; +} + +void cDriverAvrCtl::CmdSysSync(void) +{ + uint8_t cmd[4]; + + cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND; + cmd[CMD_HDR_COMMAND] = CMD_SYS_SYNC; + cmd[CMD_HDR_LENGTH] = 0; + cmd[CMD_HDR_LENGTH+1] = 0; + + port->WriteData(cmd, 4); + WaitForAck(); +} + +void cDriverAvrCtl::CmdDispClearScreen(void) +{ + uint8_t cmd[4]; + + cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND; + cmd[CMD_HDR_COMMAND] = CMD_DISP_CLEAR_SCREEN; + cmd[CMD_HDR_LENGTH] = 0; + cmd[CMD_HDR_LENGTH+1] = 0; + + port->WriteData(cmd, 4); + WaitForAck(); +} + +void cDriverAvrCtl::CmdDispSwitchScreen(void) +{ + uint8_t cmd[4]; + + cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND; + cmd[CMD_HDR_COMMAND] = CMD_DISP_SWITCH_SCREEN; + cmd[CMD_HDR_LENGTH] = 0; + cmd[CMD_HDR_LENGTH+1] = 0; + + port->WriteData(cmd, 4); + WaitForAck(); +} + +void cDriverAvrCtl::CmdDispSetBrightness(uint8_t percent) +{ + uint8_t cmd[5]; + + cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND; + cmd[CMD_HDR_COMMAND] = CMD_DISP_SET_BRIGHTNESS; + cmd[CMD_HDR_LENGTH] = 0; + cmd[CMD_HDR_LENGTH+1] = 1; + cmd[CMD_DATA_START] = percent; + + port->WriteData(cmd, 5); + WaitForAck(); +} + +void cDriverAvrCtl::CmdDispSetColData(uint16_t column, uint16_t offset, uint16_t length, uint8_t * data) +{ + uint8_t cmd[2560]; + + cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND; + cmd[CMD_HDR_COMMAND] = CMD_DISP_SET_COL_DATA; + cmd[CMD_HDR_LENGTH] = (length + 6) >> 8; + cmd[CMD_HDR_LENGTH+1] = (length + 6); + cmd[CMD_DATA_START] = column >> 8; + cmd[CMD_DATA_START+1] = column; + cmd[CMD_DATA_START+2] = offset >> 8; + cmd[CMD_DATA_START+3] = offset; + cmd[CMD_DATA_START+4] = length >> 8; + cmd[CMD_DATA_START+5] = length; + memcpy(&cmd[CMD_DATA_START+6], data, length); + + port->WriteData(cmd, length+10); + WaitForAck(); +} + +void cDriverAvrCtl::CmdDispUpdate(void) +{ + uint8_t cmd[4]; + + cmd[CMD_HDR_SYNC] = CMD_SYNC_SEND; + cmd[CMD_HDR_COMMAND] = CMD_DISP_UPDATE; + cmd[CMD_HDR_LENGTH] = 0; + cmd[CMD_HDR_LENGTH+1] = 0; + + port->WriteData(cmd, 4); + WaitForAck(); +} + +} diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/avrctl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/avrctl.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,58 @@ +/* + * GraphLCD driver library + * + * avrctl.h - AVR controlled LCD driver class + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2005 Andreas Regel + */ + +#ifndef _GLCDDRIVERS_AVRCTL_H_ +#define _GLCDDRIVERS_AVRCTL_H_ + +#include "driver.h" + +namespace GLCD +{ + +class cDriverConfig; +class cSerialPort; + +class cDriverAvrCtl : public cDriver +{ +private: + cSerialPort * port; + unsigned char ** newLCD; // wanted state + unsigned char ** oldLCD; // current state + cDriverConfig * config; + cDriverConfig * oldConfig; + int refreshCounter; + + int WaitForAck(void); + void CmdSysSync(void); + void CmdDispClearScreen(void); + void CmdDispSwitchScreen(void); + void CmdDispSetBrightness(unsigned char percent); + void CmdDispSetColData(uint16_t column, uint16_t offset, uint16_t length, uint8_t * data); + void CmdDispUpdate(void); + + int CheckSetup(); + +public: + cDriverAvrCtl(cDriverConfig * config); + virtual ~cDriverAvrCtl(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); + virtual void SetBrightness(unsigned int percent); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/common.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/common.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,231 @@ +/* + * GraphLCD driver library + * + * common.c - various functions + * + * parts were taken from graphlcd plugin for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "config.h" + + +namespace GLCD +{ + +static const int BitReverseTable[256] = +{ + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +int nSleepInit() +{ + int ret = 0; + + if (Config.waitPriority != 0) + { + ret = setpriority(PRIO_PROCESS, 0, Config.waitPriority); + } + + if (!ret) + { + switch (Config.waitMethod) + { + case kWaitUsleep: // usleep + break; + case kWaitNanosleep: // nanosleep + break; + case kWaitNanosleepRR: // nanosleep (sched_rr) + // set sched algorithm + struct sched_param param; + + param.sched_priority=1; + ret = sched_setscheduler(0, SCHED_RR, ¶m); + break; + case kWaitGettimeofday: // gettimeofday + break; + } + } + return ret; +} + +int nSleepDeInit() +{ + int ret = 0; + + if (Config.waitPriority != 0) + { + ret = setpriority(PRIO_PROCESS, 0, 0); + } + + if (!ret) + { + switch (Config.waitMethod) + { + case kWaitUsleep: // usleep + break; + case kWaitNanosleep: // nanosleep + break; + case kWaitNanosleepRR: // nanosleep (sched_rr) + // set sched algorithm + struct sched_param param; + + param.sched_priority=0; + ret = sched_setscheduler(0, SCHED_OTHER, ¶m); + break; + case kWaitGettimeofday: // gettimeofday + break; + } + } + return ret; +} + +void nSleep(long ns) +{ + switch (Config.waitMethod) + { + case kWaitUsleep: // usleep + if (ns > 0) + { + usleep(std::max(1L, ns/1000)); + } + break; + case kWaitNanosleep: // nanosleep + case kWaitNanosleepRR: // nanosleep(sched_rr) + struct timespec delay, remaining; + if (ns > 0) + { + delay.tv_sec = ns/1000000000; + delay.tv_nsec = ns%1000000000; + while (nanosleep(&delay, &remaining) == -1) + { + delay.tv_sec = remaining.tv_sec; + delay.tv_nsec = remaining.tv_nsec; + } + } + break; + case kWaitGettimeofday: //getTimeofday for Kernel 2.6 + long us; + struct timeval tv1, tv2; + suseconds_t us2; + if (ns > 0) + { + us = ns / 1000; + if (us == 0) + us = 1; + gettimeofday(&tv1, 0); + do + { + gettimeofday(&tv2, 0); + us2 = tv2.tv_usec + ((tv2.tv_sec - tv1.tv_sec) * 1000000); + } while (us2 - tv1.tv_usec < us); + } + } +} + +void uSleep(long us) +{ + if (Config.waitMethod == kWaitUsleep) + { + // usleep + if (us > 0) + usleep(std::max(1L, us)); + } + else + { + nSleep(us * 1000); + } +} + + + +unsigned char ReverseBits(unsigned char value) +{ + return BitReverseTable[value]; +} + +void clip(int & value, int min, int max) +{ + if (value < min) + value = min; + if (value > max) + value = max; +} + +void sort(int & value1, int & value2) +{ + if (value2 < value1) + { + int tmp; + tmp = value2; + value2 = value1; + value1 = tmp; + } +} + +std::string trim(const std::string & s) +{ + std::string::size_type start, end; + + start = 0; + while (start < s.length()) + { + if (!isspace(s[start])) + break; + start++; + } + end = s.length() - 1; + while (end >= 0) + { + if (!isspace(s[end])) + break; + end--; + } + return s.substr(start, end - start + 1); +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/common.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/common.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,42 @@ +/* + * GraphLCD driver library + * + * common.c - various functions + * + * parts were taken from graphlcd plugin for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDDRIVERS_COMMON_H_ +#define _GLCDDRIVERS_COMMON_H_ + +#include + +namespace GLCD +{ + +const unsigned char bitmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; +const unsigned char bitmaskl[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; +const unsigned char bitmaskr[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01}; + +// functions to enable/disable very short sleeps. +// Therefore, the priority will be changed. => use with care ! +int nSleepInit(void); +int nSleepDeInit(void); + +void nSleep(long ns); +void uSleep(long us); + +unsigned char ReverseBits(unsigned char value); +void clip(int & value, int min, int max); +void sort(int & value1, int & value2); +std::string trim(const std::string & s); + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/config.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/config.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,286 @@ +/* + * GraphLCD driver library + * + * config.c - config file classes + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include + +#include "common.h" +#include "config.h" +#include "drivers.h" + + +namespace GLCD +{ + +cDriverConfig::cDriverConfig() +: name(""), + driver(""), + id(kDriverUnknown), + device(""), + port(0), + width(0), + height(0), + upsideDown(false), + invert(false), + brightness(100), + contrast(5), + backlight(true), + adjustTiming(0), + refreshDisplay(5) +{ +} + +cDriverConfig::cDriverConfig(const cDriverConfig & rhs) +{ + name = rhs.name; + driver = rhs.driver; + id = rhs.id; + device = rhs.device; + port = rhs.port; + width = rhs.width; + height = rhs.height; + upsideDown = rhs.upsideDown; + invert = rhs.invert; + brightness = rhs.brightness; + contrast = rhs.contrast; + backlight = rhs.backlight; + adjustTiming = rhs.adjustTiming; + refreshDisplay = rhs.refreshDisplay; + for (unsigned int i = 0; i < rhs.options.size(); i++) + options.push_back(rhs.options[i]); +} + +cDriverConfig::~cDriverConfig() +{ +} + +cDriverConfig & cDriverConfig::operator=(const cDriverConfig & rhs) +{ + if (this == &rhs) + return *this; + + name = rhs.name; + driver = rhs.driver; + id = rhs.id; + device = rhs.device; + port = rhs.port; + width = rhs.width; + height = rhs.height; + upsideDown = rhs.upsideDown; + invert = rhs.invert; + brightness = rhs.brightness; + contrast = rhs.contrast; + backlight = rhs.backlight; + adjustTiming = rhs.adjustTiming; + refreshDisplay = rhs.refreshDisplay; + options.clear(); + for (unsigned int i = 0; i < rhs.options.size(); i++) + options.push_back(rhs.options[i]); + + return *this; +} + +bool cDriverConfig::Parse(const std::string & line) +{ + std::string::size_type pos; + tOption option; + + pos = line.find("="); + if (pos == std::string::npos) + return false; + option.name = trim(line.substr(0, pos)); + option.value = trim(line.substr(pos + 1)); + //printf("D %s = %s\n", option.name.c_str(), option.value.c_str()); + + if (option.name == "Driver") + { + int driverCount; + tDriver * drivers = GetAvailableDrivers(driverCount); + for (int i = 0; i < driverCount; i++) + { + if (option.value == drivers[i].name) + { + driver = drivers[i].name; + id = drivers[i].id; + break; + } + } + } + else if (option.name == "Device") + { + device = option.value; + } + else if (option.name == "Port") + { + port = GetInt(option.value); + } + else if (option.name == "Width") + { + width = GetInt(option.value); + } + else if (option.name == "Height") + { + height = GetInt(option.value); + } + else if (option.name == "UpsideDown") + { + upsideDown = GetBool(option.value); + } + else if (option.name == "Invert") + { + invert = GetBool(option.value); + } + else if (option.name == "Brightness") + { + brightness = GetInt(option.value); + } + else if (option.name == "Contrast") + { + contrast = GetInt(option.value); + } + else if (option.name == "Backlight") + { + backlight = GetBool(option.value); + } + else if (option.name == "AdjustTiming") + { + adjustTiming = GetInt(option.value); + } + else if (option.name == "RefreshDisplay") + { + refreshDisplay = GetInt(option.value); + } + else + { + options.push_back(option); + } + return true; +} + +int cDriverConfig::GetInt(const std::string & value) +{ + return strtol(value.c_str(), NULL, 0); +} + +bool cDriverConfig::GetBool(const std::string & value) +{ + return value == "yes"; +} + + +cConfig::cConfig() +: waitMethod(kWaitGettimeofday), + waitPriority(0) +{ +} + +cConfig::~cConfig() +{ +} + +bool cConfig::Load(const std::string & filename) +{ + std::fstream file; + char readLine[1000]; + std::string line; + bool inSections = false; + int section = 0; + +#if (__GNUC__ < 3) + file.open(filename.c_str(), std::ios::in); +#else + file.open(filename.c_str(), std::ios_base::in); +#endif + if (!file.is_open()) + return false; + + while (!file.eof()) + { + file.getline(readLine, 1000); + line = trim(readLine); + if (line.length() == 0) + continue; + if (line[0] == '#') + continue; + if (line[0] == '[' && line[line.length() - 1] == ']') + { + if (!inSections) + inSections = true; + else + section++; + driverConfigs.resize(section + 1); + driverConfigs[section].name = line.substr(1, line.length() - 2); + continue; + } + if (!inSections) + { + Parse(line); + } + else + { + driverConfigs[section].Parse(line); + } + } + + file.close(); + return true; +} + +bool cConfig::Parse(const std::string & line) +{ + std::string::size_type pos; + tOption option; + + pos = line.find("="); + if (pos == std::string::npos) + return false; + option.name = trim(line.substr(0, pos)); + option.value = trim(line.substr(pos + 1)); + //printf("%s = %s\n", option.name.c_str(), option.value.c_str()); + + if (option.name == "WaitMethod") + { + waitMethod = GetInt(option.value); + } + else if (option.name == "WaitPriority") + { + waitPriority = GetInt(option.value); + } + else + { + syslog(LOG_ERR, "Config error: unknown option %s given!\n", option.value.c_str()); + return false; + } + return true; +} + +int cConfig::GetInt(const std::string & value) +{ + return strtol(value.c_str(), NULL, 0); +} + +bool cConfig::GetBool(const std::string & value) +{ + return value == "yes"; +} + +int cConfig::GetConfigIndex(const std::string & name) +{ + for (int i = 0; i < (int)driverConfigs.size(); i++) + if (driverConfigs[i].name == name) + return i; + syslog(LOG_ERR, "Config error: configuration %s not found!\n", name.c_str()); + return -1; +} + +cConfig Config; + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/config.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,85 @@ +/* + * GraphLCD driver library + * + * config.h - config file classes + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDDRIVERS_CONFIG_H_ +#define _GLCDDRIVERS_CONFIG_H_ + +#include +#include + + +namespace GLCD +{ + +const int kWaitUsleep = 0; +const int kWaitNanosleep = 1; +const int kWaitNanosleepRR = 2; +const int kWaitGettimeofday = 3; + + +struct tOption +{ + std::string name; + std::string value; +}; + +class cDriverConfig +{ +public: + std::string name; + std::string driver; + int id; + std::string device; + int port; + int width; + int height; + bool upsideDown; + bool invert; + int brightness; + int contrast; + bool backlight; + int adjustTiming; + int refreshDisplay; + std::vector options; + +public: + cDriverConfig(); + cDriverConfig(const cDriverConfig & rhs); + ~cDriverConfig(); + cDriverConfig & operator=(const cDriverConfig & rhs); + bool Parse(const std::string & line); + int GetInt(const std::string & value); + bool GetBool(const std::string & value); +}; + +class cConfig +{ +public: + int waitMethod; + int waitPriority; + std::vector driverConfigs; + +public: + cConfig(); + ~cConfig(); + bool Load(const std::string & filename); + bool Save(const std::string & filename); + bool Parse(const std::string & line); + int GetInt(const std::string & value); + bool GetBool(const std::string & value); + int GetConfigIndex(const std::string & name); +}; + +extern cConfig Config; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/driver.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/driver.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,54 @@ +/* + * GraphLCD driver library + * + * driver.c - driver base class + * + * parts were taken from graphlcd plugin for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include "common.h" +#include "driver.h" + + +namespace GLCD +{ + +cDriver::cDriver() +: width(0), + height(0) +{ +} + +void cDriver::SetScreen(const unsigned char * data, int wid, int hgt, int lineSize) +{ + int x, y; + + if (wid > width) + wid = width; + if (hgt > height) + hgt = height; + + Clear(); + if (data) + { + for (y = 0; y < hgt; y++) + { + for (x = 0; x < (wid / 8); x++) + { + Set8Pixels(x * 8, y, data[y * lineSize + x]); + } + if (width % 8) + { + Set8Pixels((wid / 8) * 8, y, data[y * lineSize + wid / 8] & bitmaskl[wid % 8 - 1]); + } + } + } +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/driver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/driver.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,48 @@ +/* + * GraphLCD driver library + * + * driver.h - driver base class + * + * parts were taken from graphlcd plugin for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDDRIVERS_DRIVER_H_ +#define _GLCDDRIVERS_DRIVER_H_ + +#include + +namespace GLCD +{ + +class cDriver +{ +protected: + int width; + int height; +public: + cDriver(); + virtual ~cDriver() {} + + int Width() const { return width; } + int Height() const { return height; } + + virtual int Init() { return 0; } + virtual int DeInit() { return 0; } + + virtual void Clear() {} + virtual void Set8Pixels(int x, int y, unsigned char data) {} + virtual void SetScreen(const unsigned char * data, int width, int height, int lineSize); + virtual void Refresh(bool refreshAll = false) {} + + virtual void SetBrightness(unsigned int percent) {} +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/drivers.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/drivers.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,117 @@ +/* + * GraphLCD driver library + * + * drivers.c - global driver constants and functions + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include + +#include "drivers.h" +#include "simlcd.h" +#include "gu140x32f.h" +#include "gu256x64-372.h" +#include "gu256x64-3900.h" +#include "hd61830.h" +#include "ks0108.h" +#include "sed1330.h" +#include "sed1520.h" +#include "t6963c.h" +#include "framebuffer.h" +#include "image.h" +#include "noritake800.h" +#include "avrctl.h" +#include "network.h" +#include "gu126x64D-K610A4.h" +#include "serdisp.h" +#include "g15daemon.h" + +namespace GLCD +{ + +tDriver drivers[] = +{ + {"simlcd", kDriverSimLCD}, + {"gu140x32f", kDriverGU140X32F}, + {"gu256x64-372", kDriverGU256X64_372}, + {"gu256x64-3900", kDriverGU256X64_3900}, + {"hd61830", kDriverHD61830}, + {"ks0108", kDriverKS0108}, + {"sed1330", kDriverSED1330}, + {"sed1520", kDriverSED1520}, + {"t6963c", kDriverT6963C}, + {"framebuffer", kDriverFramebuffer}, + {"image", kDriverImage}, + {"noritake800", kDriverNoritake800}, + {"avrctl", kDriverAvrCtl}, + {"network", kDriverNetwork}, + {"gu126x64D-K610A4", kDriverGU126X64D_K610A4}, + {"serdisp", kDriverSerDisp}, + {"g15daemon", kDriverG15daemon}, + {"", kDriverUnknown} +}; + +tDriver * GetAvailableDrivers(int & count) +{ + for (count = 0; drivers[count].name.length() > 0; count++) + ; + return drivers; +} + +int GetDriverID(const std::string & driver) +{ + for (int i = 0; drivers[i].name.length() > 0; i++) + if (drivers[i].name == driver) + return drivers[i].id; + return kDriverUnknown; +} + +cDriver * CreateDriver(int driverID, cDriverConfig * config) +{ + switch (driverID) + { + case kDriverSimLCD: + return new cDriverSimLCD(config); + case kDriverGU140X32F: + return new cDriverGU140X32F(config); + case kDriverGU256X64_372: + return new cDriverGU256X64_372(config); + case kDriverGU256X64_3900: + return new cDriverGU256X64_3900(config); + case kDriverHD61830: + return new cDriverHD61830(config); + case kDriverKS0108: + return new cDriverKS0108(config); + case kDriverSED1330: + return new cDriverSED1330(config); + case kDriverSED1520: + return new cDriverSED1520(config); + case kDriverT6963C: + return new cDriverT6963C(config); + case kDriverFramebuffer: + return new cDriverFramebuffer(config); + case kDriverImage: + return new cDriverImage(config); + case kDriverNoritake800: + return new cDriverNoritake800(config); + case kDriverAvrCtl: + return new cDriverAvrCtl(config); + case kDriverNetwork: + return new cDriverNetwork(config); + case kDriverGU126X64D_K610A4: + return new cDriverGU126X64D_K610A4(config); + case kDriverSerDisp: + return new cDriverSerDisp(config); + case kDriverG15daemon: + return new cDriverG15daemon(config); + case kDriverUnknown: + default: + return NULL; + } +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/drivers.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/drivers.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,58 @@ +/* + * GraphLCD driver library + * + * drivers.h - global driver constants and functions + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDDRIVERS_DRIVERS_H_ +#define _GLCDDRIVERS_DRIVERS_H_ + +#include + + +namespace GLCD +{ + +class cDriverConfig; +class cDriver; + +enum eDriver +{ + kDriverUnknown = 0, + kDriverSimLCD = 1, + kDriverGU140X32F = 2, + kDriverGU256X64_372 = 3, + kDriverGU256X64_3900 = 4, + kDriverHD61830 = 5, + kDriverKS0108 = 6, + kDriverSED1330 = 7, + kDriverSED1520 = 8, + kDriverT6963C = 9, + kDriverFramebuffer = 10, + kDriverImage = 11, + kDriverNoritake800 = 12, + kDriverAvrCtl = 13, + kDriverNetwork = 14, + kDriverGU126X64D_K610A4 = 15, + kDriverSerDisp = 100, + kDriverG15daemon = 200 +}; + +struct tDriver +{ + std::string name; + eDriver id; +}; + +tDriver * GetAvailableDrivers(int & count); +int GetDriverID(const std::string & driver); +cDriver * CreateDriver(int driverID, cDriverConfig * config); + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/framebuffer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/framebuffer.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,249 @@ +/* + * GraphLCD driver library + * + * framebuffer.h - framebuffer device + * Output goes to a framebuffer device + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Stephan Skrodzki + */ + +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "config.h" +#include "framebuffer.h" + + +namespace GLCD +{ + +cDriverFramebuffer::cDriverFramebuffer(cDriverConfig * config) +: config(config), + offbuff(0), + fbfd(-1) +{ + oldConfig = new cDriverConfig(*config); +} + +cDriverFramebuffer::~cDriverFramebuffer() +{ + delete oldConfig; +} + +int cDriverFramebuffer::Init() +{ + // default values + width = config->width; + if (width <= 0) + width = 320; + height = config->height; + if (height <= 0) + height = 240; + zoom = 1; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "Zoom") + { + int z = atoi(config->options[i].value.c_str()); + if (z == 0 || z == 1) + zoom = z; + else + syslog(LOG_ERR, "%s error: zoom %d not supported, using default (%d)!\n", + config->name.c_str(), z, zoom); + } + } + + // Open the file for reading and writing + fbfd = open("/dev/fb0", O_RDWR); + if (1 == fbfd) + { + syslog(LOG_ERR, "%s: cannot open framebuffer device.\n", config->name.c_str()); + return -1; + } + syslog(LOG_INFO, "%s: The framebuffer device was opened successfully.\n", config->name.c_str()); + + // Get fixed screen information + if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) + { + syslog(LOG_ERR, "%s: Error reading fixed information.\n", config->name.c_str()); + return -1; + } + + // Get variable screen information + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) + { + syslog(LOG_ERR, "%s: Error reading variable information.\n", config->name.c_str()); + return -1; + } + + // Figure out the size of the screen in bytes + screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; + + syslog(LOG_INFO, "%s: V01: xres: %d, yres %d, vyres: %d, bpp: %d, linelenght: %d\n", config->name.c_str(),vinfo.xres,vinfo.yres,vinfo.yres_virtual,vinfo.bits_per_pixel,finfo.line_length); + + // reserve another memory to draw into + offbuff = new char[screensize]; + if (!offbuff) + { + syslog(LOG_ERR, "%s: failed to alloc memory for framebuffer device.\n", config->name.c_str()); + return -1; + } + + // Map the device to memory + fbp = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); + if (fbp == MAP_FAILED) + { + syslog(LOG_ERR, "%s: failed to map framebuffer device to memory.\n", config->name.c_str()); + return -1; + } + syslog(LOG_INFO, "%s: The framebuffer device was mapped to memory successfully.\n", config->name.c_str()); + + *oldConfig = *config; + + // clear display + Refresh(true); + + syslog(LOG_INFO, "%s: Framebuffer initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverFramebuffer::DeInit() +{ + if (offbuff) + delete[] offbuff; + munmap(fbp, screensize); + if (-1 != fbfd) + close(fbfd); + return 0; +} + +int cDriverFramebuffer::CheckSetup() +{ + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +void cDriverFramebuffer::SetPixel(int x, int y) +{ + int location; + int outcol; + + if (x >= width || y >= height) + return; + + if (config->upsideDown) + { + x = width - 1 - x; + y = height - 1 - y; + } + + // Figure out where in memory to put the pixel + location = (x*(1+zoom)+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + + (y*(1+zoom)+vinfo.yoffset) * finfo.line_length; + + if (vinfo.bits_per_pixel <= 8) + { + outcol = 15; + } + else + { + outcol = 255; + } + + if (vinfo.bits_per_pixel <= 8) + { + *(offbuff + location) = outcol; + if (zoom == 1) + { + *(offbuff + location + 1) = outcol; + *(offbuff + location + finfo.line_length) = outcol; + *(offbuff + location + finfo.line_length + 1) = outcol; + } + } + else if (vinfo.bits_per_pixel <= 16) + { + *(offbuff + location) = outcol; + *(offbuff + location + 1) = outcol; + if (zoom == 1) + { + *(offbuff + location + 2) = outcol; + *(offbuff + location + 3) = outcol; + *(offbuff + location + finfo.line_length) = outcol; + *(offbuff + location + finfo.line_length + 1) = outcol; + *(offbuff + location + finfo.line_length + 2) = outcol; + *(offbuff + location + finfo.line_length + 3) = outcol; + } + } + else + { + *(offbuff + location) = outcol; + *(offbuff + location + 1) = outcol; + *(offbuff + location + 2) = outcol; + *(offbuff + location + 3) = 0; /* should be transparency */ + if (zoom == 1) + { + *(offbuff + location + 4) = outcol; + *(offbuff + location + 5) = outcol; + *(offbuff + location + 6) = outcol; + *(offbuff + location + 7) = 0; + *(offbuff + location + finfo.line_length) = outcol; + *(offbuff + location + finfo.line_length + 1) = outcol; + *(offbuff + location + finfo.line_length + 2) = outcol; + *(offbuff + location + finfo.line_length + 3) = 0; + *(offbuff + location + finfo.line_length + 4) = outcol; + *(offbuff + location + finfo.line_length + 5) = outcol; + *(offbuff + location + finfo.line_length + 6) = outcol; + *(offbuff + location + finfo.line_length + 7) = 0; + } + } +} + +void cDriverFramebuffer::Clear() +{ + memset(offbuff, 0, screensize); +} + +void cDriverFramebuffer::Set8Pixels(int x, int y, unsigned char data) +{ + int n; + + x &= 0xFFF8; + + for (n = 0; n < 8; ++n) + { + if (data & (0x80 >> n)) // if bit is set + SetPixel(x + n, y); + } +} + +void cDriverFramebuffer::Refresh(bool refreshAll) +{ + memcpy(fbp, offbuff, screensize); +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/framebuffer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/framebuffer.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,56 @@ +/* + * GraphLCD driver library + * + * framebuffer.h - framebuffer device + * Output goes to a framebuffer device + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Stephan Skrodzki + */ + +#ifndef _GLCDDRIVERS_FRAMEBUFFER_H_ +#define _GLCDDRIVERS_FRAMEBUFFER_H_ + +#include "driver.h" +#include + + +namespace GLCD +{ + +class cDriverConfig; + +class cDriverFramebuffer : public cDriver +{ +private: + unsigned char ** LCD; + cDriverConfig * config; + cDriverConfig * oldConfig; + char *offbuff; + int fbfd; + struct fb_var_screeninfo vinfo; + struct fb_fix_screeninfo finfo; + long int screensize; + void *fbp; + int zoom; + + int CheckSetup(); + void SetPixel(int x, int y); + +public: + cDriverFramebuffer(cDriverConfig * config); + virtual ~cDriverFramebuffer(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/g15daemon.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/g15daemon.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,219 @@ +/* +* GraphLCD driver library +* +* g15daemon.c - pseudo device for the g15daemon meta driver +* Output goes to the g15daemon which then displays it +* +* This file is released under the GNU General Public License. Refer +* to the COPYING file distributed with this package. +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "config.h" + +#include "g15daemon.h" + +#define G15SERVER_PORT 15550 +#define G15SERVER_ADDR "127.0.0.1" + +#define G15_WIDTH 160 +#define G15_HEIGHT 43 + + +static int g15_send(int sock, char *buf, int len) +{ + int total = 0; + int retval = 0; + int bytesleft = len; + + while (total < len) { + retval = send(sock, buf+total, bytesleft, 0); + if (retval == -1) { + break; + } + bytesleft -= retval; + total += retval; + } + return retval==-1?-1:0; +} + +static int g15_recv(int sock, char *buf, int len) +{ + int total = 0; + int retval = 0; + int bytesleft = len; + + while (total < len) { + retval = recv(sock, buf+total, bytesleft, 0); + if (retval < 1) { + break; + } + total += retval; + bytesleft -= retval; + } + return total; +} + +static int open_g15_daemon() +{ + int g15screen_fd; + struct sockaddr_in serv_addr; + + char buffer[256]; + + g15screen_fd = socket(AF_INET, SOCK_STREAM, 0); + if (g15screen_fd < 0) + return -1; + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + inet_aton (G15SERVER_ADDR, &serv_addr.sin_addr); + serv_addr.sin_port = htons(G15SERVER_PORT); + + if (connect(g15screen_fd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) + return -1; + + memset(buffer,0,256); + if (g15_recv(g15screen_fd, buffer, 16)<0) + return -1; + + /* here we check that we're really talking to the g15daemon */ + if (strcmp(buffer,"G15 daemon HELLO") != 0) + return -1; + + /* we want to use a pixelbuffer */ + g15_send(g15screen_fd,"GBUF",4); + + return g15screen_fd; +} + + +namespace GLCD +{ + +cDriverG15daemon::cDriverG15daemon(cDriverConfig * config) +: config(config), + offbuff(0), + sockfd(-1) +{ + oldConfig = new cDriverConfig(*config); +} + +cDriverG15daemon::~cDriverG15daemon() +{ + delete oldConfig; +} + +int cDriverG15daemon::Init() +{ + // default values + width = config->width; + if (width !=G15_WIDTH) + width = G15_WIDTH; + height = config->height; + if (height !=G15_HEIGHT) + height = G15_HEIGHT; + + for (unsigned int i = 0; i < config->options.size(); i++) { + if (config->options[i].name == "") { + } + } + + screensize = 6880; + + if ((sockfd = open_g15_daemon())<0) + return -1; + // reserve memory to draw into + offbuff = new char[6880]; + + *oldConfig = *config; + + // clear display + Refresh(true); + + syslog(LOG_INFO, "%s: g15daemon initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverG15daemon::DeInit() +{ + if (offbuff); + delete[] offbuff; + if (-1 != sockfd) + close(sockfd); + + return 0; +} + +int cDriverG15daemon::CheckSetup() +{ + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +void cDriverG15daemon::SetPixel(int x, int y) +{ + if (x >= width || y >= height) + return; + + if (config->upsideDown) + { + x = width - 1 - x; + y = height - 1 - y; + } + + offbuff[x + (width * y)] = 1; +} + +void cDriverG15daemon::Clear() +{ + memset(offbuff, 0, screensize); +} + +void cDriverG15daemon::Set8Pixels(int x, int y, unsigned char data) +{ + int n; + + x &= 0xFFF8; + + for (n = 0; n < 8; ++n) + { + if (data & (0x80 >> n)) // if bit is set + SetPixel(x + n, y); + } +} + +void cDriverG15daemon::Refresh(bool refreshAll) +{ + g15_send(sockfd, offbuff, screensize); +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/g15daemon.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/g15daemon.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,49 @@ +/* + * GraphLCD driver library + * + * g15daemon.h - pseudo device for the g15daemon + * Output goes to the g15daemon which then displays it + * + */ + +#ifndef _GLCDDRIVERS_G15DAEMON_H_ +#define _GLCDDRIVERS_G15DAEMON_H_ + +#include "driver.h" + + +namespace GLCD +{ + +class cDriverConfig; + +class cDriverG15daemon : public cDriver +{ +private: + unsigned char ** LCD; + cDriverConfig * config; + cDriverConfig * oldConfig; + char *offbuff; + int sockfd; + long int screensize; + char *fbp; + int zoom; + + int CheckSetup(); + void SetPixel(int x, int y); + +public: + cDriverG15daemon(cDriverConfig * config); + virtual ~cDriverG15daemon(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/gu126x64D-K610A4.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/gu126x64D-K610A4.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,967 @@ +/* + * GraphLCD driver library + * + * gu126x64D-K610A4.c - 8-bit driver module for Noritake GU126x64D-K610A4 VFD + * displays. The VFD is operating in its 8 bit-mode + * connected to a single PC parallel port. + * + * based on: + * gu256x64-372 driver module for graphlcd + * (c) 2004 Andreas 'randy' Weinberger (randy AT smue.org) + * gu256x64-3900 driver module for graphlcd + * (c) 2004 Ralf Mueller (ralf AT bj-ig.de) + * gu140x32f driver module for graphlcd + * (c) 2003 Andreas Brachold + * ks0108 driver module for graphlcd + * (c) 2004 Andreas 'randy' Weinberger (randy AT smue.org) + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2007 Alexander Rieger (Alexander.Rieger AT inka.de) + */ + +#include +#include +#include +#include + +#include "common.h" +#include "config.h" +#include "gu126x64D-K610A4.h" +#include "port.h" + +namespace GLCD +{ +//----- commands to the display ----------------------------------------------- +static const unsigned char CMD_RUN_MACRO_01 = 0x01; // run macro 1 +static const unsigned char CMD_RUN_MACRO_02 = 0x02; // run macro 2 +static const unsigned char CMD_RUN_MACRO_03 = 0x03; // run macro 3 +static const unsigned char CMD_RUN_MACRO_04 = 0x04; // run macro 4 +static const unsigned char CMD_RUN_MACRO_05 = 0x05; // run macro 5 +static const unsigned char CMD_RUN_MACRO_06 = 0x06; // run macro 6 +static const unsigned char CMD_RUN_MACRO_07 = 0x07; // run macro 7 + +static const unsigned char CMD_CURSOR_POS = 0x10; // Set cursor position +static const unsigned char CMD_BOX_SET = 0x11; // Set area +static const unsigned char CMD_BOX_CLEAR = 0x12; // Clear area +static const unsigned char CMD_BOX_INVERT = 0x13; // Invert area +static const unsigned char CMD_RECT_SET = 0x14; // Set outline +static const unsigned char CMD_RECT_CLEAR = 0x15; // Clear outline + +static const unsigned char CMD_PIXEL_SET = 0x16; // Set pixel at current pos +static const unsigned char CMD_PIXEL_CLEAR = 0x17; // Clear pixel at current pos + +static const unsigned char CMD_GRAPHIC_WRITE = 0x18; // Write graphics data (args: len, data) +static const unsigned char CMD_RESET = 0x19; // Reset display +static const unsigned char CMD_WRITE_MODE = 0x1A; // Write mode +static const unsigned char CMD_INTRO = 0x1B; // Intro for other commands (see CMA_*) +static const unsigned char CMD_FONT_PROP_SML = 0x1C; // Select font: proportional mini +static const unsigned char CMD_FONT_FIX_MED = 0x1D; // Select font: fixed spaced 5x7 +static const unsigned char CMD_FONT_FIX_BIG = 0x1E; // Select font: fixed spaced 10x14 + +static const unsigned char CMA_MACROS_ERASE = 0x4D; // Erase Macros (usage: CMD_INTRO + this) +static const unsigned char CMA_EPROM_LOCK = 0x4C; // Lock EEPROM (usage: CMD_INTRO + this) +static const unsigned char CMA_EPROM_UNLOCK = 0x55; // Unlock EEPROM (usage: CMD_INTRO + this) + +static const unsigned char CMA_POWER_OFF = 0x46; // Power off (usage: CMD_INTRO + this) +static const unsigned char CMA_POWER_ON = 0x50; // Power on (usage: CMD_INTRO + this) + +//----- signal lines ---------------------------------------------------------- +static const unsigned char OUT_EN_HI = kAutoLow ; +static const unsigned char OUT_EN_LO = kAutoHigh; +static const unsigned char OUT_EN_MASK = OUT_EN_HI; + +static const unsigned char IN_MB_HI = 0x40; +static const unsigned char IN_MB_LO = 0x00; +static const unsigned char IN_MB_MASK = IN_MB_HI; + +//----- log flags ------------------------------------------------------------- +static const unsigned int LL_REFRESH_START = 0x0001; // 1 +static const unsigned int LL_REFRESH_END = 0x0002; // 2 +static const unsigned int LL_REFRESH_MED = 0x0004; // 4 +static const unsigned int LL_VFD_CMD = 0x0008; // 8 +static const unsigned int LL_MAX_WAIT = 0x0010; // 16 + +//----- mixed consts ---------------------------------------------------------- +static const long ADJUST_FACTOR = 100; // used to adjust timing + +//----------------------------------------------------------------------------- +cDriverGU126X64D_K610A4::cDriverGU126X64D_K610A4(cDriverConfig * config) + : port (0) + , config (config) + , oldConfig (0) + , myNumRows (0) + , myDrawMem (0) + , myVFDMem (0) + , myUseSleepInit (false) + , myPortDelayNS (0) + , myDelay125NS (0) + , myRefreshCounter (0) + , myClaimCounter (0) + , myDataPendingCounter(0) + , myLogFlags (0) +{ + oldConfig = new cDriverConfig(*config); +} // cDriverGU126X64D_K610A4::cDriverGU126X64D_K610A4() + +//----------------------------------------------------------------------------- +cDriverGU126X64D_K610A4::~cDriverGU126X64D_K610A4() +{ + delete oldConfig; +} // cDriverGU126X64D_K610A4::cDriverGU126X64D_K610A4() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::Init() +{ + width = config->width; + if (width <= 0 || width > 256) // don't allow unreasonable big sizes from config + { + width = 126; + } // if + + height = config->height; + if (height <= 0 || height > 256) // don't allow unreasonable big sizes from config + { + height = 64; + } // if + + //----- parse config ----- + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "Debug") + { + myLogFlags = atoi(config->options[i].value.c_str()); + } // if + } // for + + myNumRows = ((height + 7) / 8); + port = new cParallelPort(); + + // setup drawing memory + myDrawMem = new unsigned char *[width]; + for (int x = 0; x < width; x++) + { + myDrawMem[x] = new unsigned char[myNumRows]; + memset(myDrawMem[x], 0, myNumRows); + } // for + + // setup vfd memory + myVFDMem = new unsigned char *[width]; + for (int x = 0; x < width; x++) + { + myVFDMem[x] = new unsigned char[myNumRows]; + memset(myVFDMem[x], 0, myNumRows); + } // for + + if (initParallelPort() < 0) + { + return -1; + } // if + + initDisplay(); + + *oldConfig = *config; + + // Set Display SetBrightness + SetBrightness(config->brightness); + + // clear display + Clear(); + clearVFDMem(); + + syslog( LOG_INFO, "%s: initialized (width: %d height: %d)" + , config->name.c_str(), width, height + ); + + return 0; +} // cDriverGU126X64D_K610A4::Init() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::DeInit() +{ + if (myVFDMem) + { + for (int x = 0; x < width; x++) + { + delete[] myVFDMem[x]; + } // for + delete[] myVFDMem; + myVFDMem = 0; + } // if + + if (myDrawMem) + { + for(int x = 0; x < width; x++) + { + delete[] myDrawMem[x]; + } // for + delete[] myDrawMem; + myDrawMem = 0; + } // if + + if (port) + { + // claim port to avoid msg when closing the port + port->Claim(); + if (port->Close() != 0) + { + return -1; + } // if + delete port; + port = 0; + } // if + + return 0; +} // cDriverGU126X64D_K610A4::DeInit() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::checkSetup() +{ + if ( config->device != oldConfig->device + || config->port != oldConfig->port + || config->width != oldConfig->width + || config->height != oldConfig->height + ) + { + DeInit(); + Init(); + return 0; + } // if + + if (config->brightness != oldConfig->brightness) + { + oldConfig->brightness = config->brightness; + SetBrightness(config->brightness); + } // if + + if ( config->upsideDown != oldConfig->upsideDown + || config->invert != oldConfig->invert + ) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + + return 1; + } // if + + return 0; +} // cDriverGU126X64D_K610A4::checkSetup() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::initParallelPort() +{ + struct timeval tv1, tv2; + + if (config->device == "") + { + // use DirectIO + if (port->Open(config->port) != 0) + { + syslog(LOG_ERR, "%s: unable to initialize gu256x64-3900!", config->name.c_str()); + return -1; + } // if + syslog(LOG_INFO, "%s: using direct IO!", config->name.c_str()); + uSleep(10); + } + else + { + // use ppdev + if (port->Open(config->device.c_str()) != 0) + { + syslog(LOG_ERR, "%s: unable to initialize gu256x64-3900!", config->name.c_str()); + return -1; + } // if + syslog(LOG_INFO, "%s: using ppdev!", config->name.c_str()); + } // if + + if (nSleepInit() != 0) + { + syslog(LOG_ERR, "%s: INFO: cannot change wait parameters Err: %s (cDriver::Init)", config->name.c_str(), strerror(errno)); + myUseSleepInit = false; + } + else + { + myUseSleepInit = true; + } // if + + //----- measure the time to write to the port ----- + syslog(LOG_DEBUG, "%s: benchmark started.", config->name.c_str()); + gettimeofday(&tv1, 0); + + const int aBenchCount = 1000; // don't change this! + for (int x = 0; x < aBenchCount; x++) + { + port->WriteData(x % 0x100); + } // for + + gettimeofday(&tv2, 0); + + // release the port, which was implicitely claimed by open + port->Release(); + + if (myUseSleepInit) nSleepDeInit(); + + myPortDelayNS = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec); + + myDelay125NS = std::max(125 + (ADJUST_FACTOR * config->adjustTiming) - myPortDelayNS, 0L); + + syslog( LOG_DEBUG, "%s: benchmark stopped. Time for Port Command: %ldns, delay: %ldns" + , config->name.c_str(), myPortDelayNS, myDelay125NS + ); + + return 0; +} // cDriverGU126X64D_K610A4::initParallelPort() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::initDisplay() +{ + claimPort(); + cmdReset(); + releasePort(); +} // cDriverGU126X64D_K610A4::initDisplay() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::clearVFDMem() +{ + for (int x = 0; x < width; x++) + { + memset(myVFDMem[x], 0, myNumRows); + } // for +} // cDriverGU126X64D_K610A4::clearVFDMem() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::Clear() +{ + for (int x = 0; x < width; x++) + { + memset(myDrawMem[x], 0, myNumRows); + } // for +} // cDriverGU126X64D_K610A4::Clear() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::SetBrightness(unsigned int percent) +{ + claimPort(); + cmdSetBrightness(percent); + releasePort(); +} // cDriverGU126X64D_K610A4::SetBrightness() + +//----------------------------------------------------------------------------- +bool cDriverGU126X64D_K610A4::waitForStatus(unsigned char theMask, unsigned char theValue, int theMaxWait) +{ + theValue = theValue & theMask; + + int status = port->ReadStatus(); + + if ((status & theMask) != theValue) + { + // wait some time for MB go HI/LO but not forever + int i = 0; + for(i = 0; ((status & theMask) != theValue) && i < theMaxWait; i++) + { + status = port->ReadStatus(); + } // for + + if (isLogEnabled(LL_MAX_WAIT) && i >= theMaxWait) + { + syslog( LOG_INFO, "%s: slept for %5d times while waiting for MB = %d" + , config->name.c_str(), i, ((theMask & theValue) == 0 ? 0 : 1) + ); + } // + } // if + + return ((status & theMask) == theValue); +} // cDriverGU126X64D_K610A4::waitForStatus() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::writeParallel(unsigned char data) +{ + if (myUseSleepInit) nSleepInit(); + + waitForStatus(IN_MB_MASK, IN_MB_LO, 500); // wait for MB == LO + + port->WriteData(data); // write data + nSleep(myDelay125NS); // - sleep + + port->WriteControl(OUT_EN_LO & OUT_EN_MASK); // set ENABLE to LO + nSleep(myDelay125NS); // - sleep + + port->WriteControl(OUT_EN_HI & OUT_EN_MASK); // set ENABLE to HI + + waitForStatus(IN_MB_MASK, IN_MB_HI, 50); // wait for MB == HI + +// the other drivers don't do this neither +// if (myUseSleepInit) nSleepDeInit(); +} // cDriverGU126X64D_K610A4::writeParallel() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::write(unsigned char data) +{ + int b = 0; + + writeParallel(data); + ++b; + + // if data == 0x60 -> send 0x60 twice + // (0x60 switches to hex-mode) + if (data == 0x60) + { + writeParallel(data); + ++b; + } // if + + return b; +} // cDriverGU126X64D_K610A4::write() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::setPixel(int x, int y) +{ + if (!myDrawMem ) return; + if (x >= width || x < 0) return; + if (y >= height || y < 0) return; + + if (config->upsideDown) + { + x = width - 1 - x; + y = height - 1 - y; + } // if + + unsigned char c = 0x80 >> (y % 8); + + myDrawMem[x][y/8] = myDrawMem[x][y/8] | c; +} // cDriverGU126X64D_K610A4::setPixel() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::Set8Pixels(int x, int y, unsigned char data) +{ + // x - pos isn't maybe align to 8 + x &= 0xFFF8; + + for (int n = 0; n < 8; ++n) + { + if ((data & (0x80 >> n)) != 0) // if bit is set + { + setPixel(x + n, y); + } // if + } // for +} // cDriverGU126X64D_K610A4::Set8Pixels() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::Refresh(bool refreshAll) +{ + // no mem present -> return + if (!myVFDMem || !myDrawMem) + { + return; + } // if + + // create log + if (isLogEnabled(LL_REFRESH_START)) + { + syslog( LOG_INFO, "%s: > Refresh() all = %d RefreshDisplay = %d RefreshCtr = %d Delay = %ld" + , config->name.c_str() + , refreshAll + , config->refreshDisplay + , myRefreshCounter + , myDelay125NS + ); + } // if + + // setup changed -> refresh all + if (checkSetup() > 0) + { + syslog(LOG_DEBUG, "%s: Refresh() checkSetup() returned != 0 -> refreshAll = true", config->name.c_str()); + refreshAll = true; + } // if + + // refresh-counter exceeded -> refresh all + if (!refreshAll && config->refreshDisplay != 0) + { + myRefreshCounter = (myRefreshCounter + 1) % config->refreshDisplay; + refreshAll = myRefreshCounter == 0; + + if (refreshAll && isLogEnabled(LL_REFRESH_START)) + { + syslog(LOG_DEBUG, "%s: Refresh() refresh-count reached -> refreshAll = true", config->name.c_str()); + } // if + } // if + + if (isLogEnabled(LL_REFRESH_START)) + { + syslog( LOG_INFO, "%s: Refresh() all = %d RefreshDisplay = %d RefreshCtr = %d Delay = %ld" + , config->name.c_str() + , refreshAll + , config->refreshDisplay + , myRefreshCounter + , myDelay125NS + ); + } // if + + // time for logs + struct timeval tv1, tv2; + gettimeofday(&tv1, 0); + + claimPort(); + + int chunk = 128; // displays with more than 128 pixels width are written in chunks + // note: this driver isn't really prepared to handle displays + // with other dimensions than 126x64 + int xb = 0; + int yb = 0; + long bc = 0; + + for (yb = 0; yb < myNumRows; ++yb) + { + int minX = width; + int maxX = 0; + + //----- if !refreshAll -> check modified bytes + if (!refreshAll) + { + for (xb = 0; xb < width; ++xb) + { + if (myVFDMem[xb][yb] != myDrawMem[xb][yb]) + { + minX = std::min(minX, xb); + maxX = std::max(maxX, xb); + } // if + } // for + } + else + { + minX = 0; + maxX = width - 1; + } // if + + // create log + if (isLogEnabled(LL_REFRESH_MED)) + { + if (minX <= maxX) + { + syslog( LOG_INFO, "%s: Row[%d] %3d - %3d : %3d" + , config->name.c_str(), yb + , minX, maxX + , maxX - minX + 1 + ); + } + else + { + syslog( LOG_INFO, "%s: Row[%d] --- - --- : ---" + , config->name.c_str(), yb + ); + } // if + } // if + + // perform refresh + if (minX <= maxX) + { + bc += cmdSetCursorPos(minX, yb * 8); + + for (xb = minX; xb <= maxX; ++xb) + { + if ((xb - minX) % chunk == 0) + { + bc += cmdGraphicWrite(std::min((maxX - xb + 1), chunk)); + } // if + + bc += cmdGraphicData(myDrawMem[xb][yb]); + myVFDMem[xb][yb] = myDrawMem[xb][yb]; + } // for + } // if + } // for + + releasePort(); + + // create log + if (isLogEnabled(LL_REFRESH_END)) + { + gettimeofday(&tv2, 0); + + long duration_ms = ((tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec)) + / 1000 /* us -> ms */ + ; + + syslog( LOG_INFO, "%s: < Refresh() all = %d took %3ld ms %5ld bytes = %5ld bytes/sec = %5ld ns/byte" + , config->name.c_str() + , refreshAll + , duration_ms + , bc + , duration_ms == 0 ? -1 : bc * 1000 / duration_ms + , bc == 0 ? -1 : duration_ms * 1000000 / bc + ); + } // if +} // cDriverGU126X64D_K610A4::Refresh() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdReset() +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "- 1B: CMD_RESET : 0x%02X ", int(CMD_RESET)); + } // if + + b += write(CMD_RESET); + + unsigned char aMode = 1 << 7 // data orientation : 0: horizontal, 1: vertical , default: 0 + | 0 << 6 // cursor movement : 0: horizontal, 1: vertical , default: 0 + | 0 << 5 // cursor direction : 0: forwards , 1: backwards, default: 0 + | 0 << 4 // underscore cursor: 0: off , 1: on , default: 0 + | 0 << 3 // underscore cursor: 0: static , 1: flash , default: 0 + | 0 << 2 // not in documentation + | 0 << 0 // pen type: 0: overwrite, 1: AND, 2: OR, 3: XOR , default: 0 + ; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "- 2B: CMD_WRITE_MODE : 0x%02X 0x%02X", int(CMD_RESET), int(aMode)); + } // if + + b += write(CMD_WRITE_MODE); + b += write(aMode); + + return b; +} // cDriverGU126X64D_K610A4::cmdReset() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdPower(bool fOn) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 2B: CMD_POWER : 0x%02X 0x%02X" + , int(CMD_INTRO), int(fOn ? CMA_POWER_ON : CMA_POWER_OFF) + ); + } // if + + b += write(CMD_INTRO); + b += write(fOn ? CMA_POWER_ON : CMA_POWER_OFF); + + return b; +} // cDriverGU126X64D_K610A4::cmdPower() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdLock(bool fLock) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 2B: CMD_LOCK : 0x%02X 0x%02X" + , int(CMD_INTRO), int(fLock ? CMA_EPROM_LOCK : CMA_EPROM_UNLOCK) + ); + } // if + + b += write(CMD_INTRO); + b += write(fLock ? CMA_EPROM_LOCK : CMA_EPROM_UNLOCK); + + return b; +} // cDriverGU126X64D_K610A4::cmdPower() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdSetCursorPos(unsigned char x, unsigned char y) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 3B: CMD_CURSOR_POS : 0x%02X 0x%02X 0x%02X (x = %3d, y = %3d)" + , int(CMD_CURSOR_POS), int(x), int(y), int(x), int(y) + ); + } // if + + b += write(CMD_CURSOR_POS); // cmd + b += write(x ); // xpos + b += write(y ); // ypos + + return b; +} // cDriverGU126X64D_K610A4::cmdSetCursorPos(); + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdGraphicWrite(unsigned char count) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 2B: CMD_GRAPHIC_WRITE: 0x%02X 0x%02X (%d bytes)" + , int(CMD_GRAPHIC_WRITE), int(count), int(count) + ); + } // if + + b += write(CMD_GRAPHIC_WRITE); // cmd + b += write(count ); // len + + myDataPendingCounter = count; + + return b; +} // cDriverGU126X64D_K610A4::cmdGraphicWrite() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdGraphicData(unsigned char data) +{ + int b = 0; + + myDataPendingCounter--; + if (myDataPendingCounter < 0) + { + syslog( LOG_WARNING, "%s error: more graphic data written than announced -> ignored" + , config->name.c_str() + ); + } + else + { + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 1B: CMD_GRAPHIC_DATA : 0x%02X (expecting another %d bytes)" + , int(data), myDataPendingCounter + ); + } // if + + b += write(data ^ (config->invert ? 0xFF : 0x00)); + } // if + + return b; +} // cDriverGU126X64D_K610A4::cmdGraphicData() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdSetBrightness(unsigned int percent) +{ + ensureNotInGraphics(); + int b = 0; + + unsigned char bright = 0; + if (percent >= 85) bright = 0xFF; + else if (percent >= 71) bright = 0xFE; + else if (percent >= 57) bright = 0xFD; + else if (percent >= 43) bright = 0xFC; + else if (percent >= 29) bright = 0xFB; + else if (percent >= 15) bright = 0xFA; + else if (percent >= 1) bright = 0xF9; + else bright = 0xF8; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 2B: CMD_INTRO : 0x%02X 0x%02X = set brightness" + , int(CMD_INTRO), int(bright) + ); + } // if + + b += write(CMD_INTRO); + b += write(bright); + + return b; +} // cDriverGU126X64D_K610A4::cmdSetBrightness() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdSetFont(FontType theFont) +{ + ensureNotInGraphics(); + int b = 0; + + unsigned char aCmd = 0; + switch (theFont) + { + case FONT_PROP_SML: aCmd = CMD_FONT_PROP_SML; break; + case FONT_FIX_BIG : aCmd = CMD_FONT_FIX_BIG ; break; + case FONT_FIX_MED : + default : aCmd = CMD_FONT_FIX_MED ; break; + } // switch + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "- 1B: CMD_SET_FONT : 0x%02X", int(aCmd)); + } // if + + b += write(aCmd); + + return b; +} // cDriverGU126X64D_K610A4::cmdSetFont() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdWriteText(const char *theText) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "-%2dB: WRITE_TEXT : '%s'", strlen(theText), theText); + } // if + + for (const char *p = theText; *p != '\0'; ++p) + { + b += write(*p); + } // for + + return b; +} // cDriverGU126X64D_K610A4::cmdWriteText() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdDrawRect(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2) +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 5B: CMD_SET_OUTLINE : 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X (x1 = %3d, y1 = %3d, x2 = %3d, y2 = %3d)" + , int(CMD_CURSOR_POS) + , int(x1), int(y1), int(x2), int(y2) + , int(x1), int(y1), int(x2), int(y2) + ); + } // if + + b += write(CMD_RECT_SET ); + b += write(x1 ); + b += write(y1 ); + b += write(x2 ); + b += write(y2 ); + + return b; +} // cDriverGU126X64D_K610A4::cmdDrawRect() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdSetMacro(unsigned char theMacroNum, unsigned char theCountBytes) +{ + if (theMacroNum > 7) + { + return 0; + } // if + + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog( LOG_INFO, "- 3B: CMD_INTRO : 0x%02X 0x%02X 0x%02X (define macro %d with length %d)" + , int(CMD_INTRO) + , int(theMacroNum), int(theCountBytes) + , int(theMacroNum), int(theCountBytes) + ); + } // if + + b += write(CMD_INTRO ); + b += write(theMacroNum ); + b += write(theCountBytes ); + + return b; +} // cDriverGU126X64D_K610A4::cmdSetMacro() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdSetPixel(bool fSet) +{ + int b = 0; + + if (fSet) + { + ensureNotInGraphics(); + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "- 1B: SET_PIXEL : 0x%02X", 0x16); + } // if + + b += write(CMD_PIXEL_SET); + } + else + { + b = cmdClrPixel(); + } // if + + return b; +} // cDriverGU126X64D_K610A4::cmdSetPixel() + +//----------------------------------------------------------------------------- +int cDriverGU126X64D_K610A4::cmdClrPixel() +{ + ensureNotInGraphics(); + int b = 0; + + if (isLogEnabled(LL_VFD_CMD)) + { + syslog(LOG_INFO, "- 1B: CLR_PIXEL : 0x%02X", 0x17); + } // if + + b += write(CMD_PIXEL_CLEAR); + + return b; +} // cDriverGU126X64D_K610A4::cmdClrPixel() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::ensureNotInGraphics() +{ + if (myClaimCounter <= 0) + { + syslog(LOG_ERR, "%s: ERROR: port not claimed (%d)", config->name.c_str(), myClaimCounter); + } // if + + if (myDataPendingCounter > 0) + { + syslog( LOG_WARNING, "%s error: expected another %d bytes graphic data, filling with 0x00" + , config->name.c_str(), myDataPendingCounter + ); + } // if + while (myDataPendingCounter > 0) + { + cmdGraphicData(0); + } // while +} // cDriverGU126X64D_K610A4::ensureNotInGraphics() + + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::claimPort() +{ + if (myClaimCounter == 0) + { + port->Claim(); + } // if + + myClaimCounter++; + + if (myClaimCounter > 1) + { + syslog( LOG_WARNING, "%s: port claimed more than once (%d)" + , config->name.c_str(), myClaimCounter + ); + } // if + +} // cDriverGU126X64D_K610A4::claimPort() + +//----------------------------------------------------------------------------- +void cDriverGU126X64D_K610A4::releasePort() +{ + if (myClaimCounter == 1) + { + port->Release(); + } // if + + myClaimCounter--; + + if (myClaimCounter < 0) + { + syslog( LOG_WARNING, "%s: port released more often than claimed" + , config->name.c_str() + ); + myClaimCounter = 0; + } // if + +} // cDriverGU126X64D_K610A4::releasePort() + +//----------------------------------------------------------------------------- +bool cDriverGU126X64D_K610A4::isLogEnabled(int theLevel) const +{ + return (theLevel & myLogFlags) != 0; +} // cDriverGU126X64D_K610A4::isLogEnabled() + +//----------------------------------------------------------------------------- +} // end of namespace + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/gu126x64D-K610A4.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/gu126x64D-K610A4.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,130 @@ +/* + * GraphLCD driver library + * + * gu126x64D-K610A4.h - 8-bit driver module for Noritake GU126x64D-K610A4 VFD + * displays. The VFD is operating in its 8 bit-mode + * connected to a single PC parallel port. + * + * based on: + * gu256x64-372 driver module for graphlcd + * (c) 2004 Andreas 'randy' Weinberger (randy AT smue.org) + * gu256x64-3900 driver module for graphlcd + * (c) 2004 Ralf Mueller (ralf AT bj-ig.de) + * gu140x32f driver module for graphlcd + * (c) 2003 Andreas Brachold + * ks0108 driver module for graphlcd + * (c) 2004 Andreas 'randy' Weinberger (randy AT smue.org) + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2007 Alexander Rieger (Alexander.Rieger AT inka.de) + */ + +#ifndef _GLCDDRIVERS_GU126X64D_K610A4_H_ +#define _GLCDDRIVERS_GU126X64D_K610A4_H_ + +#include "driver.h" + +//=============================================================================== +// namespace GLCD +//=============================================================================== +namespace GLCD +{ + +class cDriverConfig; +class cParallelPort; + +//=============================================================================== +// class cDriverGU126X64D_K610A4 +//=============================================================================== +class cDriverGU126X64D_K610A4 : public cDriver +{ +public: + //--------------------------------------------------------------------------- + // constructor/destructor + //--------------------------------------------------------------------------- + cDriverGU126X64D_K610A4(cDriverConfig * config); + virtual ~cDriverGU126X64D_K610A4(); + + //--------------------------------------------------------------------------- + // from cDriver + //--------------------------------------------------------------------------- + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); + virtual void SetBrightness(unsigned int percent); + + //--------------------------------------------------------------------------- + // display-specific enums/methods/etc. + //--------------------------------------------------------------------------- + enum FontType + { + FONT_PROP_SML + , FONT_FIX_MED + , FONT_FIX_BIG + }; + + void setPixel (int x, int y); + + int cmdReset (); + int cmdPower (bool fOn); + int cmdLock (bool fLock); + int cmdSetCursorPos (unsigned char x, unsigned char y); + int cmdGraphicWrite (unsigned char count); + int cmdGraphicData (unsigned char data); + int cmdSetBrightness(unsigned int percent); + int cmdSetFont (FontType); + int cmdWriteText (const char *theText); + int cmdDrawRect (unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2); + int cmdSetMacro (unsigned char theMacroNum, unsigned char theCountBytes); + int cmdSetPixel (bool fSet = true); + int cmdClrPixel (); + + void claimPort(); + void releasePort(); + +private: + //--------------------------------------------------------------------------- + // helper methods + //--------------------------------------------------------------------------- + void clearVFDMem(); + int checkSetup(); + int initParallelPort(); + void initDisplay(); + + bool waitForStatus(unsigned char theMask, unsigned char theValue, int theMaxWait); + void writeParallel(unsigned char data); + int write(unsigned char data); + + void ensureNotInGraphics(); + bool isLogEnabled(int theLevel) const; + + //--------------------------------------------------------------------------- + // attributes + //--------------------------------------------------------------------------- + cParallelPort *port; + + cDriverConfig *config; + cDriverConfig *oldConfig; + + int myNumRows; + unsigned char **myDrawMem; + unsigned char **myVFDMem; + + bool myUseSleepInit; + long myPortDelayNS; + long myDelay125NS; + int myRefreshCounter; + int myClaimCounter; + int myDataPendingCounter; + unsigned int myLogFlags; + +}; // class cDriverGU126X64D_K610A4 + +} // namespace GLCD + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/gu140x32f.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/gu140x32f.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,443 @@ +/* + * GraphLCD driver library + * + * gu140x32f.c - 8-bit driver module for Noritake GU140x32-F7806 VFD + * displays. The VFD is operating in its 8 bit-mode + * connected to a single PC parallel port. + * + * based on: + * HD61830 device + * (c) 2001-2003 by Carsten Siebholz + * lcdproc 0.4 driver hd44780-ext8bit + * (c) 1999, 1995 Benjamin Tse + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003 Andreas Brachold + */ + +#include +#include +#include +#include + +#include "common.h" +#include "config.h" +#include "gu140x32f.h" +#include "port.h" + + +namespace GLCD +{ + +// Defines for hd44780 Displays +#define RS_DAT 0x00 +#define RS_CMD 0x01 + +#define CLEAR 0x01 + +#define HOMECURSOR 0x02 + +#define ENTRYMODE 0x04 +#define E_MOVERIGHT 0x02 +#define E_MOVELEFT 0x00 +#define EDGESCROLL 0x01 +#define NOSCROLL 0x00 + +#define ONOFFCTRL 0x08 +#define DISPON 0x04 +#define DISPOFF 0x00 +#define CURSORON 0x02 +#define CURSOROFF 0x00 +#define CURSORBLINK 0x01 +#define CURSORNOBLINK 0x00 + +#define CURSORSHIFT 0x10 +#define SCROLLDISP 0x08 +#define MOVECURSOR 0x00 +#define MOVERIGHT 0x04 +#define MOVELEFT 0x00 + +#define FUNCSET 0x20 +#define IF_8BIT 0x10 +#define IF_4BIT 0x00 + +// Control output lines +// Write to baseaddress+2 +#define nSTRB 0x01 // pin 1; negative logic +#define nLF 0x02 // pin 14 +#define nINIT 0x04 // pin 16; the only positive logic output line +#define nSEL 0x08 // pin 17 +#define ENIRQ 0x10 // Enable IRQ via ACK line (don't enable this withouT + // setting up interrupt stuff too) +#define ENBI 0x20 // Enable bi-directional port (is nice to play with! + // I first didn't know a SPP could do this) + +#define OUTMASK 0x0B // SEL, LF and STRB are hardware inverted + // Use this mask only for the control output lines + // XOR with this mask ( ^ OUTMASK ) + +static const std::string kWiringStandard = "Standard"; +static const std::string kWiringWindows = "Windows"; + +// standard wiring +// #define RS nSTRB +// #define RW nLF +// #define EN1 nINIT +// #define BL nSEL + +// windows wiring +// #define RS nINIT +// #define RW nLF +// #define EN1 nSTRB +// #define BL nSEL + + +cDriverGU140X32F::cDriverGU140X32F(cDriverConfig * config) +: config(config), + m_pDrawMem(0), + m_pVFDMem(0) +{ + oldConfig = new cDriverConfig(*config); + + port = new cParallelPort(); + + m_nRefreshCounter = 0; +} + +cDriverGU140X32F::~cDriverGU140X32F() +{ + delete port; + delete oldConfig; +} + +int cDriverGU140X32F::Init() +{ + int x; + struct timeval tv1, tv2; + + // default values + width = config->width; + if (width <= 0) + width = 140; + height = config->height; + if (height <= 0) + height = 32; + m_iSizeYb = ((height + 7) / 8); // 4 + m_WiringRS = nSTRB; + m_WiringEN1 = nINIT; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "Wiring") + { + if (config->options[i].value == kWiringStandard) + { + m_WiringRS = nSTRB; + m_WiringEN1 = nINIT; + } + else if (config->options[i].value == kWiringWindows) + { + m_WiringRS = nINIT; + m_WiringEN1 = nSTRB; + } + else + syslog(LOG_ERR, "%s error: wiring %s not supported, using default (Standard)!\n", + config->name.c_str(), config->options[i].value.c_str()); + } + } + + // setup the memory array for the drawing array gu140x32f + m_pDrawMem = new unsigned char[width * m_iSizeYb]; + Clear(); + + // setup the memory array for the display array gu140x32f + m_pVFDMem = new unsigned char[width * m_iSizeYb]; + ClearVFDMem(); + + if (config->device == "") + { + // use DirectIO + if (port->Open(config->port) != 0) + return -1; + uSleep(10); + } + else + { + // use ppdev + if (port->Open(config->device.c_str()) != 0) + return -1; + } + + if (nSleepInit() != 0) + { + syslog(LOG_ERR, "%s: INFO: cannot change wait parameters Err: %s (cDriver::Init)\n", config->name.c_str(), strerror(errno)); + m_bSleepIsInit = false; + } + else + { + m_bSleepIsInit = true; + } + + syslog(LOG_DEBUG, "%s: benchmark started.\n", config->name.c_str()); + gettimeofday(&tv1, 0); + for (x = 0; x < 10000; x++) + { + port->WriteData(x % 0x100); + } + gettimeofday(&tv2, 0); + nSleepDeInit(); + m_nTimingAdjustCmd = ((tv2.tv_sec - tv1.tv_sec) * 10000 + (tv2.tv_usec - tv1.tv_usec)) / 1000; + syslog(LOG_DEBUG, "%s: benchmark stopped. Time for Port Command: %ldns\n", config->name.c_str(), m_nTimingAdjustCmd); + + + // setup the lcd in 8 bit mode + Write(RS_CMD, FUNCSET | IF_8BIT, 4100); + Write(RS_CMD, FUNCSET | IF_8BIT, 100); + Write(RS_CMD, FUNCSET | IF_8BIT, 40); + + Write(RS_CMD, ONOFFCTRL | DISPON | CURSOROFF | CURSORNOBLINK, 40); + Write(RS_CMD, CLEAR, 1600); + Write(RS_CMD, HOMECURSOR, 1600); + + port->Release(); + + *oldConfig = *config; + + // Set Display SetBrightness + SetBrightness(config->brightness); + // clear display + ClearVFDMem(); + Clear(); + + syslog(LOG_INFO, "%s: gu140x32f initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverGU140X32F::DeInit() +{ + if (m_pVFDMem) + delete[] m_pVFDMem; + if (m_pDrawMem) + delete[] m_pDrawMem; + + if (port->Close() != 0) + return -1; + return 0; +} + +int cDriverGU140X32F::CheckSetup() +{ + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->brightness != oldConfig->brightness) + { + oldConfig->brightness = config->brightness; + SetBrightness(config->brightness); + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +void cDriverGU140X32F::ClearVFDMem() +{ + for (int n = 0; m_pVFDMem && n < (width * m_iSizeYb); n++) + m_pVFDMem[n] = 0x00; +} + +void cDriverGU140X32F::Clear() +{ + for (int n = 0; m_pDrawMem && n < (width * m_iSizeYb); n++) + m_pDrawMem[n] = 0x00; +} + +void cDriverGU140X32F::SetBrightness(unsigned int percent) +{ + port->Claim(); + + unsigned char level; + if (percent > 100) + percent = 100; + level = percent / 25; + if (level < 1) + level = 1; + level = (4 - level) & 0x03; + // Set Brightness + // 00 - 100% + // 01 - 75% + // 02 - 50% + // 03 - 25% + Write(RS_CMD, FUNCSET | IF_8BIT, 40); + Write(RS_DAT, level, 40); + + port->Release(); +} + +void cDriverGU140X32F::Write(unsigned char nFlags, unsigned char bData, unsigned int nMicroSecBusyTime) +{ + if (m_bSleepIsInit) + nSleepInit(); + + unsigned char enableLines = 0, portControl; + + // Only one controller is supported + enableLines = m_WiringEN1; + + if (nFlags == RS_CMD) + portControl = 0; + else // if (nFlags == RS_DAT) + portControl = m_WiringRS; + + // portControl |= m_WiringBL; + + port->WriteControl(portControl ^ OUTMASK); //Reset controlbits + port->WriteData(bData); //Set data + port->WriteControl((enableLines | portControl) ^ OUTMASK); //Set controlbits + + // How long hold the data active + if (m_bSleepIsInit && (25 + (100 * config->adjustTiming) - m_nTimingAdjustCmd > 0)) + { + // Wait 50ns + nSleep(std::max(25L, 50 + (100 * config->adjustTiming) - m_nTimingAdjustCmd)); + } + + port->WriteControl(portControl ^ OUTMASK); //Reset controlbits + + nSleep((nMicroSecBusyTime * 1000) + (100 * config->adjustTiming) - m_nTimingAdjustCmd); + + if (m_bSleepIsInit) + nSleepDeInit(); +} + +void cDriverGU140X32F::SetPixel(int x, int y) +{ + unsigned char c; + int n; + + if (!m_pDrawMem) + return; + + if (x >= width || x < 0) + return; + if (y >= height || y < 0) + return; + + if (config->upsideDown) + { + x = width - 1 - x; + y = height - 1 - y; + } + + n = x + ((y / 8) * width); + c = 0x80 >> (y % 8); + + m_pDrawMem[n] |= c; +} + +void cDriverGU140X32F::Set8Pixels(int x, int y, unsigned char data) +{ + int n; + + // x - pos is'nt mayby align to 8 + x &= 0xFFF8; + + for (n = 0; n < 8; ++n) + { + if (data & (0x80 >> n)) // if bit is set + SetPixel(x + n, y); + } +} + +void cDriverGU140X32F::Refresh(bool refreshAll) +{ + int n, x, yb; + + if (!m_pVFDMem || !m_pDrawMem) + return; + + bool doRefresh = false; + int minX = width; + int maxX = 0; + int minYb = m_iSizeYb; + int maxYb = 0; + + if (CheckSetup() > 0) + refreshAll = true; + + for (yb = 0; yb < m_iSizeYb; ++yb) + for (x = 0; x < width; ++x) + { + n = x + (yb * width); + if (m_pVFDMem[n] != m_pDrawMem[n]) + { + m_pVFDMem[n] = m_pDrawMem[n]; + minX = std::min(minX, x); + maxX = std::max(maxX, x); + minYb = std::min(minYb, yb); + maxYb = std::max(maxYb, yb + 1); + doRefresh = true; + } + } + + m_nRefreshCounter = (m_nRefreshCounter + 1) % config->refreshDisplay; + + if (!refreshAll && !m_nRefreshCounter) + refreshAll = true; + + if (refreshAll || doRefresh) + { + if (refreshAll) + { + minX = 0; + maxX = width; + minYb = 0; + maxYb = m_iSizeYb; + // and reset RefreshCounter + m_nRefreshCounter = 0; + } + + minX = std::max(minX, 0); + maxX = std::min(maxX, width - 1); + minYb = std::max(minYb, 0); + maxYb = std::min(maxYb, m_iSizeYb); + + port->Claim(); + // send lcd data to display, controller + Write(RS_CMD, 0xF1, 40); + Write(RS_DAT, minX, 40); + Write(RS_DAT, (minYb * 8) & 0xFFF8, 40); + Write(RS_DAT, maxX, 40); + Write(RS_DAT, (maxYb * 8), 40); + + Write(RS_DAT, 'v', 500); + + for (yb = minYb; yb <= maxYb; ++yb) + for (x = minX; x <= maxX; ++x) + { + n = x + (yb * width); + + if (n >= (width * m_iSizeYb)) + break; + Write(RS_DAT, (m_pVFDMem[n]) ^ (config->invert ? 0xff : 0x00), 40); + } + port->Release(); + } +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/gu140x32f.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/gu140x32f.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,73 @@ +/* + * GraphLCD driver library + * + * gu140x32f.h - 8-bit driver module for Noritake GU140x32-F7806 VFD + * displays. The VFD is operating in its 8 bit-mode + * connected to a single PC parallel port. + * + * based on: + * HD61830 device + * (c) 2001-2003 by Carsten Siebholz + * lcdproc 0.4 driver hd44780-ext8bit + * (c) 1999, 1995 Benjamin Tse + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003 Andreas Brachold + */ + +#ifndef _GLCDDRIVERS_GU140X32F_H_ +#define _GLCDDRIVERS_GU140X32F_H_ + +#include "driver.h" + + +namespace GLCD +{ + +class cDriverConfig; +class cParallelPort; + + +class cDriverGU140X32F : public cDriver +{ + unsigned char m_WiringRS; + unsigned char m_WiringEN1; + + cParallelPort * port; + + cDriverConfig * config; + cDriverConfig * oldConfig; + + int m_iSizeYb; + int m_nRefreshCounter; + unsigned char *m_pDrawMem; // the draw "memory" + unsigned char *m_pVFDMem; // the double buffed display "memory" + long m_nTimingAdjustCmd; + bool m_bSleepIsInit; + + int CheckSetup(); + +protected: + void ClearVFDMem(); + void SetPixel(int x, int y); + void Write(unsigned char nFlags, unsigned char bData, unsigned int nMicroSecBusyTime); + +public: + cDriverGU140X32F(cDriverConfig * config); + virtual ~cDriverGU140X32F(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); + + virtual void SetBrightness(unsigned int percent); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/gu256x64-372.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/gu256x64-372.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,408 @@ +/* + * GraphLCD driver library + * + * gu256x64-372.c - 8-bit driver module for Noritake GU256x64-372 + * VFD displays. The VFD is operating in its 8-bit + * mode connected to a single PC parallel port. + * + * based on: + * gu256x32f driver module for graphlcd + * (c) 2003 Andreas Brachold + * HD61830 device + * (c) 2001-2003 by Carsten Siebholz + * lcdproc 0.4 driver hd44780-ext8bit + * (c) 1999, 1995 Benjamin Tse + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas 'randy' Weinberger (randy AT smue.org) + */ + +#include +#include +#include +#include + +#include "common.h" +#include "config.h" +#include "gu256x64-372.h" +#include "port.h" + + +namespace GLCD +{ + +#define SCREENSOFF 0x00 // both screens are off +#define SCREEN1ON 0x01 // only screen #1 is on (graphic screen) +#define SCREEN2ON 0x02 // only screen #2 is on (graphic/character screen) +#define SCREENSON 0x03 // both screens are on + +#define CURS_AUTOINC 0x04 // cursor increments automatically +#define CURS_HOLD 0x05 // cursor holds + +#define SCREEN2CHAR 0x06 // screen #2 sets to "character" display +#define SCREEN2GRAPH 0x07 // screen #2 sets to "graphic" display + +#define DATA_WRITE 0x08 // data write mode +#define DATA_READ 0x09 // data read mode + +#define DISP_LOSTA1 0x0A // lower addr. of display start of screen #1 +#define DISP_HISTA1 0x0B // upper addr. of display start of screen #1 +#define DISP_LOSTA2 0x0C // lower addr. of display start of screen #2 +#define DISP_HISTA2 0x0D // upper addr. of display start of screen #2 +#define CURS_LOADDR 0x0E // lower addr. of cursor of screen #1 & #2 +#define CURS_HIADDR 0x0F // upper addr. of cursor start of screen #1 & #2 + +#define DISP_OR 0x10 // or display of screen #1 & #2 +#define DISP_EXOR 0x11 // ex-or display of screen #1 & #2 +#define DISP_AND 0x12 // and display of screen #1 & #2 + +#define BRIGHT_1 0x18 // luminance level 1 100.0% +#define BRIGHT_2 0x19 // luminance level 2 87.5% +#define BRIGHT_3 0x1A // luminance level 3 75.0% +#define BRIGHT_4 0x1B // luminance level 4 62.5% + +#define WRHI 0x04 // INIT +#define WRLO 0x00 +#define CDHI 0x00 // nSEL +#define CDLO 0x08 + + +cDriverGU256X64_372::cDriverGU256X64_372(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); + + port = new cParallelPort(); + + m_nRefreshCounter = 0; +} + +cDriverGU256X64_372::~cDriverGU256X64_372() +{ + delete oldConfig; + delete port; +} + +int cDriverGU256X64_372::Init() +{ + int x; + struct timeval tv1, tv2; + + width = config->width; + if (width <= 0) + width = 256; + height = config->height; + if (height <= 0) + height = 64; + m_iSizeYb = (height + 7) / 8; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "") + { + } + } + + // setup linear lcd array + m_pDrawMem = new unsigned char *[width]; + if (m_pDrawMem) + { + for (x = 0; x < width; x++) + { + m_pDrawMem[x] = new unsigned char[m_iSizeYb]; + memset(m_pDrawMem[x], 0, m_iSizeYb); + } + } + Clear(); + + // setup the lcd array for the "vertical" mem + m_pVFDMem = new unsigned char *[width]; + if (m_pVFDMem) + { + for (x = 0; x < width; x++) + { + m_pVFDMem[x] = new unsigned char[m_iSizeYb]; + memset(m_pVFDMem[x], 0, m_iSizeYb); + } + } + ClearVFDMem(); + + if (config->device == "") + { + // use DirectIO + if (port->Open(config->port) != 0) + return -1; + uSleep(10); + } + else + { + // use ppdev + if (port->Open(config->device.c_str()) != 0) + return -1; + } + + if (nSleepInit() != 0) + { + syslog(LOG_ERR, "%s: INFO: cannot change wait parameters Err: %s (cDriver::Init)\n", config->name.c_str(), strerror(errno)); + m_bSleepIsInit = false; + } + else + { + m_bSleepIsInit = true; + } + + syslog(LOG_DEBUG, "%s: benchmark started.\n", config->name.c_str()); + gettimeofday(&tv1, 0); + for (x = 0; x < 10000; x++) + { + port->WriteData(x % 0x100); + } + gettimeofday(&tv2, 0); + nSleepDeInit(); + m_nTimingAdjustCmd = ((tv2.tv_sec - tv1.tv_sec) * 10000 + (tv2.tv_usec - tv1.tv_usec)) / 1000; + syslog(LOG_DEBUG, "%s: benchmark stopped. Time for Port Command: %ldns\n", config->name.c_str(), m_nTimingAdjustCmd); + + GU256X64Cmd(SCREEN1ON); + GU256X64Cmd(CURS_AUTOINC); + GU256X64Cmd(SCREEN2CHAR); + + GU256X64Cmd(DISP_LOSTA1); GU256X64Data(0x00); + GU256X64Cmd(DISP_HISTA1); GU256X64Data(0x00); + GU256X64Cmd(DISP_LOSTA2); GU256X64Data(0x00); + GU256X64Cmd(DISP_HISTA2); GU256X64Data(0x10); + GU256X64Cmd(CURS_LOADDR); GU256X64Data(0x00); + GU256X64Cmd(CURS_HIADDR); GU256X64Data(0x00); + + GU256X64Cmd(DISP_OR); + + port->Release(); + + *oldConfig = *config; + + // Set Display SetBrightness + SetBrightness(config->brightness); + // clear display + Clear(); + ClearVFDMem(); + + syslog(LOG_INFO, "%s: gu256x64-372 initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverGU256X64_372::DeInit() +{ + int x; + + if (m_pVFDMem) + for (x = 0; x < width; x++) + { + delete[] m_pVFDMem[x]; + } + delete[] m_pVFDMem; + + if (m_pDrawMem) + for (x = 0; x < width; x++) + { + delete[] m_pDrawMem[x]; + } + delete[] m_pDrawMem; + + if (port->Close() != 0) + return -1; + return 0; +} + +int cDriverGU256X64_372::CheckSetup() +{ + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->brightness != oldConfig->brightness) + { + oldConfig->brightness = config->brightness; + SetBrightness(config->brightness); + } + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +void cDriverGU256X64_372::ClearVFDMem() +{ + for (int x = 0; x < width; x++) + memset(m_pVFDMem[x], 0, m_iSizeYb); +} + +void cDriverGU256X64_372::Clear() +{ + for (int x = 0; x < width; x++) + memset(m_pDrawMem[x], 0, m_iSizeYb); +} + +void cDriverGU256X64_372::SetBrightness(unsigned int percent) +{ + port->Claim(); + + if (percent > 88) { + GU256X64Cmd(BRIGHT_1); + } else if (percent > 75) { + GU256X64Cmd(BRIGHT_2); + } else if (percent > 66) { + GU256X64Cmd(BRIGHT_3); + } else if (percent > 0 ) { + GU256X64Cmd(BRIGHT_4); + } else { + GU256X64Cmd(SCREENSOFF); + } + port->Release(); +} + +void cDriverGU256X64_372::GU256X64Cmd(unsigned char data) +{ + if (m_bSleepIsInit) + nSleepInit(); + + port->WriteControl(CDHI | WRHI); + port->WriteData(data); + nSleep(100 + (100 * config->adjustTiming) - m_nTimingAdjustCmd); + port->WriteControl(CDHI | WRLO); + nSleep(100 + (100 * config->adjustTiming) - m_nTimingAdjustCmd); + port->WriteControl(CDHI | WRHI); + nSleep(100 + (100 * config->adjustTiming) - m_nTimingAdjustCmd); +} + +void cDriverGU256X64_372::GU256X64Data(unsigned char data) +{ + if (m_bSleepIsInit) + nSleepInit(); + + port->WriteControl(CDLO | WRHI); + port->WriteData(data); + nSleep(100 + (100 * config->adjustTiming) - m_nTimingAdjustCmd); + port->WriteControl(CDLO | WRLO); + nSleep(100 + (100 * config->adjustTiming) - m_nTimingAdjustCmd); + port->WriteControl(CDLO | WRHI); + nSleep(100 + (100 * config->adjustTiming) - m_nTimingAdjustCmd); +} + +void cDriverGU256X64_372::SetPixel(int x, int y) +{ + unsigned char c; + + if (!m_pDrawMem) + return; + + if (x >= width || x < 0) + return; + if (y >= height || y < 0) + return; + + if (config->upsideDown) + { + x = width - 1 - x; + y = height - 1 - y; + } + + c = 0x80 >> (y % 8); + + m_pDrawMem[x][y/8] = m_pDrawMem[x][y/8] | c; +} + +void cDriverGU256X64_372::Set8Pixels(int x, int y, unsigned char data) +{ + int n; + + // x - pos is'nt mayby align to 8 + x &= 0xFFF8; + + for (n = 0; n < 8; ++n) + { + if (data & (0x80 >> n)) // if bit is set + SetPixel(x + n, y); + } +} + +void cDriverGU256X64_372::Refresh(bool refreshAll) +{ + int xb, yb; + + if (!m_pVFDMem || !m_pDrawMem) + return; + + bool doRefresh = false; + int minX = width; + int maxX = 0; + int minYb = m_iSizeYb; + int maxYb = 0; + + if (CheckSetup() > 0) + refreshAll = true; + + for (xb = 0; xb < width; ++xb) + { + for (yb = 0; yb < m_iSizeYb; ++yb) + { + if (m_pVFDMem[xb][yb] != m_pDrawMem[xb][yb]) + { + m_pVFDMem[xb][yb] = m_pDrawMem[xb][yb]; + minX = std::min(minX, xb); + maxX = std::max(maxX, xb); + minYb = std::min(minYb, yb); + maxYb = std::max(maxYb, yb + 1); + doRefresh = true; + } + } + } + + m_nRefreshCounter = (m_nRefreshCounter + 1) % config->refreshDisplay; + if (!refreshAll && !m_nRefreshCounter) + refreshAll = true; + + if (refreshAll || doRefresh) + { + if (refreshAll) { + minX = 0; + maxX = width; + minYb = 0; + maxYb = m_iSizeYb; + // and reset RefreshCounter + m_nRefreshCounter = 0; + } + + minX = std::max(minX, 0); + maxX = std::min(maxX, width - 1); + minYb = std::max(minYb, 0); + maxYb = std::min(maxYb, m_iSizeYb); + + port->Claim(); + + GU256X64Cmd(CURS_LOADDR); GU256X64Data(0x00); + GU256X64Cmd(CURS_HIADDR); GU256X64Data(0x00); + GU256X64Cmd(DATA_WRITE); + + for (xb = 0; xb < width; xb++) + { + for (yb = 0; yb < m_iSizeYb; yb++) + { + GU256X64Data((m_pVFDMem[xb][yb]) ^ (config->invert ? 0xff : 0x00)); + } + } + port->Release(); + } +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/gu256x64-372.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/gu256x64-372.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,73 @@ +/* + * GraphLCD driver library + * + * gu256x64-372.h - 8-bit driver module for Noritake GU256x64-372 + * VFD displays. The VFD is operating in its 8-bit + * mode connected to a single PC parallel port. + * + * based on: + * gu256x32f driver module for graphlcd + * (c) 2003 Andreas Brachold + * HD61830 device + * (c) 2001-2003 by Carsten Siebholz + * lcdproc 0.4 driver hd44780-ext8bit + * (c) 1999, 1995 Benjamin Tse + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas 'randy' Weinberger (randy AT smue.org) + */ + +#ifndef _GLCDDRIVERS_GU256X64_372_H_ +#define _GLCDDRIVERS_GU256X64_372_H_ + +#include "driver.h" + +namespace GLCD +{ + +class cDriverConfig; +class cParallelPort; + +class cDriverGU256X64_372 : public cDriver +{ + cParallelPort * port; + + cDriverConfig * config; + cDriverConfig * oldConfig; + + int m_iSizeYb; + int m_nRefreshCounter; + + unsigned char ** m_pDrawMem; // the draw "memory" + unsigned char ** m_pVFDMem; // the double buffed display "memory" + + long m_nTimingAdjustCmd; + bool m_bSleepIsInit; + + int CheckSetup(); + +protected: + void ClearVFDMem(); + void SetPixel(int x, int y); + void GU256X64Cmd(unsigned char data); + void GU256X64Data(unsigned char data); + +public: + cDriverGU256X64_372(cDriverConfig * config); + virtual ~cDriverGU256X64_372(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); + + virtual void SetBrightness(unsigned int percent); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/gu256x64-3900.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/gu256x64-3900.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,651 @@ +/* + * GraphLCD driver library + * + * gu256x64-3900.c - 8-bit driver module for Noritake GU256X64x-3900 + * VFD displays. The VFD is either operating in + * 8-bit mode connected to a single PC parallel + * port or in serial mode connected to a single PC + * serial port. + * + * based on: + * gu256x64-372 driver module for graphlcd + * (c) 2004 Andreas 'randy' Weinberger + * gu256x32f driver module for graphlcd + * (c) 2003 Andreas Brachold + * HD61830 device + * (c) 2001-2003 by Carsten Siebholz + * lcdproc 0.4 driver hd44780-ext8bit + * (c) 1999, 1995 Benjamin Tse + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Ralf Mueller (ralf AT bj-ig.de) + */ + +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "config.h" +#include "gu256x64-3900.h" +#include "port.h" + + +namespace GLCD +{ + +static const unsigned char dSETSTART0 = 0x02; // Set display start address (CMD prefix) +static const unsigned char dSETSTART1 = 0x44; // Set display start address (CMD) +static const unsigned char dSETSTART2 = 0x00; // Set display start address +static const unsigned char dSETSTART3 = 0x53; // Set display start address + +static const unsigned char nINITDISPLAY0 = 0x1b; // Initialize display (CMD prefix) +static const unsigned char nINITDISPLAY1 = 0x40; // Initialize display (CMD) + +static const unsigned char nPOWER0 = 0x1f; // Power on/off +static const unsigned char nPOWER1 = 0x28; // Power on/off +static const unsigned char nPOWER2 = 0x61; // Power on/off +static const unsigned char nPOWER3 = 0x40; // Power on/off + +static const unsigned char nSETBRIGHT0 = 0x1f; // Set brightness (CMD prefix) +static const unsigned char nSETBRIGHT1 = 0x58; // Set brightness (CMD) + +static const unsigned char dSETBRIGHT0 = 0x02; // Set brightness (CMD prefix) +static const unsigned char dSETBRIGHT1 = 0x44; // Set brightness (CMD) +static const unsigned char dSETBRIGHT2 = 0x00; // Set brightness +static const unsigned char dSETBRIGHT3 = 0x58; // Set brightness + +static const unsigned char BRIGHT_000 = 0x10; // Brightness 0% +static const unsigned char BRIGHT_012 = 0x11; // Brightness 12.5% +static const unsigned char BRIGHT_025 = 0x12; // Brightness 25% +static const unsigned char BRIGHT_037 = 0x13; // Brightness 37.5% +static const unsigned char BRIGHT_050 = 0x14; // Brightness 50% +static const unsigned char BRIGHT_062 = 0x15; // Brightness 62.5% +static const unsigned char BRIGHT_075 = 0x16; // Brightness 75% +static const unsigned char BRIGHT_087 = 0x17; // Brightness 87.5% +static const unsigned char BRIGHT_100 = 0x18; // Brightness 100% + +static const unsigned char nSETCURSOR0 = 0x1f; // Set cursor (CMD prefix) +static const unsigned char nSETCURSOR1 = 0x24; // Set cursor (CMD) + +static const unsigned char nDISPLAYCURSOR0 = 0x1f; // display cursor +static const unsigned char nDISPLAYCURSOR1 = 0x43; // display cursor + +static const unsigned char nBLITIMAGE0 = 0x1f; // Display image +static const unsigned char nBLITIMAGE1 = 0x28; // Display image +static const unsigned char nBLITIMAGE2 = 0x66; // Display image +static const unsigned char nBLITIMAGE3 = 0x11; // Display image + +static const unsigned char dBLITIMAGE0 = 0x02; // Image write +static const unsigned char dBLITIMAGE1 = 0x44; // Image write +static const unsigned char dBLITIMAGE2 = 0x00; // Image write +static const unsigned char dBLITIMAGE3 = 0x46; // Image write + + +static const unsigned char WRHI = 0x0f; // any control pin to high +static const unsigned char WRLO = 0x00; +static const unsigned char RDYHI = 0x40; // RDY +static const unsigned char RDYHIALT = 0x80; // RDY satyr wiring +static const unsigned char RDYLO = 0x00; + +static const std::string kWiringStandard = "Standard"; +static const std::string kWiringSatyr = "Satyr"; + +static const int kInterfaceParallel = 0; // parallel mode +static const int kInterfaceSerial = 1; // serial mode + + +cDriverGU256X64_3900::cDriverGU256X64_3900(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); + + portFd = -1; + m_nRefreshCounter = 0; +} + +cDriverGU256X64_3900::~cDriverGU256X64_3900() +{ + delete oldConfig; +} + +int cDriverGU256X64_3900::Init() +{ + int x; + + width = config->width; + if (width <= 0) + width = 256; + height = config->height; + if (height <= 0) + height = 64; + m_iSizeYb = ((height + 7) / 8); + + // default values + readyMask = RDYHI; + readyHi = RDYHI; + interface = kInterfaceParallel; + useDMA = true; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "Wiring") + { + if (config->options[i].value == kWiringStandard) + { + readyMask = RDYHI; + readyHi = RDYHI; + } + else if (config->options[i].value == kWiringSatyr) + { + readyMask = RDYHIALT; + readyHi = RDYLO; + } + else + syslog(LOG_ERR, "%s error: wiring %s not supported, using default (Standard)!\n", + config->name.c_str(), config->options[i].value.c_str()); + } + if (config->options[i].name == "Interface") + { + if (config->options[i].value == "Parallel") + interface = kInterfaceParallel; + else if (config->options[i].value == "Serial") + interface = kInterfaceSerial; + else + syslog(LOG_ERR, "%s error: interface %s not supported, using default (Parallel)!\n", + config->name.c_str(), config->options[i].value.c_str()); + } + else if (config->options[i].name == "DMA") + { + if (config->options[i].value == "yes") + useDMA = true; + else if (config->options[i].value == "no") + useDMA = false; + else + syslog(LOG_ERR, "%s error: unknown DMA setting %s, using default (%s)!\n", + config->name.c_str(), config->options[i].value.c_str(), useDMA ? "yes" : "no"); + } + } + + if (interface == kInterfaceParallel) + port = new cParallelPort(); + else + port = NULL; + + // setup linear lcd array + m_pDrawMem = new unsigned char *[width]; + if (m_pDrawMem) + { + for (x = 0; x < width; x++) + { + m_pDrawMem[x] = new unsigned char[m_iSizeYb]; + memset(m_pDrawMem[x], 0, m_iSizeYb); + } + } + Clear(); + + // setup the lcd array for the "vertical" mem + m_pVFDMem = new unsigned char *[width]; + if (m_pVFDMem) + { + for (x = 0; x < width; x++) + { + m_pVFDMem[x] = new unsigned char[m_iSizeYb]; + memset(m_pVFDMem[x], 0, m_iSizeYb); + } + } + ClearVFDMem(); + + if (interface == kInterfaceSerial) + { + if (InitSerialPort() < 0) + return -1; + } + else + { + if (InitParallelPort() < 0) + return -1; + } + + if (useDMA) + InitDMADisplay(); + else + InitNormalDisplay(); + + if (interface == kInterfaceParallel) + { + // claim is in InitParallelPort + port->Release(); + } + + *oldConfig = *config; + + // Set Display SetBrightness + SetBrightness(config->brightness); + // clear display + Clear(); + ClearVFDMem(); + + syslog(LOG_INFO, "%s: gu256x64-3900 initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverGU256X64_3900::DeInit() +{ + int x; + + if (m_pVFDMem) + { + for (x = 0; x < width; x++) + { + delete[] m_pVFDMem[x]; + } + delete[] m_pVFDMem; + } + if (m_pDrawMem) + { + for (x = 0; x < width; x++) + { + delete[] m_pDrawMem[x]; + } + delete[] m_pDrawMem; + } + + if (interface == kInterfaceSerial) + { + if (portFd >= 0) + { + close(portFd); + portFd =- 1; + } + } + if (port) + { + if (port->Close() != 0) + { + return -1; + } + delete port; + port = NULL; + } + return 0; +} + +int cDriverGU256X64_3900::CheckSetup() +{ + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->brightness != oldConfig->brightness) + { + oldConfig->brightness = config->brightness; + SetBrightness(config->brightness); + } + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +int cDriverGU256X64_3900::InitSerialPort() +{ + if (config->device == "") + { + syslog(LOG_ERR, "%s: unable to initialize gu256x64-3900!\n", config->name.c_str()); + return -1; + } + + portFd = open(config->device.c_str(), O_RDWR | O_NOCTTY); + if (portFd >= 0) + { + struct termios options; + tcgetattr(portFd, &options); + cfsetispeed(&options, B38400); + cfsetospeed(&options, B38400); + options.c_cflag &= ~CSIZE; + options.c_cflag &= ~PARENB; + options.c_cflag &= ~CSTOPB; + options.c_cflag |= CS8; + tcsetattr(portFd, TCSANOW, &options); + } + else + { + syslog(LOG_ERR, "%s: unable to initialize gu256x64-3900!\n", config->name.c_str()); + return -1; + } + return 0; +} + +int cDriverGU256X64_3900::InitParallelPort() +{ + struct timeval tv1, tv2; + + if (config->device == "") + { + // use DirectIO + if (port->Open(config->port) != 0) + { + syslog(LOG_ERR, "%s: unable to initialize gu256x64-3900!\n", config->name.c_str()); + return -1; + } + uSleep(10); + } + else + { + // use ppdev + if (port->Open(config->device.c_str()) != 0) + { + syslog(LOG_ERR, "%s: unable to initialize gu256x64-3900!\n", config->name.c_str()); + return -1; + } + } + + if (nSleepInit() != 0) + { + syslog(LOG_ERR, "%s: INFO: cannot change wait parameters Err: %s (cDriver::Init)\n", config->name.c_str(), strerror(errno)); + m_bSleepIsInit = false; + } + else + { + m_bSleepIsInit = true; + } + + port->Claim(); + + syslog(LOG_DEBUG, "%s: benchmark started.\n", config->name.c_str()); + gettimeofday(&tv1, 0); + for (int x = 0; x < 1000; x++) + { + port->WriteData(x % 0x100); + } + gettimeofday(&tv2, 0); + nSleepDeInit(); + m_nTimingAdjustCmd = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec); + syslog(LOG_INFO, "%s: benchmark stopped. Time for Port Command: %ldns\n", config->name.c_str(), m_nTimingAdjustCmd); + + return 0; +} + +void cDriverGU256X64_3900::InitNormalDisplay() +{ + Write(nPOWER0); + Write(nPOWER1); + Write(nPOWER2); + Write(nPOWER3); + Write(1); // power on + + Write(nINITDISPLAY0); + Write(nINITDISPLAY1); + + Write(nDISPLAYCURSOR0); + Write(nDISPLAYCURSOR1); + Write(0); // off + + Write(nSETCURSOR0); + Write(nSETCURSOR1); + Write(0); // low byte x + Write(0); // high byte x + Write(0); // low byte y + Write(0); // high byte y +} + +void cDriverGU256X64_3900::InitDMADisplay() +{ + Write(dSETSTART0); + Write(dSETSTART1); + Write(dSETSTART2); + Write(dSETSTART3); + Write(0); + Write(0); +} + +void cDriverGU256X64_3900::ClearVFDMem() +{ + for (int x = 0; x < width; x++) + memset(m_pVFDMem[x], 0, m_iSizeYb); +} + +void cDriverGU256X64_3900::Clear() +{ + for (int x = 0; x < width; x++) + memset(m_pDrawMem[x], 0, m_iSizeYb); +} + +void cDriverGU256X64_3900::SetBrightness(unsigned int percent) +{ + if (interface == kInterfaceParallel) + port->Claim(); + + if (interface == kInterfaceParallel && useDMA) + { + Write(dSETBRIGHT0); + Write(dSETBRIGHT1); + Write(dSETBRIGHT2); + Write(dSETBRIGHT3); + } + else + { + Write(nSETBRIGHT0); + Write(nSETBRIGHT1); + } + if (percent > 87) { + Write(BRIGHT_100); + } else if (percent > 75) { + Write(BRIGHT_087); + } else if (percent > 62) { + Write(BRIGHT_075); + } else if (percent > 50) { + Write(BRIGHT_062); + } else if (percent > 37) { + Write(BRIGHT_050); + } else if (percent > 25) { + Write(BRIGHT_037); + } else if (percent > 12) { + Write(BRIGHT_025); + } else if (percent > 1) { + Write(BRIGHT_012); + } else { + Write(BRIGHT_000); + } + if (interface == kInterfaceParallel) + port->Release(); +} + +void cDriverGU256X64_3900::WriteParallel(unsigned char data) +{ + if (m_bSleepIsInit) + nSleepInit(); + if ((port->ReadStatus() & readyMask) != readyHi) + { + int i = 0; + int status = port->ReadStatus(); + for (; ((status&readyMask) != readyHi) && i < 1000; i++) + { + // wait until display ack's write but not forever + status=port->ReadStatus(); + } + } + + port->WriteControl(WRLO); + port->WriteData(data); + nSleep(100 + (100 * config->adjustTiming) - m_nTimingAdjustCmd); + port->WriteControl(WRHI); + nSleep(500 + (100 * config->adjustTiming) - m_nTimingAdjustCmd); +} + +void cDriverGU256X64_3900::WriteSerial(unsigned char data) +{ + write(portFd, &data, 1); +} + +void cDriverGU256X64_3900::Write(unsigned char data) +{ + if (interface == kInterfaceSerial) + WriteSerial(data); + else + WriteParallel(data); +} + +void cDriverGU256X64_3900::SetPixel(int x, int y) +{ + unsigned char c; + + if (!m_pDrawMem) + return; + + if (x >= width || x < 0) + return; + if (y >= height || y < 0) + return; + + if (config->upsideDown) + { + x = width - 1 - x; + y = height - 1 - y; + } + + c = 0x80 >> (y % 8); + + m_pDrawMem[x][y/8] = m_pDrawMem[x][y/8] | c; +} + +void cDriverGU256X64_3900::Set8Pixels(int x, int y, unsigned char data) +{ + int n; + + // x - pos is'nt maybe align to 8 + x &= 0xFFF8; + + for (n = 0; n < 8; ++n) + { + if (data & (0x80 >> n)) // if bit is set + SetPixel(x + n, y); + } +} + +void cDriverGU256X64_3900::Refresh(bool refreshAll) +{ + int xb, yb; + + if (!m_pVFDMem || !m_pDrawMem) + return; + + bool doRefresh = false; + int minX = width; + int maxX = 0; + int minYb = m_iSizeYb; + int maxYb = 0; + + if (CheckSetup() > 0) + refreshAll = true; + + for (xb = 0; xb < width; ++xb) + { + for (yb = 0; yb < m_iSizeYb; ++yb) + { + if (m_pVFDMem[xb][yb] != m_pDrawMem[xb][yb]) + { + m_pVFDMem[xb][yb] = m_pDrawMem[xb][yb]; + minX = std::min(minX, xb); + maxX = std::max(maxX, xb); + minYb = std::min(minYb, yb); + maxYb = std::max(maxYb, yb + 1); + doRefresh = true; + } + } + } + + if (config->refreshDisplay > 0) + { + m_nRefreshCounter = (m_nRefreshCounter + 1) % config->refreshDisplay; + if (!refreshAll && !m_nRefreshCounter) + refreshAll = true; + } + + if (refreshAll || doRefresh) + { + if (refreshAll) + { + minX = 0; + maxX = width; + minYb = 0; + maxYb = m_iSizeYb; + // and reset RefreshCounter + m_nRefreshCounter = 0; + } + + minX = std::max(minX, 0); + maxX = std::min(maxX, width - 1); + minYb = std::max(minYb, 0); + maxYb = std::min(maxYb, m_iSizeYb); + + if (interface == kInterfaceParallel) + port->Claim(); + + if (interface == kInterfaceParallel && useDMA) + { + Write(dBLITIMAGE0); + Write(dBLITIMAGE1); + Write(dBLITIMAGE2); + Write(dBLITIMAGE3); + Write(0); // low byte address + Write(0); // high byte address + Write((m_iSizeYb*width)&0xff); // low byte size + Write((m_iSizeYb*width)>>8); // high byte size + } + else + { + Write(nSETCURSOR0); + Write(nSETCURSOR1); + Write(0); // low byte x + Write(0); // high byte x + Write(0); // low byte y + Write(0); // high byte y + + Write(nBLITIMAGE0); + Write(nBLITIMAGE1); + Write(nBLITIMAGE2); + Write(nBLITIMAGE3); + Write(width&0xff); // low byte width + Write(width>>8); // high byte width + Write(m_iSizeYb); // low byte height + Write(0); // high byte height + Write(1); // end header + } + + for (xb = 0; xb < width; xb++) + { + for (yb = 0; yb < m_iSizeYb; yb++) + { + Write((m_pVFDMem[xb][yb]) ^ (config->invert ? 0xff : 0x00)); + } + // parallel port writing is busy waiting - with realtime priority you + // can lock the system - so don't be so greedy ;) + if ((xb % 32) == 31) + { + uSleep(1000); + } + } + + if (interface == kInterfaceParallel) + port->Release(); + } +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/gu256x64-3900.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/gu256x64-3900.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,87 @@ +/* + * GraphLCD driver library + * + * gu256x64-3900.h - 8-bit driver module for Noritake GU256X64x-3900 + * VFD displays. The VFD is either operating in + * 8-bit mode connected to a single PC parallel + * port or in serial mode connected to a single PC + * serial port. + * + * based on: + * gu256x64-372 driver module for graphlcd + * (c) 2004 Andreas 'randy' Weinberger + * gu140x32f driver module for graphlcd + * (c) 2003 Andreas Brachold + * HD61830 device + * (c) 2001-2003 by Carsten Siebholz + * lcdproc 0.4 driver hd44780-ext8bit + * (c) 1999, 1995 Benjamin Tse + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Ralf Mueller (ralf AT bj-ig.de) + */ + +#ifndef _GLCDDRIVERS_GU256X64_3900_H_ +#define _GLCDDRIVERS_GU256X64_3900_H_ + +#include "driver.h" + +namespace GLCD +{ + +class cDriverConfig; +class cParallelPort; + +class cDriverGU256X64_3900 : public cDriver +{ + cParallelPort * port; + int portFd; + + cDriverConfig * config; + cDriverConfig * oldConfig; + + int m_iSizeYb; + int m_nRefreshCounter; + int interface; + bool useDMA; + unsigned char readyMask; + unsigned char readyHi; + + unsigned char ** m_pDrawMem; // the draw "memory" + unsigned char ** m_pVFDMem; // the double buffed display "memory" + + long m_nTimingAdjustCmd; + bool m_bSleepIsInit; + + int CheckSetup(); + +protected: + void ClearVFDMem(); + void SetPixel(int x, int y); + int InitSerialPort(); + int InitParallelPort(); + void InitNormalDisplay(); + void InitDMADisplay(); + + void WriteSerial(unsigned char data); + void WriteParallel(unsigned char data); + void Write(unsigned char data); +public: + cDriverGU256X64_3900(cDriverConfig * config); + virtual ~cDriverGU256X64_3900(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); + + virtual void SetBrightness(unsigned int percent); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/hd61830.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/hd61830.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,391 @@ +/* + * GraphLCD driver library + * + * hd61830.c - HD61830 driver class + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2001-2004 Carsten Siebholz + */ + +#include +#include + +#include "common.h" +#include "config.h" +#include "hd61830.h" +#include "port.h" + + +namespace GLCD +{ + +// commands +#define MCNT 0x00 +#define CPIT 0x01 +#define NOCH 0x02 +#define NOTD 0x03 +#define CPOS 0x04 + +#define DSAL 0x08 +#define DSAH 0x09 +#define CACL 0x0A +#define CACH 0x0B + +#define WDDI 0x0C +#define RDDI 0x0D + +#define CBIT 0x0E +#define SBIT 0x0F + +// control bits for DirectIO +#define EN 0x01 +#define ENHI 0x00 +#define ENLO 0x01 + +#define RW 0x02 +#define RWHI 0x00 +#define RWLO 0x02 + +#define RS 0x04 +#define RSHI 0x04 +#define RSLO 0x00 + + +cDriverHD61830::cDriverHD61830(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); + + port = new cParallelPort(); + + useSleepInit = false; + + refreshCounter = 0; + timeForPortCmdInNs = 0; +} + +cDriverHD61830::~cDriverHD61830() +{ + delete port; + delete oldConfig; +} + +int cDriverHD61830::Init() +{ + int i; + int x; + struct timeval tv1, tv2; + + width = config->width; + if (width <= 0) + width = 240; + height = config->height; + if (height <= 0) + height = 128; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "") + { + } + } + + // setup lcd array (wanted state) + newLCD = new unsigned char *[(width + 7) / 8]; + if (newLCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + newLCD[x] = new unsigned char[height]; + memset(newLCD[x], 0, height); + } + } + // setup lcd array (current state) + oldLCD = new unsigned char*[(width + 7) / 8]; + if (oldLCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + oldLCD[x] = new unsigned char[height]; + memset(oldLCD[x], 0, height); + } + } + + if (config->device == "") + { + // use DirectIO + if (port->Open(config->port) != 0) + return -1; + uSleep(10); + } + else + { + // use ppdev + if (port->Open(config->device.c_str()) != 0) + return -1; + } + + if (nSleepInit() != 0) + { + syslog(LOG_DEBUG, "%s: INFO: cannot change wait parameters (cDriver::Init)\n", config->name.c_str()); + useSleepInit = false; + } + else + { + useSleepInit = true; + } + + syslog(LOG_DEBUG, "%s: benchmark started.\n", config->name.c_str()); + gettimeofday(&tv1, 0); + for (i = 0; i < 1000; i++) + { + port->WriteData(1 % 0x100); + } + gettimeofday(&tv2, 0); + if (useSleepInit) + nSleepDeInit(); + timeForPortCmdInNs = (tv2.tv_sec-tv1.tv_sec) * 1000000 + (tv2.tv_usec-tv1.tv_usec); + syslog(LOG_DEBUG, "%s: benchmark stopped. Time for Port Command: %ldns\n", config->name.c_str(), timeForPortCmdInNs); + + // initialize graphic mode + InitGraphic(); + + port->Release(); + + *oldConfig = *config; + + // clear display + Clear(); + + syslog(LOG_INFO, "%s: HD61830 initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverHD61830::DeInit() +{ + int x; + + // free lcd array (wanted state) + if (newLCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + delete[] newLCD[x]; + } + delete[] newLCD; + } + // free lcd array (current state) + if (oldLCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + delete[] oldLCD[x]; + } + delete[] oldLCD; + } + if (port->Close() != 0) + return -1; + return 0; +} + +int cDriverHD61830::CheckSetup() +{ + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +int cDriverHD61830::InitGraphic() +{ + Write(MCNT, 0x32); // set Mode Control Register + // DISP ON, MASTER ON, BLINK OFF, CURSOR OFF, GRAPHIC-Mode, int.Clock + Write(CPIT, 0x07); // set Character Pitch Register + // 8 pixels per byte + Write(NOCH, std::max(1, (width + 7) / 8 - 1)); // set Number-Of-Characters Register + // (width - 1) / 8 bytes per line horizontally + Write(NOTD, std::max(1, height - 1)); // set Number-Of-Time-Divisions Register + // height - 1 + Write(CPOS, 0x00); // set Cursor Position Register + // optional, because we havn't enabled a cursor + Write(DSAL, 0x00); // set Display Start Address Register (Low Order Byte) + Write(DSAH, 0x00); // set Display Start Address Register (High Order Byte) + Write(CACL, 0x00); // set Cursor Address Counter Register (Low Order Byte) + Write(CACH, 0x00); // set Cursor Address Counter Register (High Order Byte) + + return 0; +} + +void cDriverHD61830::Write(unsigned char cmd, unsigned char data) +{ + if (useSleepInit) + nSleepInit(); + + // set RS high (instruction), RW low (write) and E low + port->WriteControl(RSHI | RWLO | ENLO); + nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming); + + // Output the actual command + port->WriteData(cmd); + + // set E high + port->WriteControl(RSHI | RWLO | ENHI); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + + // set E low + port->WriteControl(RSHI | RWLO | ENLO); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + + + // set RS low (data), RW low (write) and E low + port->WriteControl(RSLO | RWLO | ENLO); + nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming); + + // Output the actual data + port->WriteData(data); + + // set E high + port->WriteControl(RSLO | RWLO | ENHI); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + + // set E low + port->WriteControl(RSLO | RWLO | ENLO); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + + switch (cmd) + { + case MCNT: + case CPIT: + case NOCH: + case NOTD: + case CPOS: + case DSAL: + case DSAH: + case CACL: + case CACH: + nSleep(4000 - std::max(450l, timeForPortCmdInNs) + 100 * config->adjustTiming); + break; + case WDDI: + case RDDI: + nSleep(6000 - std::max(450l, timeForPortCmdInNs) + 100 * config->adjustTiming); + break; + case CBIT: + case SBIT: + nSleep(36000 - std::max(450l, timeForPortCmdInNs) + 100 * config->adjustTiming); + break; + } + if (useSleepInit) + nSleepDeInit(); +} + +void cDriverHD61830::Clear() +{ + for (int x = 0; x < (width + 7) / 8; x++) + memset(newLCD[x], 0, height); +} + +void cDriverHD61830::Set8Pixels(int x, int y, unsigned char data) +{ + if (x >= width || y >= height) + return; + + if (!config->upsideDown) + { + // normal orientation + newLCD[x / 8][y] = newLCD[x / 8][y] | ReverseBits(data); + } + else + { + // upside down orientation + x = width - 1 - x; + y = height - 1 - y; + newLCD[x / 8][y] = newLCD[x / 8][y] | data; + } +} + +void cDriverHD61830::Refresh(bool refreshAll) +{ + int x; + int y; + int pos = 0; + + if (CheckSetup() > 0) + refreshAll = true; + + if (config->refreshDisplay > 0) + { + refreshCounter = (refreshCounter + 1) % config->refreshDisplay; + if (!refreshAll && !refreshCounter) + refreshAll = true; + } + + port->Claim(); + + if (refreshAll) + { + // draw all + + for (y = 0; y < height; y++) + { + for (x = 0; x < (width + 7) / 8; x++) + { + // (re-setting the cursor position + // might be removed, when the graphic glitches are solved) + Write(CACL, (pos % 0x100)); + Write(CACH, (pos / 0x100)); + Write(WDDI, (newLCD[x][y]) ^ (config->invert ? 0xff : 0x00)); + oldLCD[x][y] = newLCD[x][y]; + pos++; + } + } + // and reset RefreshCounter + refreshCounter = 0; + } + else + { + // draw only the changed bytes + + bool cs = false; + for (y = 0; y < height; y++) + { + for (x = 0; x < (width + 7) / 8; x++) + { + if (newLCD[x][y] != oldLCD[x][y]) + { + if (!cs) + { + Write(CACL, (pos % 0x100)); + Write(CACH, (pos / 0x100)); + cs = true; + } + Write(WDDI, (newLCD[x][y]) ^ (config->invert ? 0xff : 0x00)); + oldLCD[x][y] = newLCD[x][y]; + } + else + { + cs = false; + } + pos++; + } + } + } + port->Release(); +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/hd61830.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/hd61830.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,54 @@ +/* + * GraphLCD driver library + * + * hd61830.h - HD61830 driver class + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2001-2004 Carsten Siebholz + */ + +#ifndef _GLCDDRIVERS_HD61830_H_ +#define _GLCDDRIVERS_HD61830_H_ + +#include "driver.h" + +namespace GLCD +{ + +class cDriverConfig; +class cParallelPort; + +class cDriverHD61830 : public cDriver +{ +private: + cParallelPort * port; + + unsigned char ** newLCD; // wanted state + unsigned char ** oldLCD; // current state + cDriverConfig * config; + cDriverConfig * oldConfig; + int refreshCounter; + long timeForPortCmdInNs; + bool useSleepInit; + + int CheckSetup(); + int InitGraphic(); + void Write(unsigned char cmd, unsigned char data); + +public: + cDriverHD61830(cDriverConfig * config); + virtual ~cDriverHD61830(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/image.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/image.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,167 @@ +/* + * GraphLCD driver library + * + * image.c - Image output device + * Output goes to a image file instead of LCD. + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include + +#include "common.h" +#include "config.h" +#include "image.h" + + +namespace GLCD +{ + +cDriverImage::cDriverImage(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); +} + +cDriverImage::~cDriverImage() +{ + delete oldConfig; +} + +int cDriverImage::Init() +{ + width = config->width; + if (width <= 0) + width = 240; + height = config->height; + if (height <= 0) + height = 128; + lineSize = (width + 7) / 8; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "") + { + } + } + + newLCD = new unsigned char[lineSize * height]; + if (newLCD) + memset(newLCD, 0, lineSize * height); + oldLCD = new unsigned char[lineSize * height]; + if (oldLCD) + memset(oldLCD, 0, lineSize * height); + + counter = 0; + + *oldConfig = *config; + + // clear display + Clear(); + + syslog(LOG_INFO, "%s: image driver initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverImage::DeInit() +{ + if (newLCD) + delete[] newLCD; + if (oldLCD) + delete[] oldLCD; + return 0; +} + +int cDriverImage::CheckSetup() +{ + if (config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +void cDriverImage::Clear() +{ + memset(newLCD, 0, lineSize * height); +} + +void cDriverImage::Set8Pixels(int x, int y, unsigned char data) +{ + if (x >= width || y >= height) + return; + + if (!config->upsideDown) + { + // normal orientation + newLCD[lineSize * y + x / 8] |= data; + } + else + { + // upside down orientation + x = width - 1 - x; + y = height - 1 - y; + newLCD[lineSize * y + x / 8] |= ReverseBits(data); + } +} + +void cDriverImage::Refresh(bool refreshAll) +{ + int i; + bool refresh; + char fileName[256]; + char str[32]; + FILE * fp; + unsigned char c; + + refresh = false; + if (CheckSetup() > 0) + refresh = true; + + for (i = 0; i < lineSize * height; i++) + { + if (newLCD[i] != oldLCD[i]) + { + refresh = true; + break; + } + } + + if (refresh) + { + sprintf(fileName, "%s/%s%05d.%s", "/tmp", "lcd", counter, "pbm"); + fp = fopen(fileName, "wb"); + if (fp) + { + sprintf(str, "P4\n%d %d\n", width, height); + fwrite(str, strlen(str), 1, fp); + for (i = 0; i < lineSize * height; i++) + { + c = newLCD[i] ^ (config->invert ? 0xff : 0x00); + fwrite(&c, 1, 1, fp); + oldLCD[i] = newLCD[i]; + } + fclose(fp); + } + counter++; + if (counter > 99999) + counter = 0; + } +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/image.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/image.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,50 @@ +/* + * GraphLCD driver library + * + * image.h - Image output device + * Output goes to a image file instead of LCD. + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDDRIVERS_IMAGE_H_ +#define _GLCDDRIVERS_IMAGE_H_ + +#include "driver.h" + + +namespace GLCD +{ + +class cDriverConfig; + +class cDriverImage : public cDriver +{ +private: + unsigned char * newLCD; + unsigned char * oldLCD; + cDriverConfig * config; + cDriverConfig * oldConfig; + int lineSize; + int counter; + + int CheckSetup(); + +public: + cDriverImage(cDriverConfig * config); + virtual ~cDriverImage(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/ks0108.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/ks0108.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,593 @@ +/* + * GraphLCD driver library + * + * ks0108.c - KS0108 driver class + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003 Andreas 'randy' Weinberger + */ + +#include +#include + +#include "common.h" +#include "config.h" +#include "ks0108.h" +#include "port.h" + + +namespace GLCD +{ + +// commands +const unsigned char kSEAD = 0x40; // Set (X) Address +const unsigned char kSEPA = 0xb8; // Set (Y) Page +const unsigned char kSEDS = 0xc0; // Set Display Start Line +const unsigned char kDIOF = 0x3e; // Display off +const unsigned char kDION = 0x3f; // Display on + +const unsigned char kCEHI = 0x01; // Chip Enable on +const unsigned char kCELO = 0x00; +const unsigned char kCDHI = 0x08; // Command/Data Register Select +const unsigned char kCDLO = 0x00; + +const unsigned char kCS1HI = 0x02; // ChipSelect 1 +const unsigned char kCS1LO = 0x00; +const unsigned char kCS2HI = 0x00; // ChipSelect 2 +const unsigned char kCS2LO = 0x04; + + +cDriverKS0108::cDriverKS0108(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); + + port = new cParallelPort(); + + refreshCounter = 0; + timeForLCDInNs = 50; + control = 1; +} + +cDriverKS0108::~cDriverKS0108() +{ + delete port; + delete oldConfig; +} + +int cDriverKS0108::Init() +{ + int x; + int i; + struct timeval tv1, tv2; + + if (config->width <= 128) { + width = 128; + } else if (config->width > 192) { + width = 256; + } else if (config->width > 128) { + width = 192; + } + + if (config->height <= 64) { + height = 64; + } else if (config->height > 64) { + height = 128; + width = 128; // force 2* 128x64 display + } + + if (width == 128 && height == 64) { + CS1 = kCS2HI | kCS1LO; + CS2 = kCS2LO | kCS1HI; + CS3 = -1; // invalid + CS4 = -1; + } else { // multiplexed via 74LS42 + CS1 = kCS2HI | kCS1HI; + CS2 = kCS2HI | kCS1LO; + CS3 = kCS2LO | kCS1HI; + CS4 = kCS2LO | kCS1LO; + } + + SEAD = kSEAD; + SEPA = kSEPA; + SEDS = kSEDS; + DIOF = kDIOF; + DION = kDION; + + CEHI = kCEHI; + CELO = kCELO; + CDHI = kCDHI; + CDLO = kCDLO; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "Control") + { + if (config->options[i].value == "0") + control = 0; + else if (config->options[i].value == "1") + control = 1; + else + syslog(LOG_ERR, "%s error: unknown control setting %s, using default (%d)!\n", + config->name.c_str(), config->options[i].value.c_str(), control); + } + } + + // setup linear lcd array + LCD = new unsigned char *[(width + 7) / 8]; + if (LCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + LCD[x] = new unsigned char[height]; + memset(LCD[x], 0, height); + } + } + // setup the lcd array for the paged ks0108 + LCD_page = new unsigned char *[width]; + if (LCD_page) + { + for (x = 0; x < width; x++) + { + LCD_page[x] = new unsigned char[(height + 7) / 8]; + memset(LCD_page[x], 0, (height + 7) / 8); + } + } + + if (config->device == "") + { + // use DirectIO + if (port->Open(config->port) != 0) + return -1; + uSleep(10); + } + else + { + // use ppdev + if (port->Open(config->device.c_str()) != 0) + return -1; + } + + if (nSleepInit() != 0) + { + syslog(LOG_DEBUG, "%s: INFO: cannot change wait parameters (cDriver::Init)\n", config->name.c_str()); + useSleepInit = false; + } + else + { + useSleepInit = true; + } + + syslog(LOG_DEBUG, "%s: benchmark started.\n", config->name.c_str()); + gettimeofday(&tv1, 0); + for (i = 0; i < 1000; i++) + { + port->WriteData(i % 0x100); + } + gettimeofday(&tv2, 0); + if (useSleepInit) + nSleepDeInit(); + timeForPortCmdInNs = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec); + syslog(LOG_DEBUG, "%s: benchmark stopped. Time for Command: %ldns\n", config->name.c_str(), timeForPortCmdInNs); + + // initialize graphic mode + InitGraphic(); + + port->Release(); + + *oldConfig = *config; + + // clear display + Clear(); + + syslog(LOG_INFO, "%s: KS0108 initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverKS0108::DeInit() +{ + int x; + + // free linear lcd array + if (LCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + delete[] LCD[x]; + } + delete[] LCD; + } + // free paged lcd array + if (LCD_page) + { + for (x = 0; x < width; x++) + { + delete[] LCD_page[x]; + } + delete[] LCD_page; + } + if (port->Close() != 0) + return -1; + return 0; +} + +int cDriverKS0108::CheckSetup() +{ + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +int cDriverKS0108::InitGraphic() +{ + // init controllers + if (CS1 > -1) { + KS0108Cmd(SEDS, 1); + KS0108Cmd(SEPA, 1); + KS0108Cmd(SEAD, 1); + KS0108Cmd(DION, 1); + } + if (CS2 > -1) { + KS0108Cmd(SEDS, 2); + KS0108Cmd(SEPA, 2); + KS0108Cmd(SEAD, 2); + KS0108Cmd(DION, 2); + } + if (CS3 > -1) { + KS0108Cmd(SEDS, 3); + KS0108Cmd(SEPA, 3); + KS0108Cmd(SEAD, 3); + KS0108Cmd(DION, 3); + } + if (CS4 > -1) { + KS0108Cmd(SEDS, 4); + KS0108Cmd(SEPA, 4); + KS0108Cmd(SEAD, 4); + KS0108Cmd(DION, 4); + } + return 0; +} + +void cDriverKS0108::KS0108Cmd(unsigned char data, int cs) +{ + if (useSleepInit) + nSleepInit(); + switch (cs) { + case 1: + if (control == 1) + port->WriteControl(CDHI | CS1 | CELO); + else + port->WriteControl(CDHI | CS1 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + port->WriteData(data); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + if (control == 1) + { + port->WriteControl(CDHI | CS1 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + } + port->WriteControl(CDHI | CS1 | CELO); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + break; + case 2: + if (control == 1) + port->WriteControl(CDHI | CS2 | CELO); + else + port->WriteControl(CDHI | CS2 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + port->WriteData(data); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + if (control == 1) + { + port->WriteControl(CDHI | CS2 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + } + port->WriteControl(CDHI | CS2 | CELO); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + break; + case 3: + if (control == 1) + port->WriteControl(CDHI | CS3 | CELO); + else + port->WriteControl(CDHI | CS3 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + port->WriteData(data); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + if (control == 1) + { + port->WriteControl(CDHI | CS3 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + } + port->WriteControl(CDHI | CS3 | CELO); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + break; + case 4: + if (control == 1) + port->WriteControl(CDHI | CS4 | CELO); + else + port->WriteControl(CDHI | CS4 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + port->WriteData(data); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + if (control == 1) + { + port->WriteControl(CDHI | CS4 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + } + port->WriteControl(CDHI | CS4 | CELO); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + break; + } + if (useSleepInit) + nSleepDeInit(); +} + +void cDriverKS0108::KS0108Data(unsigned char data, int cs) +{ + if (useSleepInit) + nSleepInit(); + switch (cs) { + case 1: + if (control == 1) + port->WriteControl(CDLO | CS1 | CELO); + else + port->WriteControl(CDLO | CS1 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + port->WriteData(data); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + if (control == 1) + { + port->WriteControl(CDLO | CS1 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + } + port->WriteControl(CDLO | CS1 | CELO); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + break; + case 2: + if (control == 1) + port->WriteControl(CDLO | CS2 | CELO); + else + port->WriteControl(CDLO | CS2 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + port->WriteData(data); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + if (control == 1) + { + port->WriteControl(CDLO | CS2 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + } + port->WriteControl(CDLO | CS2 | CELO); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + break; + case 3: + if (control == 1) + port->WriteControl(CDLO | CS3 | CELO); + else + port->WriteControl(CDLO | CS3 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + port->WriteData(data); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + if (control == 1) + { + port->WriteControl(CDLO | CS3 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + } + port->WriteControl(CDLO | CS3 | CELO); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + break; + case 4: + if (control == 1) + port->WriteControl(CDLO | CS4 | CELO); + else + port->WriteControl(CDLO | CS4 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + port->WriteData(data); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + if (control == 1) + { + port->WriteControl(CDLO | CS4 | CEHI); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + } + port->WriteControl(CDLO | CS4 | CELO); + nSleep((timeForLCDInNs + timeForPortCmdInNs) + 100 * config->adjustTiming); + break; + } + if (useSleepInit) + nSleepDeInit(); +} + +void cDriverKS0108::Clear() +{ + for (int x = 0; x < (width + 7) / 8; x++) + memset(LCD[x], 0, height); +} + +void cDriverKS0108::Set8Pixels(int x, int y, unsigned char data) +{ + if (x >= width || y >= height) + return; + + if (!config->upsideDown) + { + // normal orientation + LCD[x / 8][y] = LCD[x / 8][y] | data; + } + else + { + // upside down orientation + x = width - 1 - x; + y = height - 1 - y; + LCD[x / 8][y] = LCD[x / 8][y] | ReverseBits(data); + } +} + +void cDriverKS0108::Refresh(bool refreshAll) +{ + int x,y; + int xx,yy; + unsigned char dByte, oneBlock[8]; + + if (CheckSetup() > 0) + refreshAll = true; + + if (config->refreshDisplay > 0) + { + refreshCounter = (refreshCounter + 1) % config->refreshDisplay; + if (!refreshAll && !refreshCounter) + refreshAll=true; + } + + refreshAll = true; // differential update is not yet supported + + if (refreshAll) + { + // draw all + + // convert the linear lcd array to the paged array for the display + for (y = 0; y < (height + 7) / 8; y++) + { + for (x = 0; x < (width + 7) / 8; x++) + { + for (yy = 0; yy < 8; yy++) + { + oneBlock[yy] = LCD[x][yy + (y * 8)] ^ (config->invert ? 0xff : 0x00); + } + for (xx = 0; xx < 8; xx++) + { + dByte = 0; + for (yy = 0; yy < 8; yy++) + { + if (oneBlock[yy] & bitmask[xx]) + { + dByte += (1 << yy); + } + } + LCD_page[x * 8 + xx][y] = dByte; + } + } + } + + port->Claim(); + + if (width == 128 && height == 64) { + for (y = 0; y < 64/8; y++) { + KS0108Cmd(SEPA + y, 1); + KS0108Cmd(SEAD, 1); + + for (x = 0; x < 64; x++) { + KS0108Data(LCD_page[x][y], 1); + } + } + + for (y = 0; y < 64/8; y++) { + KS0108Cmd(SEPA + y, 2); + KS0108Cmd(SEAD, 2); + + for (x = 64; x < 128; x++) { + KS0108Data(LCD_page[x][y], 2); + } + } + } + + if (width > 128 && height == 64) { + for (y = 0; y < 64/8; y++) { + KS0108Cmd(SEPA + y, 1); + KS0108Cmd(SEAD, 1); + + for (x = 0; x < 64; x++) { + KS0108Data(LCD_page[x][y], 1); + } + } + + for (y = 0; y < 64/8; y++) { + KS0108Cmd(SEPA + y, 2); + KS0108Cmd(SEAD, 2); + for (x = 64; x < 128; x++) { + KS0108Data(LCD_page[x][y], 2); + } + } + + for (y = 0; y < 64/8; y++) { + KS0108Cmd(SEPA + y, 3); + KS0108Cmd(SEAD, 3); + + for (x = 128; x < 192; x++) { + KS0108Data(LCD_page[x][y], 3); + } + } + + for (y = 0; y < 64/8; y++) { + if (width > 192) { + KS0108Cmd(SEPA + y, 4); + KS0108Cmd(SEAD, 4); + for (x = 192; x < 256; x++) { + KS0108Data(LCD_page[x][y], 4); + } + } + } + } + + if (width == 128 && height == 128) { + for (y = 0; y < 64/8; y++) { + KS0108Cmd(SEPA + y, 1); + KS0108Cmd(SEAD, 1); + + for (x = 0; x < 64; x++) { + KS0108Data(LCD_page[x][y], 1); + } + } + + for (y = 0; y < 64/8; y++) { + KS0108Cmd(SEPA + y, 2); + KS0108Cmd(SEAD, 2); + + for (x = 64; x < 128; x++) { + KS0108Data(LCD_page[x][y], 2); + } + } + + for (y = 0; y < 64/8; y++) { + KS0108Cmd(SEPA + y, 3); + KS0108Cmd(SEAD, 3); + + for (x = 0; x < 64; x++) { + KS0108Data(LCD_page[x][y+8], 3); + } + } + + for (y = 0; y < 64/8; y++) { + KS0108Cmd(SEPA + y, 4); + KS0108Cmd(SEAD, 4); + + for (x = 64; x < 128; x++) { + KS0108Data(LCD_page[x][y+8], 4); + } + } + } + port->WriteData(0); + port->Release(); + } + else + { + // draw only the changed bytes + } +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/ks0108.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/ks0108.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,78 @@ +/* + * GraphLCD driver library + * + * ks0108.h - KS0108 driver class + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003 Andreas 'randy' Weinberger + */ + +#ifndef _GLCDDRIVERS_KS0108_H_ +#define _GLCDDRIVERS_KS0108_H_ + +#include "driver.h" + + +namespace GLCD +{ + +class cDriverConfig; +class cParallelPort; + +class cDriverKS0108 : public cDriver +{ +private: + cParallelPort * port; + unsigned char ** LCD; // linear lcd display "memory" + unsigned char ** LCD_page; // paged lcd display "memory" + int refreshCounter; + long timeForPortCmdInNs; + long timeForLCDInNs; + cDriverConfig * config; + cDriverConfig * oldConfig; + bool useSleepInit; + + int CheckSetup(); + int InitGraphic(); + void KS0108Cmd(unsigned char data, int cs); + void KS0108Data(unsigned char data, int cs); + + int SEAD; + int SEPA; + int SEDS; + int DIOF; + int DION; + + int CEHI; + int CELO; + int CDHI; + int CDLO; + int CS1HI; + int CS1LO; + int CS2HI; + int CS2LO; + + int CS1; + int CS2; + int CS3; + int CS4; + + unsigned char control; + +public: + cDriverKS0108(cDriverConfig * config); + virtual ~cDriverKS0108(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/network.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/network.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,267 @@ +/* + * GraphLCD driver library + * + * network.c - Network output device + * Output goes to a network client. + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "config.h" +#include "network.h" + + +namespace GLCD +{ + +cDriverNetwork::cDriverNetwork(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); + childTid = 0; + running = false; + clientConnected = false; +} + +cDriverNetwork::~cDriverNetwork() +{ + delete oldConfig; +} + +int cDriverNetwork::Init() +{ + width = config->width; + if (width <= 0) + width = 240; + height = config->height; + if (height <= 0) + height = 128; + lineSize = (width + 7) / 8; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "") + { + } + } + + newLCD = new unsigned char[lineSize * height]; + if (newLCD) + memset(newLCD, 0, lineSize * height); + oldLCD = new unsigned char[lineSize * height]; + if (oldLCD) + memset(oldLCD, 0, lineSize * height); + + *oldConfig = *config; + + // clear display + Clear(); + + running = true; + if (pthread_create(&childTid, NULL, (void *(*) (void *)) &ServerThread, (void *)this) != 0) + { + syslog(LOG_ERR, "%s: error creating server thread.\n", config->name.c_str()); + running = false; + return 1; + } + syslog(LOG_INFO, "%s: network driver initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverNetwork::DeInit() +{ + // stop server thread + running = false; + usleep(3000000); // wait 3 seconds + pthread_cancel(childTid); + childTid = 0; + + if (newLCD) + delete[] newLCD; + if (oldLCD) + delete[] oldLCD; + return 0; +} + +int cDriverNetwork::CheckSetup() +{ + if (config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +void cDriverNetwork::Clear() +{ + memset(newLCD, 0, lineSize * height); +} + +void cDriverNetwork::Set8Pixels(int x, int y, unsigned char data) +{ + if (x >= width || y >= height) + return; + + if (!config->upsideDown) + { + // normal orientation + newLCD[lineSize * y + x / 8] |= data; + } + else + { + // upside down orientation + x = width - 1 - x; + y = height - 1 - y; + newLCD[lineSize * y + x / 8] |= ReverseBits(data); + } +} + +void cDriverNetwork::Refresh(bool refreshAll) +{ + int i; + bool refresh; + + refresh = false; + if (CheckSetup() > 0) + refresh = true; + + for (i = 0; i < lineSize * height; i++) + { + if (newLCD[i] != oldLCD[i]) + { + refresh = true; + break; + } + } + + if (refresh && clientConnected) + { + char msg[1024]; + int x; + int y; + int sent; + + sprintf(msg, "update begin %d %d\r\n", width, height); + sent = send(clientSocket, msg, strlen(msg), 0); + if (sent == -1) + { + syslog(LOG_ERR, "%s: error sending message: %s.\n", config->name.c_str(), strerror(errno)); + clientConnected = false; + return; + } + for (y = 0; y < height; y++) + { + sprintf(msg, "update line %d ", y); + for (x = 0; x < lineSize; x++) + { + char tmp[3]; + sprintf(tmp, "%02X", newLCD[y * lineSize + x]); + strcat(msg, tmp); + oldLCD[i] = newLCD[i]; + } + strcat(msg, "\r\n"); + sent = send(clientSocket, msg, strlen(msg), 0); + if (sent == -1) + { + syslog(LOG_ERR, "%s: error sending message: %s.\n", config->name.c_str(), strerror(errno)); + clientConnected = false; + return; + } + } + sprintf(msg, "update end\r\n"); + sent = send(clientSocket, msg, strlen(msg), 0); + if (sent == -1) + { + syslog(LOG_ERR, "%s: error sending message: %s.\n", config->name.c_str(), strerror(errno)); + clientConnected = false; + return; + } + } +} + +void * cDriverNetwork::ServerThread(cDriverNetwork * Driver) +{ + int serverSocket; + struct sockaddr_in address; + socklen_t addrlen; + int clientSocket; + fd_set set; + fd_set setsave; + struct timeval timeout; + + serverSocket = socket(AF_INET, SOCK_STREAM, 0); + if (serverSocket == -1) + { + syslog(LOG_ERR, "%s: error creating server socket.\n", Driver->config->name.c_str()); + return NULL; + } + + int y = 1; + setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int)); + + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(2003); + if (bind(serverSocket, (struct sockaddr *) &address, sizeof(address)) != 0) + { + syslog(LOG_ERR, "%s: error port %d is already used.\n", Driver->config->name.c_str(), 2003); + return NULL; + } + + listen(serverSocket, 1); + addrlen = sizeof(struct sockaddr_in); + + FD_ZERO(&set); + FD_SET(serverSocket, &set); + setsave = set; + + while (Driver->running) + { + set = setsave; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + if (select(FD_SETSIZE, &set, NULL, NULL, &timeout) < 0) + { + syslog(LOG_ERR, "%s: error during select.\n", Driver->config->name.c_str()); + break; + } + + if (FD_ISSET(serverSocket, &set)) + { + clientSocket = accept(serverSocket, (struct sockaddr *) &address, &addrlen); + if (clientSocket > 0) + { + Driver->clientSocket = clientSocket; + Driver->clientConnected = true; + } + } + } + close(serverSocket); + return NULL; +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/network.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/network.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,56 @@ +/* + * GraphLCD driver library + * + * network.h - Network output device + * Output goes to a network client. + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDDRIVERS_NETWORK_H_ +#define _GLCDDRIVERS_NETWORK_H_ + +#include + +#include "driver.h" + + +namespace GLCD +{ + +class cDriverConfig; + +class cDriverNetwork : public cDriver +{ +private: + unsigned char * newLCD; + unsigned char * oldLCD; + cDriverConfig * config; + cDriverConfig * oldConfig; + int lineSize; + bool running; + pthread_t childTid; + int clientSocket; + bool clientConnected; + + int CheckSetup(); + static void * ServerThread(cDriverNetwork * Driver); + +public: + cDriverNetwork(cDriverConfig * config); + virtual ~cDriverNetwork(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/noritake800.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/noritake800.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,537 @@ +/* + * GraphLCD driver library + * + * noritake800.c - Noritake 800(A) series VFD graphlcd driver, + * different "Medium 0.6 dot" sizes should work, + * see http://www.noritake-itron.com: + * - GU128X64-800A, + * - GU256X32-800A, + * - GU128X32-800A, + * - GU160X16-800A, + * - GU160X32-800A, + * - GU192X16-800A. + * + * based on: + * ideas and HW-command related stuff from the open source project + * "lcdplugin for Winamp": + * (c) 1999 - 2003 Markus Zehnder + * GU256x64-372 driver module for graphlcd + * (c) 20040410 Andreas 'Randy' Weinberger + * gu140x32f driver module for graphlcd + * (c) 2003 Andreas Brachold + * HD61830 device + * (c) 2001-2003 by Carsten Siebholz + * lcdproc 0.4 driver hd44780-ext8bit + * (c) 1999, 1995 Benjamin Tse + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Lucian Muresan + */ + +#include +#include +#include +#include + +#include "common.h" +#include "config.h" +#include "noritake800.h" +#include "port.h" + +namespace GLCD +{ + +/* LPT Control Port lines */ +#define LPT_CTL_HI_DIR 0x20 +#define LPT_CTL_HI_IRQEN 0x10 +#define LPT_CTL_LO_STROBE 0x01 +#define LPT_CTL_LO_LFEED 0x02 +#define LPT_CTL_LO_INIT 0x04 +#define LPT_CTL_LO_SELECT 0x08 + +/* Noritake 800(A) VFD control signals bit masks*/ +#define VFDSGN_CD 0x01 +#define VFDSGN_WR 0x02 +#define VFDSGN_RD 0x04 +#define VFDSGN_CSS 0x08 + +//wirings +#define WIRING_LIQUIDMP3 0 +static const std::string kWiringLiquidmp3 = "LiquidMp3"; +#define WIRING_MZ 1 +static const std::string kWiringMZ = "MZ"; +// ... other wirings may follow + +/* Command set for this display */ +#define ANDCNTL 0x03 +#define ORCNTL 0x01 +#define XORCNTL 0x02 +#define Init800A 0x5F /* initialization code sequence 5f */ +#define Init800B 0x62 +#define Init800C 0x00+n +#define Init800D 0xFF +#define CLEARSCREENS 0x5e /* clear all screens (layers) */ +#define LAYER0ON 0x24 /* screen0 both on */ +#define LAYER1ON 0x28 /* screen1 both on */ +#define LAYERSON 0x2c /* both screens both on */ +#define LAYERSOFF 0x20 /* screens both off */ +#define ORON 0x40 /* OR screens */ +#define ANDON 0x48 /* AND screens */ +#define XORON 0x44 /* XOR screens */ +#define SETX 0x64 /* set X position */ +#define SETY 0x60 /* set Y position */ +#define HSHIFT 0x70 /* set horizontal shift */ +#define VSHIFT 0xB0 +#define AUTOINCOFF 0x80 /* address auto increment off */ +#define SETPOSITION 0xff + + +cDriverNoritake800::cDriverNoritake800(cDriverConfig * config) +{ + int x = 0; + m_bGraphScreen0_On = true; + m_bGraphScreen1_On = false; + // default initilaization for the wiring + m_nWiring = WIRING_LIQUIDMP3; + + m_Config = config; + m_oldConfig = new cDriverConfig(* config); + + m_pport = new cParallelPort(); + + m_nTimingAdjustCmd = 0; + m_nRefreshCounter = 0; + + width = m_Config->width; // 128 + if (width <= 0) + width = 128; + height = m_Config->height; // 64 + if (height <= 0) + height = 64; + m_iSizeYb = (height + 7)/8; // 8 + + // + // initialize wiring + // + for (unsigned int i = 0; i < m_Config->options.size(); i++) + { + if (m_Config->options[i].name == "Wiring") + { + if (m_Config->options[i].value == kWiringLiquidmp3) + { + m_nWiring = WIRING_LIQUIDMP3; + } + else if (m_Config->options[i].value == kWiringMZ) + { + m_nWiring = WIRING_MZ; + } + else + syslog(LOG_ERR, "%s error: wiring %s not supported, using default wiring(%s)!\n", + config->name.c_str(), config->options[i].value.c_str(), kWiringLiquidmp3.c_str()); + } + } + // fill the wiring mask cache for all the 16 possibilities + m_pWiringMaskCache = new unsigned char[16]; + for (unsigned int i = 0; i < 16; i++) + { + m_pWiringMaskCache[i] = N800LptWiringMask(i); + } + + // setup linear lcd array + m_pDrawMem = new unsigned char*[width]; + if (m_pDrawMem) + { + for (x = 0; x < width; x++) + { + m_pDrawMem[x] = new unsigned char[m_iSizeYb]; + memset(m_pDrawMem[x], 0, m_iSizeYb); + } + } + Clear(); + + // setup the lcd array for the "vertikal" mem + m_pVFDMem = new unsigned char*[width]; + if (m_pVFDMem) + { + for (x = 0; x < width; x++) + { + m_pVFDMem[x] = new unsigned char[m_iSizeYb]; + memset(m_pVFDMem[x], 0, m_iSizeYb); + } + } + ClearVFDMem(); +} + +cDriverNoritake800::~cDriverNoritake800() +{ + int x; + + if (m_pVFDMem) + for (x = 0; x < (width + 7) / 8; x++) + { + delete[] m_pVFDMem[x]; + } + delete[] m_pVFDMem; + if (m_pDrawMem) + for (x = 0; x < (width + 7) / 8; x++) + { + delete[] m_pDrawMem[x]; + } + delete[] m_pDrawMem; + delete[] m_pWiringMaskCache; + delete m_oldConfig; + delete m_pport; +} + +void cDriverNoritake800::Clear() +{ + for (int x = 0; x < width; x++) + { + memset(m_pDrawMem[x], 0, m_iSizeYb); + } +} + +void cDriverNoritake800::ClearVFDMem() +{ + for (int x = 0; x < width; x++) + { + memset(m_pVFDMem[x], 0, m_iSizeYb); + } +} + +int cDriverNoritake800::DeInit() +{ + if (m_pport->Close() != 0) + return -1; + return 0; +} + +int cDriverNoritake800::CheckSetup() +{ + if (m_Config->device != m_oldConfig->device || + m_Config->port != m_oldConfig->port || + m_Config->width != m_oldConfig->width || + m_Config->height != m_oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (m_Config->brightness != m_oldConfig->brightness) + { + m_oldConfig->brightness = m_Config->brightness; + SetBrightness(m_Config->brightness); + } + + if (m_Config->upsideDown != m_oldConfig->upsideDown || + m_Config->invert != m_oldConfig->invert) + { + m_oldConfig->upsideDown = m_Config->upsideDown; + m_oldConfig->invert = m_Config->invert; + return 1; + } + return 0; +} + +int cDriverNoritake800::Init() +{ + int x; + struct timeval tv1, tv2; + + if (m_Config->device == "") + { + // use DirectIO + if (m_pport->Open(m_Config->port) != 0) + return -1; + uSleep(10); + } + else + { + // use ppdev + if (m_pport->Open(m_Config->device.c_str()) != 0) + return -1; + } + + if (nSleepInit() != 0) + { + syslog(LOG_ERR, "%s: INFO: cannot change wait parameters Err: %s (cDriver::Init)\n", m_Config->name.c_str(), strerror(errno)); + m_bSleepIsInit = false; + } + else + { + m_bSleepIsInit = true; + } + + // benchmark port access + m_pport->Claim(); + syslog(LOG_DEBUG, "%s: benchmark started.\n", m_Config->name.c_str()); + gettimeofday(&tv1, 0); + int nBenchFactor = 100000; + for (x = 0; x < nBenchFactor; x++) + { + m_pport->WriteData(x % 0x100); + } + gettimeofday(&tv2, 0); + nSleepDeInit(); + //m_nTimingAdjustCmd = ((tv2.tv_sec - tv1.tv_sec) * 10000 + (tv2.tv_usec - tv1.tv_usec)) / 1000; + m_nTimingAdjustCmd = long(double((tv2.tv_sec - tv1.tv_sec) * 1000 + (tv2.tv_usec - tv1.tv_usec)) / double(nBenchFactor)); + syslog(LOG_DEBUG, "%s: benchmark stopped. Time for Port Command: %ldns\n", m_Config->name.c_str(), m_nTimingAdjustCmd); + m_pport->Release(); + + + // initialize display + N800Cmd(Init800A); + + int n; + for (n=0; n < 15; n++) + { + N800Cmd(0x62); + nSleep(100 + (100 * m_Config->adjustTiming) - m_nTimingAdjustCmd); + N800Cmd(n); + nSleep(100 + (100 * m_Config->adjustTiming) - m_nTimingAdjustCmd); + N800Data(0xff); + nSleep(100 + (100 * m_Config->adjustTiming) - m_nTimingAdjustCmd); + } + nSleep(100 + (100 * m_Config->adjustTiming) - m_nTimingAdjustCmd); + + + N800Cmd(LAYERSOFF | LAYER0ON); // layer 0 of the graphic RAM on + N800Cmd(ORON); // OR the layers + N800Cmd(HSHIFT); // set horizontal shift + N800Cmd(0x00); // no shift + N800Cmd(VSHIFT); // Vertical shift =0 + N800Cmd(AUTOINCOFF); // auto increment off + N800Cmd(SETX); // set x coord + N800Cmd(0x40); // to 0 + N800Cmd(SETY); // set y coord + N800Cmd(0); // to 0 + + m_pport->Release(); + + *m_oldConfig = *m_Config; + + // Set Display SetBrightness + SetBrightness(m_Config->brightness); + // clear display + ClearVFDMem(); + Refresh(true); + + syslog(LOG_INFO, "%s: initialization done.\n", m_Config->name.c_str()); + return 0; +} + +void cDriverNoritake800::Refresh(bool refreshAll) +{ + // + // for VFD displays, we can safely ignore refreshAll, as they are "sticky" + // + int xb, yb; + + if (CheckSetup() > 0) + refreshAll = true; // we don't use it + + if (!m_pVFDMem || !m_pDrawMem) + return; + +// // just refresh if the time needed between refreshes is up +// m_nRefreshCounter = (m_nRefreshCounter + 1) % m_Config->refreshDisplay; +// if(!m_nRefreshCounter) +// { + m_pport->Claim(); + for (xb = 0; xb < width; ++xb) + { + for (yb = 0; yb < m_iSizeYb; ++yb) + { + if (m_pVFDMem[xb][yb] != m_pDrawMem[xb][yb]) + { + m_pVFDMem[xb][yb] = m_pDrawMem[xb][yb]; + // reset RefreshCounter + m_nRefreshCounter = 0; + // actually write to display + N800WriteByte( + (m_pVFDMem[xb][yb]) ^ ((m_Config->invert != 0) ? 0xff : 0x00), + xb, + yb, + 0); + } + } + } + m_pport->Release(); +// } +} + +void cDriverNoritake800::N800Cmd(unsigned char data) +{ + if (m_bSleepIsInit) + nSleepInit(); + + // set direction to "port_output" & C/D to C + m_pport->WriteControl(m_pWiringMaskCache[0x00]); + // write to data port + m_pport->WriteData(data); + //nSleep(100 + (100 * m_Config->adjustTiming) - m_nTimingAdjustCmd); + // set /WR on the control port + m_pport->WriteControl(m_pWiringMaskCache[VFDSGN_WR]); + //nSleep(100 + (100 * m_Config->adjustTiming) - m_nTimingAdjustCmd); + // reset /WR on the control port + m_pport->WriteControl(m_pWiringMaskCache[0x00]); + //nSleep(100 + (100 * m_Config->adjustTiming) - m_nTimingAdjustCmd); + // set direction to "port_input" + m_pport->WriteControl(LPT_CTL_HI_DIR | m_pWiringMaskCache[0x00]); +} + +void cDriverNoritake800::N800Data(unsigned char data) +{ + if (m_bSleepIsInit) + nSleepInit(); + + // set direction to "port_output" & C/D to C + m_pport->WriteControl(m_pWiringMaskCache[VFDSGN_CD]); + // write to data port + m_pport->WriteData(data); + //nSleep(100 + (100 * m_Config->adjustTiming) - m_nTimingAdjustCmd); + // set /WR on the control port + m_pport->WriteControl(m_pWiringMaskCache[VFDSGN_CD | VFDSGN_WR]); + //nSleep(100 + (100 * m_Config->adjustTiming) - m_nTimingAdjustCmd); + // reset /WR on the control port + m_pport->WriteControl(m_pWiringMaskCache[VFDSGN_CD]); + //nSleep(100 + (100 * m_Config->adjustTiming) - m_nTimingAdjustCmd); + // set direction to "port_input" + m_pport->WriteControl(LPT_CTL_HI_DIR | m_pWiringMaskCache[0x00]); +} + +void cDriverNoritake800::SetPixel(int x, int y) +{ + unsigned char c; + + if (!m_pDrawMem) + return; + + if (x >= width || x < 0) + return; + if (y >= height || y < 0) + return; + + if (m_Config->upsideDown) + { + x = width - 1 - x; + y = height - 1 - y; + } + + c = 0x80 >> (y % 8); + + m_pDrawMem[x][y/8] |= c; +} + +void cDriverNoritake800::Set8Pixels(int x, int y, unsigned char data) +{ + int n; + + // x - pos is'nt mayby align to 8 + x &= 0xFFF8; + + for (n = 0; n < 8; ++n) + { + if (data & (0x80 >> n)) // if bit is set + SetPixel(x + n, y); + } +} + +void cDriverNoritake800::SetBrightness(unsigned int percent) +{ + // display can do 16 brightness levels, + // 0 = light + // 15 = dark + + // convert from "light percentage" into darkness values from 0 to 15 + if (percent > 100) + { + percent = 100; + } + unsigned int darkness = 16 - (unsigned int)((double)percent * 16.0 / 100.0); + + m_pport->Claim(); + N800Cmd(0x40 + (darkness & 0xf)); + m_pport->Release(); +} + +unsigned char cDriverNoritake800::N800LptWiringMask(unsigned char ctrl_bits) +{ + unsigned char newstatus = 0x0; + + if (m_nWiring == WIRING_LIQUIDMP3) + { + if (ctrl_bits & VFDSGN_CSS) + newstatus |= LPT_CTL_LO_STROBE; + else + newstatus &= ~LPT_CTL_LO_STROBE; + + if (ctrl_bits & VFDSGN_RD) + newstatus |= LPT_CTL_LO_LFEED; + else + newstatus &= ~LPT_CTL_LO_LFEED; + + if (ctrl_bits & VFDSGN_WR) + newstatus |= LPT_CTL_LO_INIT; + else + newstatus &= ~LPT_CTL_LO_INIT; + + if (ctrl_bits & VFDSGN_CD) + newstatus |= LPT_CTL_LO_SELECT; + else + newstatus &= ~LPT_CTL_LO_SELECT; + + // control commands are XOR-ed with 0x5 + // to account for active lows and highs + newstatus ^= 0x5; + } + else if (m_nWiring == WIRING_MZ) + { + if (ctrl_bits & VFDSGN_CSS) + newstatus |= LPT_CTL_LO_INIT; + else + newstatus &= ~LPT_CTL_LO_INIT; + + if (ctrl_bits & VFDSGN_RD) + newstatus |= LPT_CTL_LO_LFEED; + else + newstatus &= ~LPT_CTL_LO_LFEED; + + if (ctrl_bits & VFDSGN_WR) + newstatus |= LPT_CTL_LO_STROBE; + else + newstatus &= ~LPT_CTL_LO_STROBE; + + if (ctrl_bits & VFDSGN_CD) + newstatus |= LPT_CTL_LO_SELECT; + else + newstatus &= ~LPT_CTL_LO_SELECT; + } + return newstatus; +} + +void cDriverNoritake800::N800WriteByte(unsigned char data, int nCol, int nRow, int layer) +{ + /* set cursor to desired address */ + N800Cmd(SETX); /* set upper cursor address */ + N800Cmd(nCol); + + if (layer==0) + { + N800Cmd(SETY); /* set lower cursor address */ + N800Cmd(nRow); /*layer0 */ + } + else if (layer==1) + { + N800Cmd(SETY); /* set lower cursor address */ + N800Cmd(nRow+8); /* layer 1 */ + } + + N800Data(ReverseBits(data)); +} + +} // end of namespace + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/noritake800.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/noritake800.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,92 @@ +/* + * GraphLCD driver library + * + * noritake800.h - Noritake 800(A) series VFD graphlcd driver, + * different "Medium 0.6 dot" sizes should work, + * see http://www.noritake-itron.com: + * - GU128X64-800A, + * - GU256X32-800A, + * - GU128X32-800A, + * - GU160X16-800A, + * - GU160X32-800A, + * - GU192X16-800A. + * + * based on: + * ideas and HW-command related stuff from the open source project + * "lcdplugin for Winamp": + * (c) 1999 - 2003 Markus Zehnder + * GU256x64-372 driver module for graphlcd + * (c) 20040410 Andreas 'Randy' Weinberger + * gu140x32f driver module for graphlcd + * (c) 2003 Andreas Brachold + * HD61830 device + * (c) 2001-2003 by Carsten Siebholz + * lcdproc 0.4 driver hd44780-ext8bit + * (c) 1999, 1995 Benjamin Tse + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Lucian Muresan + */ + +#ifndef _GLCDDRIVERS_NORITAKE800_H_ +#define _GLCDDRIVERS_NORITAKE800_H_ + +#include "driver.h" + +namespace GLCD +{ + +class cDriverConfig; +class cParallelPort; + +class cDriverNoritake800 : public cDriver +{ + cParallelPort * m_pport; + + cDriverConfig * m_Config; + cDriverConfig * m_oldConfig; + + int m_iSizeYb; + int m_nRefreshCounter; + int m_nWiring; + + unsigned char ** m_pDrawMem; /* the draw "memory" */ + unsigned char ** m_pVFDMem; /* the double buffed display "memory" */ + + long m_nTimingAdjustCmd; + bool m_bSleepIsInit; + + // internal graphics layers + bool m_bGraphScreen0_On; + bool m_bGraphScreen1_On; + + unsigned char * m_pWiringMaskCache; + +protected: + void ClearVFDMem(); + void N800Cmd(unsigned char data); + void N800Data(unsigned char data); + int CheckSetup(); + unsigned char N800LptWiringMask(unsigned char ctrl_bits); + void N800WriteByte(unsigned char data, int nCol, int nRow, int layer); + +public: + cDriverNoritake800(cDriverConfig * config); + virtual ~cDriverNoritake800(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void SetPixel(int x, int y); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); + + virtual void SetBrightness(unsigned int percent); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/port.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/port.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,350 @@ +/* + * GraphLCD driver library + * + * port.c - parallel port class with low level routines + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include "port.h" + +namespace GLCD +{ + +static inline int port_in(int port) +{ + unsigned char value; + __asm__ volatile ("inb %1,%0" + : "=a" (value) + : "d" ((unsigned short) port)); + return value; +} + +static inline void port_out(unsigned short int port, unsigned char val) +{ + __asm__ volatile ("outb %0,%1\n" + : + : "a" (val), "d" (port)); +} + +cParallelPort::cParallelPort() +: fd(-1), + port(0), + usePPDev(false) +{ +} + +cParallelPort::~cParallelPort() +{ +} + +int cParallelPort::Open(int portIO) +{ + usePPDev = false; + port = portIO; + + if (port < 0x400) + { + if (ioperm(port, 3, 255) == -1) + { + syslog(LOG_ERR, "glcd drivers: ERROR ioperm(0x%X) failed! Err:%s (cParallelPort::Open)\n", + port, strerror(errno)); + return -1; + } + } + else + { + if (iopl(3) == -1) + { + syslog(LOG_ERR, "glcd drivers: ERROR iopl failed! Err:%s (cParallelPort::Init)\n", + strerror(errno)); + return -1; + } + } + return 0; +} + +int cParallelPort::Open(const char * device) +{ + usePPDev = true; + + fd = open(device, O_RDWR); + if (fd == -1) + { + syslog(LOG_ERR, "glcd drivers: ERROR cannot open %s. Err:%s (cParallelPort::Init)\n", + device, strerror(errno)); + return -1; + } + + if (ioctl(fd, PPCLAIM, NULL) == -1) + { + syslog(LOG_ERR, "glcd drivers: ERROR cannot claim %s. Err:%s (cParallelPort::Init)\n", + device, strerror(errno)); + close(fd); + return -1; + } + + int mode = PARPORT_MODE_PCSPP; + if (ioctl(fd, PPSETMODE, &mode) == -1) + { + syslog(LOG_ERR, "glcd drivers: ERROR cannot setmode %s. Err:%s (cParallelPort::Init)\n", + device, strerror(errno)); + close(fd); + return -1; + } + + return 0; +} + +int cParallelPort::Close() +{ + if (usePPDev) + { + if (fd != -1) + { + ioctl(fd, PPRELEASE); + close(fd); + fd = -1; + } + else + { + return -1; + } + } + else + { + if (port < 0x400) + { + if (ioperm(port, 3, 0) == -1) + { + return -1; + } + } + else + { + if (iopl(0) == -1) + { + return -1; + } + } + } + return 0; +} + +void cParallelPort::Claim() +{ + if (usePPDev) + ioctl(fd, PPCLAIM); +} + +void cParallelPort::Release() +{ + if (usePPDev) + ioctl(fd, PPRELEASE); +} + +void cParallelPort::SetDirection(int direction) +{ + if (usePPDev) + { + if (ioctl(fd, PPDATADIR, &direction) == -1) + { + perror("ioctl(PPDATADIR)"); + //exit(1); + } + } + else + { + if (direction == kForward) + port_out(port + 2, port_in(port + 2) & 0xdf); + else + port_out(port + 2, port_in(port + 2) | 0x20); + } +} + +unsigned char cParallelPort::ReadControl() +{ + unsigned char value; + + if (usePPDev) + { + if (ioctl(fd, PPRCONTROL, &value) == -1) + { + perror("ioctl(PPRCONTROL)"); + //exit(1); + } + } + else + { + value = port_in(port + 2); + } + + return value; +} + +void cParallelPort::WriteControl(unsigned char value) +{ + if (usePPDev) + { + if (ioctl(fd, PPWCONTROL, &value) == -1) + { + perror("ioctl(PPWCONTROL)"); + //exit(1); + } + } + else + { + port_out(port + 2, value); + } +} + +unsigned char cParallelPort::ReadStatus() +{ + unsigned char value; + + if (usePPDev) + { + if (ioctl(fd, PPRSTATUS, &value) == -1) + { + perror("ioctl(PPRSTATUS)"); + //exit(1); + } + } + else + { + value = port_in(port + 1); + } + + return value; +} + +unsigned char cParallelPort::ReadData() +{ + unsigned char data; + + if (usePPDev) + { + if (ioctl(fd, PPRDATA, &data) == -1) + { + perror("ioctl(PPRDATA)"); + //exit(1); + } + } + else + { + data = port_in(port); + } + + return data; +} + +void cParallelPort::WriteData(unsigned char data) +{ + if (usePPDev) + { + if (ioctl(fd, PPWDATA, &data) == -1) + { + perror("ioctl(PPWDATA)"); + //exit(1); + } + } + else + { + port_out(port, data); + } +} + + + +cSerialPort::cSerialPort() +: fd(-1) +{ +} + +cSerialPort::~cSerialPort() +{ +} + +int cSerialPort::Open(const char * device) +{ + struct termios options; + + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); + if (fd == -1) + { + printf("error opening port\n"); + return -1; + } + //fcntl(fd, F_SETFL, FNDELAY); + fcntl(fd, F_SETFL, 0); + + tcgetattr(fd, &options); + + cfsetispeed(&options, B921600); + cfsetospeed(&options, B921600); + + options.c_cflag &= ~PARENB; + options.c_cflag &= ~CSTOPB; + options.c_cflag &= ~CSIZE; + options.c_cflag |= CS8; + + options.c_cflag &= ~CRTSCTS; + + options.c_cflag |= (CLOCAL | CREAD); + + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + + options.c_iflag &= ~(IXON | IXOFF | IXANY); + + options.c_oflag &= ~OPOST; + + tcsetattr(fd, TCSANOW, &options); + + return 0; +} + +int cSerialPort::Close() +{ + if (fd == -1) + return -1; + close(fd); + return 0; +} + +int cSerialPort::ReadData(unsigned char * data) +{ + if (fd == -1) + return 0; + return read(fd, data, 1); +} + +void cSerialPort::WriteData(unsigned char data) +{ + WriteData(&data, 1); +} + +void cSerialPort::WriteData(unsigned char * data, unsigned short length) +{ + if (fd == -1) + return; + write(fd, data, length); +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/port.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/port.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,78 @@ +/* + * GraphLCD driver library + * + * port.h - parallel port class with low level routines + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDDRIVERS_PORT_H_ +#define _GLCDDRIVERS_PORT_H_ + +namespace GLCD +{ + +const int kForward = 0; +const int kReverse = 1; + +const unsigned char kStrobeHigh = 0x00; // Pin 1 +const unsigned char kStrobeLow = 0x01; +const unsigned char kAutoHigh = 0x00; // Pin 14 +const unsigned char kAutoLow = 0x02; +const unsigned char kInitHigh = 0x04; // Pin 16 +const unsigned char kInitLow = 0x00; +const unsigned char kSelectHigh = 0x00; // Pin 17 +const unsigned char kSelectLow = 0x08; + +class cParallelPort +{ +private: + int fd; + int port; + bool usePPDev; + +public: + cParallelPort(); + ~cParallelPort(); + + int Open(int port); + int Open(const char * device); + int Close(); + + bool IsDirectIO() const { return (!usePPDev); } + int GetPortHandle() const { return ((usePPDev) ? fd : port); } + + void Claim(); + void Release(); + + void SetDirection(int direction); + unsigned char ReadControl(); + void WriteControl(unsigned char values); + unsigned char ReadStatus(); + unsigned char ReadData(); + void WriteData(unsigned char data); +}; + +class cSerialPort +{ +private: + int fd; + +public: + cSerialPort(); + ~cSerialPort(); + + int Open(const char * device); + int Close(); + + int ReadData(unsigned char * data); + void WriteData(unsigned char data); + void WriteData(unsigned char * data, unsigned short length); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/sed1330.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/sed1330.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,630 @@ +/* + * GraphLCD driver library + * + * sed1330.c - SED1330 driver class + * + * based on: hd61830.c + * (c) 2001-2004 Carsten Siebholz + * + * changes for Seiko-Epson displays: Mar 2004 + * (c) 2004 Heinz Gressenberger + * + * init sequence taken from Thomas Baumann's LCD-Test program + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003 Roland Praml + */ + +#include +#include + +#include "common.h" +#include "config.h" +#include "port.h" +#include "sed1330.h" + + +namespace GLCD +{ + +// SED1330 Commands + +// Command Codes, Bytes for Param + +#define C_SYSTEMSET 0x40 +#define C_SLEEPIN 0x53 +#define C_DISPON 0x59 +#define C_DISPOFF 0x58 +#define C_SCROLL 0x44 +#define C_CSRFORM 0x5D +#define C_CGRAMADR 0x5C +#define C_CSRDIR_R 0x4C +#define C_CSRDIR_L 0x4D +#define C_CSRDIR_U 0x4E +#define C_CSRDIR_D 0x4F +#define C_HDOTSCR 0x5A +#define C_OVLAY 0x5B +#define C_CSRW 0x46 +#define C_CSRR 0x47 +#define C_MWRITE 0x42 +#define C_MREAD 0x43 + +#define M0 0 +// 0-internal CG ROM, 1-external CG-ROM/RAM + +#define M1 0 +// 0 - 32 char CG-RAM, 1 - 64 char + +#define M2 0 +// 0 - 8x8, 1 - 8x16 matrix in CG-RAM/ROM + +#define FX 8 +// character-with +#define FY 8 +// character-height +#define BPC 1 +// byte per character, 1 - FX<=8, 2 - FX=9..16 + +#define SAD1 0x0000 +// startadress first screen + + +const int kInterface6800 = 0; +const int kInterface8080 = 1; + +const std::string kWiringOriginal = "Original"; +const std::string kWiringPowerLCD = "PowerLCD"; +const std::string kWiringLCDProc = "LCDProc"; +const std::string kWiringTweakers = "Tweakers"; +const std::string kWiringYASEDW = "YASEDW"; + +const unsigned char kOriginalA0HI = kInitHigh; +const unsigned char kOriginalA0LO = kInitLow; +const unsigned char kOriginalRDHI = kStrobeHigh; +const unsigned char kOriginalRDLO = kStrobeLow; +const unsigned char kOriginalWRHI = kAutoHigh; +const unsigned char kOriginalWRLO = kAutoLow; +const unsigned char kOriginalCSHI = kSelectHigh; +const unsigned char kOriginalCSLO = kSelectLow; + +const unsigned char kPowerLCDA0HI = kInitHigh; +const unsigned char kPowerLCDA0LO = kInitLow; +const unsigned char kPowerLCDRDHI = kSelectHigh; +const unsigned char kPowerLCDRDLO = kSelectLow; +const unsigned char kPowerLCDWRHI = kStrobeHigh; +const unsigned char kPowerLCDWRLO = kStrobeLow; +const unsigned char kPowerLCDCSHI = kAutoHigh; +const unsigned char kPowerLCDCSLO = kAutoLow; + +const unsigned char kLCDProcA0HI = kSelectHigh; +const unsigned char kLCDProcA0LO = kSelectLow; +const unsigned char kLCDProcRDHI = kInitHigh; +const unsigned char kLCDProcRDLO = kInitLow; +const unsigned char kLCDProcWRHI = kAutoHigh; +const unsigned char kLCDProcWRLO = kAutoLow; +const unsigned char kLCDProcCSHI = kStrobeHigh; +const unsigned char kLCDProcCSLO = kStrobeLow; + +const unsigned char kTweakersA0HI = kSelectHigh; +const unsigned char kTweakersA0LO = kSelectLow; +const unsigned char kTweakersRDHI = kAutoHigh; +const unsigned char kTweakersRDLO = kAutoLow; +const unsigned char kTweakersWRHI = kInitHigh; +const unsigned char kTweakersWRLO = kInitLow; +const unsigned char kTweakersCSHI = kStrobeHigh; +const unsigned char kTweakersCSLO = kStrobeLow; + +const unsigned char kYASEDWA0HI = kAutoHigh; +const unsigned char kYASEDWA0LO = kAutoLow; +const unsigned char kYASEDWRDHI = kInitHigh; +const unsigned char kYASEDWRDLO = kInitLow; +const unsigned char kYASEDWWRHI = kStrobeHigh; +const unsigned char kYASEDWWRLO = kStrobeLow; +const unsigned char kYASEDWCSHI = kSelectHigh; +const unsigned char kYASEDWCSLO = kSelectLow; + + +cDriverSED1330::cDriverSED1330(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); + + port = new cParallelPort(); + + refreshCounter = 0; +} + +cDriverSED1330::~cDriverSED1330() +{ + delete port; + delete oldConfig; +} + +int cDriverSED1330::Init() +{ + int x; + struct timeval tv1, tv2; + + width = config->width; + if (width <= 0) + width = 320; + height = config->height; + if (height <= 0) + height = 240; + + // default values + oscillatorFrequency = 9600; + interface = kInterface6800; + A0HI = kOriginalA0HI; + A0LO = kOriginalA0LO; + RDHI = kOriginalRDHI; + RDLO = kOriginalRDLO; + WRHI = kOriginalWRHI; + WRLO = kOriginalWRLO; + CSHI = kOriginalCSHI; + CSLO = kOriginalCSLO; + ENHI = RDHI; + ENLO = RDLO; + RWHI = WRHI; + RWLO = WRLO; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "Wiring") + { + if (config->options[i].value == kWiringOriginal) + { + A0HI = kOriginalA0HI; + A0LO = kOriginalA0LO; + RDHI = kOriginalRDHI; + RDLO = kOriginalRDLO; + WRHI = kOriginalWRHI; + WRLO = kOriginalWRLO; + CSHI = kOriginalCSHI; + CSLO = kOriginalCSLO; + } + else if (config->options[i].value == kWiringPowerLCD) + { + A0HI = kPowerLCDA0HI; + A0LO = kPowerLCDA0LO; + RDHI = kPowerLCDRDHI; + RDLO = kPowerLCDRDLO; + WRHI = kPowerLCDWRHI; + WRLO = kPowerLCDWRLO; + CSHI = kPowerLCDCSHI; + CSLO = kPowerLCDCSLO; + } + else if (config->options[i].value == kWiringLCDProc) + { + A0HI = kLCDProcA0HI; + A0LO = kLCDProcA0LO; + RDHI = kLCDProcRDHI; + RDLO = kLCDProcRDLO; + WRHI = kLCDProcWRHI; + WRLO = kLCDProcWRLO; + CSHI = kLCDProcCSHI; + CSLO = kLCDProcCSLO; + } + else if (config->options[i].value == kWiringTweakers) + { + A0HI = kTweakersA0HI; + A0LO = kTweakersA0LO; + RDHI = kTweakersRDHI; + RDLO = kTweakersRDLO; + WRHI = kTweakersWRHI; + WRLO = kTweakersWRLO; + CSHI = kTweakersCSHI; + CSLO = kTweakersCSLO; + } + else if (config->options[i].value == kWiringYASEDW) + { + A0HI = kYASEDWA0HI; + A0LO = kYASEDWA0LO; + RDHI = kYASEDWRDHI; + RDLO = kYASEDWRDLO; + WRHI = kYASEDWWRHI; + WRLO = kYASEDWWRLO; + CSHI = kYASEDWCSHI; + CSLO = kYASEDWCSLO; + } + else + { + syslog(LOG_ERR, "%s error: wiring %s not supported, using default (Original)!\n", + config->name.c_str(), config->options[i].value.c_str()); + } + ENHI = RDHI; + ENLO = RDLO; + RWHI = WRHI; + RWLO = WRLO; + } + else if (config->options[i].name == "OscillatorFrequency") + { + int freq = atoi(config->options[i].value.c_str()); + if (freq > 1000 && freq < 15000) + oscillatorFrequency = freq; + else + syslog(LOG_ERR, "%s error: oscillator frequency %d out of range, using default (%d)!\n", + config->name.c_str(), freq, oscillatorFrequency); + } + if (config->options[i].name == "Interface") + { + if (config->options[i].value == "6800") + interface = kInterface6800; + else if (config->options[i].value == "8080") + interface = kInterface8080; + else + syslog(LOG_ERR, "%s error: interface %s not supported, using default (6800)!\n", + config->name.c_str(), config->options[i].value.c_str()); + } + } + + // setup lcd array (wanted state) + newLCD = new unsigned char *[(width + 7) / 8]; + if (newLCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + newLCD[x] = new unsigned char[height]; + memset(newLCD[x], 0, height); + } + } + // setup lcd array (current state) + oldLCD = new unsigned char *[(width + 7) / 8]; + if (oldLCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + oldLCD[x] = new unsigned char[height]; + memset(oldLCD[x], 0, height); + } + } + + if (config->device == "") + { + // use DirectIO + if (port->Open(config->port) != 0) + return -1; + uSleep(10); + } + else + { + // use ppdev + if (port->Open(config->device.c_str()) != 0) + return -1; + } + + if (nSleepInit() != 0) + { + syslog(LOG_DEBUG, "%s: INFO: cannot change wait parameters (cDriver::Init)\n", config->name.c_str()); + useSleepInit = false; + } + else + { + useSleepInit = true; + } + + syslog(LOG_DEBUG, "%s: benchmark started.\n", config->name.c_str()); + gettimeofday(&tv1, 0); + for (x = 0; x < 1000; x++) + { + port->WriteData(x % 0x100); + } + gettimeofday(&tv2, 0); + if (useSleepInit) + nSleepDeInit(); + timeForPortCmdInNs = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec); + syslog(LOG_DEBUG, "%s: benchmark stopped. Time for Command: %ldns\n", config->name.c_str(), timeForPortCmdInNs); + + // initialize graphic mode + InitGraphic(); + + *oldConfig = *config; + + // clear display + Clear(); + // The SED1330 can have up to 64k memory. If there is less memory + // it will be overwritten twice or more times. + WriteCmd(C_MWRITE); + for (x = 0; x < 65536; x++) + WriteData(0x00); + + WriteCmd(C_CSRW); + WriteData(0x00); // initializing cursor adress, low byte + WriteData(0x00); // high byte + + port->Release(); + + syslog(LOG_INFO, "%s: SED1330 initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverSED1330::DeInit() +{ + int x; + + // free lcd array (wanted state) + if (newLCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + delete[] newLCD[x]; + } + delete[] newLCD; + } + // free lcd array (current state) + if (oldLCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + delete[] oldLCD[x]; + } + delete[] oldLCD; + } + + if (port->Close() != 0) + return -1; + return 0; +} + +int cDriverSED1330::CheckSetup() +{ + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +int cDriverSED1330::InitGraphic() +{ + // initialize setup with two graphic screens + // most parts taken from Thomas Baumann's LCD-Test program + int cr; + int memGraph; + int sad1l, sad1h, sad2l, sad2h; + + cr = (width / FX - 1) * BPC; + memGraph = ((cr + 1) * height); // required memory for a graphic layer + sad1l = SAD1 & 0xFF; + sad1h = SAD1 >> 8 & 0xFF; + sad2l = ((SAD1 + memGraph) & 0xFF); + sad2h = ((SAD1 + memGraph) >> 8 & 0xFF); + + WriteCmd(C_SYSTEMSET); + WriteData(0x30 + M0 + (M1 << 1) + (M2 << 2)); + WriteData(0x80 + (FX - 1)); + WriteData(0x00 + (FY - 1)); + WriteData(cr); // C/R .. display adresses per line + WriteData((oscillatorFrequency * 1000 / (70 * height) - 1) / 9); // TC/R .. , fFR=70Hz + WriteData(height - 1); // L/F .. display lines per screen + WriteData(cr + 1); // adresses per virtual display line, low byte + WriteData(0x00); // adresses per virtual display line, high byte + // currently we don't use virtual screens greater then the display, + // therefore the high byte should always be zero + + WriteCmd(C_SCROLL); + WriteData(sad1l); // low-byte startadress first layer + WriteData(sad1h); // high-byte startadress first layer + WriteData(height); // lines per screen + WriteData(sad2l); // low-byte startadress second layer + WriteData(sad2h); // high-byte startadress second layer + WriteData(height); // lines per screen + WriteData(0x00); // low-byte startadress third layer, not used + WriteData(0x00); // high-byte startadress third layer, not used + WriteData(0x00); // low-byte startadress fourth layer, not used + WriteData(0x00); // high-byte startadress fourth layer, not used + + WriteCmd(C_CSRFORM); + WriteData(0x00); // cursor with: 1 pixel + WriteData(0x86); // cursor height: 7 lines, block mode + + WriteCmd(C_CSRDIR_R); // automatic cursor increment to the right + + WriteCmd(C_OVLAY); + WriteData(0x0C); // two layer composition with Priority-OR + + WriteCmd(C_HDOTSCR); + WriteData(0x00); + + WriteCmd(C_DISPON); // display ON with + WriteData(0x04); // cursor OFF and first layer ON without flashing + + WriteCmd(C_CSRW); + WriteData(0x00); // initializing cursor adress, low byte + WriteData(0x00); // high byte + + return 0; +} + +void cDriverSED1330::WriteCmd(unsigned char cmd) +{ + //if (useSleepInit) + // nSleepInit(); + + if (interface == kInterface6800) + { + // set A0 high (instruction), RW low (write) and E low + port->WriteControl(A0HI | CSLO | RWLO | ENLO); + //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming); + // Output the actual command + port->WriteData(cmd); + //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming); + // set E high + port->WriteControl(A0HI | CSLO | RWLO | ENHI); + //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + // set E low + port->WriteControl(A0HI | CSLO | RWLO | ENLO); + //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + } + else + { + // set A0 high (instruction), CS low, RD and WR high + port->WriteControl(A0HI | CSLO | RDHI | WRHI); + //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming); + // Output the actual command + port->WriteData(cmd); + //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming); + // set WR low + port->WriteControl(A0HI | CSLO | RDHI | WRLO); + //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + // set WR high + port->WriteControl(A0HI | CSLO | RDHI | WRHI); + //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + } + + //if (useSleepInit) + // nSleepDeInit(); +} + +void cDriverSED1330::WriteData(unsigned char data) +{ + //if (useSleepInit) + // nSleepInit(); + + if (interface == kInterface6800) + { + // set A0 low (data), RW low (write) and E low + port->WriteControl(A0LO | CSLO | RWLO | ENLO); + //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming); + // Output the actual data + port->WriteData(data); + //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming); + // set E high + port->WriteControl(A0LO | CSLO | RWLO | ENHI); + //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + // set E low + port->WriteControl(A0LO | CSLO | RWLO | ENLO); + //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + } + else + { + // set A0 low (data), CS low, RD and WR high + port->WriteControl(A0LO | CSLO | RDHI | WRHI); + //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming); + // Output the actual data + port->WriteData(data); + //nSleep(140 - timeForPortCmdInNs + 100 * config->adjustTiming); + // set WR low + port->WriteControl(A0LO | CSLO | RDHI | WRLO); + //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + // set WR high + port->WriteControl(A0LO | CSLO | RDHI | WRHI); + //nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + } + + //if (useSleepInit) + // nSleepDeInit(); +} + +void cDriverSED1330::Clear() +{ + for (int x = 0; x < (width + 7) / 8; x++) + memset(newLCD[x], 0, height); +} + +void cDriverSED1330::Set8Pixels(int x, int y, unsigned char data) +{ + if (x >= width || y >= height) + return; + + if (!config->upsideDown) + { + // normal orientation + newLCD[x / 8][y] = newLCD[x / 8][y] | data; + } + else + { + // upside down orientation + x = width - 1 - x; + y = height - 1 - y; + newLCD[x / 8][y] = newLCD[x / 8][y] | ReverseBits(data); + } +} + +void cDriverSED1330::Refresh(bool refreshAll) +{ + int x; + int y; + int pos = SAD1; + + if (CheckSetup() > 0) + refreshAll = true; + + if (config->refreshDisplay > 0) + { + refreshCounter = (refreshCounter + 1) % config->refreshDisplay; + if (!refreshAll && !refreshCounter) + refreshAll = true; + } + + port->Claim(); + + if (refreshAll) + { + // draw all + // set cursor to startadress + WriteCmd(C_CSRW); + WriteData(pos & 0xFF); + WriteData(pos >> 8); + + for (y = 0; y < height; y++) + { + for (x = 0; x < (width + 7) / 8; x++) + { + WriteCmd(C_MWRITE); // cursor increments automatically + WriteData(newLCD[x][y] ^ (config->invert ? 0xff : 0x00)); + oldLCD[x][y] = newLCD[x][y]; + pos++; + } + } + // and reset RefreshCounter + refreshCounter = 0; + } + else + { + // draw only the changed bytes + bool cs = false; + for (y = 0; y < height; y++) + { + for (x = 0; x < (width + 7) / 8; x++) + { + if (newLCD[x][y] != oldLCD[x][y]) + { + if (!cs) + { + WriteCmd(C_CSRW); + WriteData(pos & 0xFF); + WriteData(pos >> 8); + WriteCmd(C_MWRITE); + cs = true; + } + WriteData(newLCD[x][y] ^ (config->invert ? 0xff : 0x00)); + oldLCD[x][y] = newLCD[x][y]; + } + else + { + cs = false; + } + pos++; + } + } + } + port->Release(); +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/sed1330.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/sed1330.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,78 @@ +/* + * GraphLCD driver library + * + * sed1330.h - SED1330 driver class + * + * based on: hd61830.c + * (c) 2001-2004 Carsten Siebholz + * + * changes for Seiko-Epson displays: Mar 2004 + * (c) 2004 Heinz Gressenberger + * + * init sequence taken from Thomas Baumann's LCD-Test program + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003 Roland Praml + */ + +#ifndef _GLCDDRIVERS_SED1330_H_ +#define _GLCDDRIVERS_SED1330_H_ + +#include "driver.h" + + +namespace GLCD +{ + +class cDriverConfig; +class cParallelPort; + +class cDriverSED1330 : public cDriver +{ +private: + cParallelPort * port; + unsigned char ** newLCD; // wanted state + unsigned char ** oldLCD; // current state + int refreshCounter; + long timeForPortCmdInNs; + cDriverConfig * config; + cDriverConfig * oldConfig; + bool useSleepInit; + + int oscillatorFrequency; + int interface; + unsigned char A0HI; + unsigned char A0LO; + unsigned char RDHI; + unsigned char RDLO; + unsigned char ENHI; + unsigned char ENLO; + unsigned char WRHI; + unsigned char WRLO; + unsigned char RWHI; + unsigned char RWLO; + unsigned char CSHI; + unsigned char CSLO; + + int CheckSetup(); + int InitGraphic(); + void WriteCmd(unsigned char cmd); + void WriteData(unsigned char data); + +public: + cDriverSED1330(cDriverConfig * config); + virtual ~cDriverSED1330(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/sed1520.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/sed1520.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,402 @@ +/* + * GraphLCD driver library + * + * sed1520.c - SED1520 driver class + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003 Andreas 'randy' Weinberger + */ + +#include +#include + +#include "common.h" +#include "config.h" +#include "port.h" +#include "sed1520.h" + + +namespace GLCD +{ + +// commands +const unsigned char kSEAD = 0x00; // Set (X) Column Address +const unsigned char kSEPA = 0xb8; // Set (Y) Page Address +const unsigned char kSEDS = 0xc0; // Set Display Start Line +const unsigned char kDION = 0xaf; // Display on +const unsigned char kDIOF = 0xae; // Display off + +// control bits for DirectIO +#define CE1 0x01 +#define CE1HI 0x01 // Chip Enable 1 on +#define CE1LO 0x00 // Chip Enable 1 off + +const unsigned char kCS1HI = 0x00; // Chip Select 1 +const unsigned char kCS1LO = 0x01; +const unsigned char kCS2HI = 0x04; // Chip Select 2 +const unsigned char kCS2LO = 0x00; +const unsigned char kCDHI = 0x08; // Command/Data Register Select +const unsigned char kCDLO = 0x00; +const unsigned char kLEDHI = 0x02; // LED Backlight (not supported currently) +const unsigned char kLEDLO = 0x00; + + +cDriverSED1520::cDriverSED1520(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); + + port = new cParallelPort(); + + refreshCounter = 0; +} + +cDriverSED1520::~cDriverSED1520() +{ + delete port; + delete oldConfig; +} + +int cDriverSED1520::Init() +{ + int x; + int i; + struct timeval tv1, tv2; + + if (!(config->width % 8) == 0) { + width = config->width + (8 - (config->width % 8)); + } else { + width = config->width; + } + + if (!(config->height % 8) == 0) { + height = config->height + (8 - (config->height % 8)); + } else { + height = config->height; + } + + if (width <= 0) + width = 120; + if (height <= 0) + height = 32; + + SEAD = kSEAD; + SEPA = kSEPA; + SEDS = kSEDS; + DION = kDION; + DIOF = kDIOF; + LED = kLEDHI; + CDHI = kCDHI; + CDLO = kCDLO; + CS1HI = kCS1HI; + CS1LO = kCS1LO; + CS2HI = kCS2HI; + CS2LO = kCS2LO; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "") + { + } + } + + // setup linear lcd array + LCD = new unsigned char *[(width + 7) / 8]; + if (LCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + LCD[x] = new unsigned char[height]; + memset(LCD[x], 0, height); + } + } + // setup the lcd array for the paged sed1520 + LCD_page = new unsigned char *[width]; + if (LCD_page) + { + for (x = 0; x < width; x++) + { + LCD_page[x] = new unsigned char[(height + 7) / 8]; + memset(LCD_page[x], 0, (height + 7) / 8); + } + } + + if (config->device == "") + { + // use DirectIO + if (port->Open(config->port) != 0) + return -1; + uSleep(10); + } + else + { + // use ppdev + if (port->Open(config->device.c_str()) != 0) + return -1; + } + + if (nSleepInit() != 0) + { + syslog(LOG_DEBUG, "%s: INFO: cannot change wait parameters (cDriver::Init)\n", config->name.c_str()); + useSleepInit = false; + } + else + { + useSleepInit = true; + } + + syslog(LOG_DEBUG, "%s: benchmark started.\n", config->name.c_str()); + gettimeofday(&tv1, 0); + for (i = 0; i < 1000; i++) + { + port->WriteData(i % 0x100); + } + gettimeofday(&tv2, 0); + if (useSleepInit) + nSleepDeInit(); + timeForPortCmdInNs = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec); + syslog(LOG_DEBUG, "%s: benchmark stopped. Time for Command: %ldns\n", config->name.c_str(), timeForPortCmdInNs); + + // initialize graphic mode + InitGraphic(); + + port->Release(); + + *oldConfig = *config; + + // clear display + Clear(); + + syslog(LOG_INFO, "%s: SED1520 initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverSED1520::DeInit() +{ + int x; + + // free linear lcd array + if (LCD) + { + for (x = 0; x < (width + 7) / 8; x++) + { + delete[] LCD[x]; + } + delete[] LCD; + } + // free the lcd array for the paged sed1520 + if (LCD_page) + { + for (x = 0; x < width; x++) + { + delete[] LCD_page[x]; + } + delete[] LCD_page; + } + + if (port->Close() != 0) + return -1; + return 0; +} + +int cDriverSED1520::CheckSetup() +{ + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +int cDriverSED1520::InitGraphic() +{ + // initialize controller1, set display start 0, set page 0, set y address 0, display on + SED1520Cmd(SEDS, 1); + SED1520Cmd(SEPA, 1); + SED1520Cmd(SEAD, 1); + SED1520Cmd(DION, 1); + + // initialize controller2, set display start 0, set page 0, set y address 0, display on + SED1520Cmd(SEDS, 2); + SED1520Cmd(SEPA, 2); + SED1520Cmd(SEAD, 2); + SED1520Cmd(DION, 2); + + return 0; +} + +void cDriverSED1520::SED1520Cmd(unsigned char data, int cmdcs) +{ + if (useSleepInit) + nSleepInit(); + + switch (cmdcs) + { + case 1: + port->WriteControl(CDHI | CS1LO | CS2LO | LEDHI); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + port->WriteData(data); + nSleep(650 - timeForPortCmdInNs + 100 * config->adjustTiming); + port->WriteControl(CDHI | CS1HI | CS2LO | LEDHI); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + break; + case 2: + port->WriteControl(CDHI | CS1LO | CS2LO | LED); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + port->WriteData(data); + nSleep(650 - timeForPortCmdInNs + 100 * config->adjustTiming); + port->WriteControl(CDHI | CS1LO | CS2HI | LED); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + break; + } + if (useSleepInit) + nSleepDeInit(); +} + +void cDriverSED1520::SED1520Data(unsigned char data, int datacs) +{ + if (useSleepInit) + nSleepInit(); + + switch (datacs) + { + case 1: + port->WriteControl(CDLO | CS1LO | CS2LO | LEDHI); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + port->WriteData(data); + nSleep(650 - timeForPortCmdInNs + 100 * config->adjustTiming); + port->WriteControl(CDLO | CS1HI | CS2LO | LEDHI); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + break; + case 2: + port->WriteControl(CDLO | CS1LO | CS2LO | LED); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + port->WriteData(data); + nSleep(650 - timeForPortCmdInNs + 100 * config->adjustTiming); + port->WriteControl(CDLO | CS1LO | CS2HI | LED); + nSleep(450 - timeForPortCmdInNs + 100 * config->adjustTiming); + break; + } + if (useSleepInit) + nSleepDeInit(); +} + +void cDriverSED1520::Clear() +{ + for (int x = 0; x < (width + 7) / 8; x++) + memset(LCD[x], 0, height); +} + +void cDriverSED1520::Set8Pixels (int x, int y, unsigned char data) +{ + if (x >= width || y >= height) + return; + + if (!config->upsideDown) + { + // normal orientation + LCD[x / 8][y] = LCD[x / 8][y] | data; + } + else + { + // upside down orientation + x = width - 1 - x; + y = height - 1 - y; + LCD[x / 8][y] = LCD[x / 8][y] | ReverseBits(data); + } +} + +void cDriverSED1520::Refresh(bool refreshAll) +{ + int x,y,xx,yy; + unsigned char dByte, oneBlock[8]; + + if (CheckSetup() > 0) + refreshAll = true; + + if (config->refreshDisplay > 0) + { + refreshCounter = (refreshCounter + 1) % config->refreshDisplay; + if (!refreshAll && !refreshCounter) + refreshAll = true; + } + + refreshAll = true; // differential update is not yet supported + + if (refreshAll) + { + // draw all + + // convert the linear lcd array to the paged array for the display + for (y = 0; y < (height + 7) / 8; y++) + { + for (x = 0; x < (width + 7) / 8; x++) + { + for (yy = 0; yy < 8; yy++) + { + oneBlock[yy] = LCD[x][yy + (y * 8)] ^ (config->invert ? 0xff : 0x00); + } + for (xx = 0; xx < 8; xx++) + { + dByte = 0; + for (yy = 0; yy < 8; yy++) + { + if (oneBlock[yy] & bitmask[xx]) + { + dByte += (1 << yy); + } + } + LCD_page[x * 8 + xx][y] = dByte; + } + } + } + + port->Claim(); + + // send lcd_soll data to display, controller 1 + // set page and start address + for (y = 0; y < (height + 7) / 8; y++) + { + SED1520Cmd(SEAD, 1); + SED1520Cmd(SEPA + y, 1); + SED1520Data(0x00 ^ (config->invert ? 0xff : 0x00), 1); // fill first row with zero + + for (x = 0; x < width / 2 + 1; x++) + { + SED1520Data(LCD_page[x][y], 1); + } + + SED1520Cmd(SEAD, 2); + SED1520Cmd(SEPA + y, 2); + + for (x = width / 2; x < width; x++) + { + SED1520Data(LCD_page[x][y], 2); + } + + SED1520Data(0x00 ^ (config->invert ? 0xff : 0x00), 2); // fill last row with zero + } + port->Release(); + } + else + { + // draw only the changed bytes + } +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/sed1520.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/sed1520.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,72 @@ +/* + * GraphLCD driver library + * + * sed1520.h - SED1520 driver class + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003 Andreas 'randy' Weinberger + */ + +#ifndef _GLCDDRIVERS_SED1520_H_ +#define _GLCDDRIVERS_SED1520_H_ + +#include "driver.h" + + +namespace GLCD +{ + +class cDriverConfig; +class cParallelPort; + +class cDriverSED1520 : public cDriver +{ +private: + cParallelPort * port; + unsigned char ** LCD; // linear lcd display "memory" + unsigned char ** LCD_page; // paged lcd display "memory" + int refreshCounter; + long timeForPortCmdInNs; + cDriverConfig * config; + cDriverConfig * oldConfig; + bool useSleepInit; + + int SEAD; + int SEPA; + int SEDS; + int DION; + int DIOF; + + int CS1LO; + int CS2LO; + int CS1HI; + int CS2HI; + + int CDHI; + int CDLO; + + int LED; + int LEDHI; + + int CheckSetup(); + int InitGraphic(); + void SED1520Cmd(unsigned char data, int cmscd); + void SED1520Data(unsigned char data, int datacs); + +public: + cDriverSED1520(cDriverConfig * config); + virtual ~cDriverSED1520(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/serdisp.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/serdisp.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,467 @@ +/* + * GraphLCD driver library + * + * serdisp.h - include support for displays supported by serdisplib (if library is installed) + * http://serdisplib.sourceforge.net + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003-2005 Wolfgang Astleitner + */ + +#include +#include +#include +#include + +#include "common.h" +#include "config.h" +#include "serdisp.h" + +#define SERDISP_VERSION(a,b) ((long)(((a) << 8) + (b))) +#define SERDISP_VERSION_GET_MAJOR(_c) ((int)( (_c) >> 8 )) +#define SERDISP_VERSION_GET_MINOR(_c) ((int)( (_c) & 0xFF )) + +// taken from serdisp_control.h +#define FEATURE_CONTRAST 0x01 +#define FEATURE_REVERSE 0x02 +#define FEATURE_BACKLIGHT 0x03 +#define FEATURE_ROTATE 0x04 + +#define SD_COL_BLACK 0xFF000000 + +namespace GLCD +{ + +cDriverSerDisp::cDriverSerDisp(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); + + dd = (void *) NULL; +} + +cDriverSerDisp::~cDriverSerDisp(void) +{ + delete oldConfig; +} + +int cDriverSerDisp::Init(void) +{ + char* errmsg; // error message returned by dlerror() + + std::string controller; + std::string optionstring = ""; + std::string wiringstring; + + + // dynamically load serdisplib using dlopen() & co. + + sdhnd = dlopen("libserdisp.so", RTLD_LAZY); + if (!sdhnd) { // try /usr/local/lib + sdhnd = dlopen("/usr/local/lib/libserdisp.so", RTLD_LAZY); + } + + if (!sdhnd) { // serdisplib seems not to be installed + syslog(LOG_ERR, "%s: error: unable to dynamically load library '%s'. Err: %s (cDriver::Init)\n", + config->name.c_str(), "libserdisp.so", "not found"); + return -1; + } + + dlerror(); // clear error code + + /* pre-init some flags, function pointers, ... */ + supports_options = 0; + fg_colour = 1; + bg_colour = -1; + + // get serdisp version + fp_serdisp_getversioncode = (long int (*)()) dlsym(sdhnd, "serdisp_getversioncode"); + + if (dlerror()) { // no serdisp_getversioncode() -> version of serdisplib is < 1.95 + syslog(LOG_DEBUG, "%s: INFO: symbol serdisp_getversioncode unknown: autodetecting pre 1.95 serdisplib version (cDriver::Init)\n", + config->name.c_str()); + + fp_SDCONN_open = (void*(*)(const char*)) dlsym(sdhnd, "SDCONN_open"); + if (dlerror()) { // no SDCONN_open() -> version of serdisplib is < 1.93 + serdisp_version = SERDISP_VERSION(1,92); + syslog(LOG_DEBUG, "%s: INFO: detected serdisplib version <= 1.92 (cDriver::Init)\n", config->name.c_str()); + + fp_PP_open = (void*(*)(const char*))dlsym(sdhnd, "PP_open"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "PP_open", errmsg); + return -1; + } + fp_PP_close = (void*(*)(void*))dlsym(sdhnd, "PP_close"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "PP_close", errmsg); + return -1; + } + } else { + serdisp_version = SERDISP_VERSION(1,94); // no serdisp_getversioncode, but SDCONN_open: 1.93 or 1.94 + syslog(LOG_DEBUG, "%s: INFO: detected serdisplib version 1.93 or 1.94 (cDriver::Init)\n", config->name.c_str()); + + fp_serdisp_quit = (void (*)(void*)) dlsym(sdhnd, "serdisp_quit"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_quit", errmsg); + return -1; + } + } + + fp_serdisp_setpixcol = (void (*)(void*, int, int, long int)) dlsym(sdhnd, "serdisp_setpixel"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_setpixel", errmsg); + return -1; + } + fg_colour = 1; /* set foreground to 'pixel on' */ + + } else { // serdisp version >= 1.95 + serdisp_version = fp_serdisp_getversioncode(); + syslog(LOG_DEBUG, "%s: INFO: detected serdisplib version %d.%d (cDriver::Init)\n", + config->name.c_str(), SERDISP_VERSION_GET_MAJOR(serdisp_version), SERDISP_VERSION_GET_MINOR(serdisp_version)); + + + fp_SDCONN_open = (void*(*)(const char*)) dlsym(sdhnd, "SDCONN_open"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "SDCONN_open", errmsg); + return -1; + } + fp_serdisp_quit = (void (*)(void*)) dlsym(sdhnd, "serdisp_quit"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_quit", errmsg); + return -1; + } + fp_serdisp_setpixcol = (void (*)(void*, int, int, long int)) dlsym(sdhnd, "serdisp_setcolour"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_setcolour", errmsg); + return -1; + } + fg_colour = SD_COL_BLACK; /* set foreground colour to black */ + + if (serdisp_version >= SERDISP_VERSION(1,96) ) { + supports_options = 1; + + fp_serdisp_isoption = (int (*)(void*, const char*)) dlsym(sdhnd, "serdisp_isoption"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_isoption", errmsg); + return -1; + } + fp_serdisp_setoption = (void (*)(void*, const char*, long int)) dlsym(sdhnd, "serdisp_setoption"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_setoption", errmsg); + return -1; + } + } /* >= 1.96 */ + } + + // load other symbols that will be required + fp_serdisp_init = (void*(*)(void*, const char*, const char*)) dlsym(sdhnd, "serdisp_init"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_init", errmsg); + return -1; + } + + fp_serdisp_rewrite = (void (*)(void*)) dlsym(sdhnd, "serdisp_rewrite"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_rewrite", errmsg); + return -1; + } + + fp_serdisp_update = (void (*)(void*)) dlsym(sdhnd, "serdisp_update"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_update", errmsg); + return -1; + } + + fp_serdisp_clearbuffer = (void (*)(void*)) dlsym(sdhnd, "serdisp_clearbuffer"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_clearbuffer", errmsg); + return -1; + } + + fp_serdisp_feature = (int (*)(void*, int, int)) dlsym(sdhnd, "serdisp_feature"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_feature", errmsg); + return -1; + } + + fp_serdisp_close = (void (*)(void*))dlsym(sdhnd, "serdisp_close"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_close", errmsg); + return -1; + } + + fp_serdisp_getwidth = (int (*)(void*)) dlsym(sdhnd, "serdisp_getwidth"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_getwidth", errmsg); + return -1; + } + + fp_serdisp_getheight = (int (*)(void*)) dlsym(sdhnd, "serdisp_getheight"); + if ( (errmsg = dlerror()) != NULL ) { // should not happen + syslog(LOG_ERR, "%s: error: cannot load symbol %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), "serdisp_getheight", errmsg); + return -1; + } + + // done loading all required symbols + + + // setting up the display + width = 0; + height = 0; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "Controller") { + controller = config->options[i].value; + } else if (config->options[i].name == "Options") { + optionstring = config->options[i].value; + } else if (config->options[i].name == "Wiring") { + wiringstring = config->options[i].value; + } else if (config->options[i].name == "FGColour") { + fg_colour = strtoul(config->options[i].value.c_str(), (char **)NULL, 0); + fg_colour |= 0xFF000000L; /* force alpha to 0xFF */ + } else if (config->options[i].name == "BGColour") { + bg_colour = strtoul(config->options[i].value.c_str(), (char **)NULL, 0); + bg_colour |= 0xFF000000L; /* force alpha to 0xFF */ + } + } + + if (wiringstring.length()) { + optionstring = "WIRING=" + wiringstring + ((optionstring != "") ? ";" + optionstring : ""); + } + + if (controller == "") + { + syslog(LOG_ERR, "%s error: no controller given!\n", config->name.c_str()); + return -1; + } + + + if (config->device == "") + { + // use DirectIO + + // neither device nor port is set + if (config->port == 0) + return -1; + + char temp[10]; + snprintf(temp, 8, "0x%x", config->port); + + if (serdisp_version < SERDISP_VERSION(1,93) ) { + sdcd = fp_PP_open(temp); + } else { + sdcd = fp_SDCONN_open(temp); + } + + if (sdcd == 0) { + syslog(LOG_ERR, "%s: error: unable to open port 0x%x for display %s. (cDriver::Init)\n", + config->name.c_str(), config->port, controller.c_str()); + return -1; + } + + uSleep(10); + } + else + { + // use ppdev + if (serdisp_version < SERDISP_VERSION(1,93) ) { + sdcd = fp_PP_open(config->device.c_str()); + } else { + sdcd = fp_SDCONN_open(config->device.c_str()); + } + + if (sdcd == 0) { + syslog(LOG_ERR, "%s: error: unable to open device %s for display %s. (cDriver::Init)\n", + config->name.c_str(), config->device.c_str(), controller.c_str()); + return -1; + } + } + + if (serdisp_version < SERDISP_VERSION(1,95) ) + dd = fp_serdisp_init(sdcd, controller.c_str(), ""); + else + dd = fp_serdisp_init(sdcd, controller.c_str(), optionstring.c_str()); + + if (!dd) + { + syslog(LOG_ERR, "%s: error: cannot open display %s. Err:%s (cDriver::Init)\n", + config->name.c_str(), controller.c_str(), "no handle"); + return -1; + } + + width = config->width; + if (width <= 0) + width = fp_serdisp_getwidth(dd); + height = config->height; + if (height <= 0) + height = fp_serdisp_getheight(dd); + + if (serdisp_version < SERDISP_VERSION(1,96) ) { + fp_serdisp_feature(dd, FEATURE_ROTATE, config->upsideDown); + fp_serdisp_feature(dd, FEATURE_CONTRAST, config->contrast); + fp_serdisp_feature(dd, FEATURE_BACKLIGHT, config->backlight); + fp_serdisp_feature(dd, FEATURE_REVERSE, config->invert); + } else { + /* standard options */ + fp_serdisp_setoption(dd, "ROTATE", config->upsideDown); + fp_serdisp_setoption(dd, "CONTRAST", config->contrast); + fp_serdisp_setoption(dd, "BACKLIGHT", config->backlight); + fp_serdisp_setoption(dd, "INVERT", config->invert); + + /* driver dependend options */ + for (unsigned int i = 0; i < config->options.size(); i++) { + std::string optionname = config->options[i].name; + if (optionname != "UpsideDown" && optionname != "Contrast" && + optionname != "Backlight" && optionname != "Invert") { + + if ( fp_serdisp_isoption(dd, optionname.c_str()) == 1 ) /* if == 1: option is existing AND r/w */ + fp_serdisp_setoption(dd, optionname.c_str(), strtol(config->options[i].value.c_str(), NULL, 0)); + } + } + + } + + *oldConfig = *config; + + // clear display + Clear(); + + syslog(LOG_INFO, "%s: SerDisp with %s initialized.\n", config->name.c_str(), controller.c_str()); + return 0; +} + +int cDriverSerDisp::DeInit(void) +{ + if (serdisp_version < SERDISP_VERSION(1,93) ) { + fp_serdisp_close(dd); + fp_PP_close(sdcd); + sdcd = NULL; + } else { + //fp_serdisp_quit(dd); + /* use serdisp_close instead of serdisp_quit so that showpic and showtext are usable together with serdisplib */ + fp_serdisp_close(dd); + } + (int) dlclose(sdhnd); + sdhnd = NULL; + + return 0; +} + +int cDriverSerDisp::CheckSetup() +{ + bool update = false; + + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->contrast != oldConfig->contrast) + { + fp_serdisp_feature(dd, FEATURE_CONTRAST, config->contrast); + oldConfig->contrast = config->contrast; + update = true; + } + if (config->backlight != oldConfig->backlight) + { + fp_serdisp_feature(dd, FEATURE_BACKLIGHT, config->backlight); + oldConfig->backlight = config->backlight; + update = true; + } + if (config->upsideDown != oldConfig->upsideDown) + { + fp_serdisp_feature(dd, FEATURE_ROTATE, config->upsideDown); + oldConfig->upsideDown = config->upsideDown; + update = true; + } + if (config->invert != oldConfig->invert) + { + fp_serdisp_feature(dd, FEATURE_REVERSE, config->invert); + oldConfig->invert = config->invert; + update = true; + } + + /* driver dependend options */ + for (unsigned int i = 0; i < config->options.size(); i++) { + std::string optionname = config->options[i].name; + if (optionname != "UpsideDown" && optionname != "Contrast" && + optionname != "Backlight" && optionname != "Invert") { + + if ( fp_serdisp_isoption(dd, optionname.c_str()) == 1 ) /* if == 1: option is existing AND r/w */ + fp_serdisp_setoption(dd, optionname.c_str(), strtol(config->options[i].value.c_str(), NULL, 0)); + oldConfig->options[i] = config->options[i]; + update = true; + } + } + + + if (update) + return 1; + return 0; +} + +void cDriverSerDisp::Clear(void) +{ + if (bg_colour == -1) + fp_serdisp_clearbuffer(dd); + else { /* if bg_colour is set, draw background 'by hand' */ + int x,y; + for (y = 0; y < fp_serdisp_getheight(dd); y++) + for (x = 0; x < fp_serdisp_getwidth(dd); x++) + fp_serdisp_setpixcol(dd, x, y, bg_colour); /* >= 1.95: serdisp_setcolour(), < 1.95: serdisp_setpixel() */ + } +} + +void cDriverSerDisp::Set8Pixels(int x, int y, unsigned char data) { + int i, start, pixel; + + data = ReverseBits(data); + + start = (x >> 3) << 3; + + for (i = 0; i < 8; i++) { + pixel = data & (1 << i); + if (pixel) + fp_serdisp_setpixcol(dd, start + i, y, fg_colour); /* >= 1.95: serdisp_setcolour(), < 1.95: serdisp_setpixel() */ + else if (!pixel && bg_colour != -1) /* if bg_colour is set: use it if pixel is not set */ + fp_serdisp_setpixcol(dd, start + i, y, bg_colour); /* >= 1.95: serdisp_setcolour(), < 1.95: serdisp_setpixel() */ + } +} + +void cDriverSerDisp::Refresh(bool refreshAll) +{ + if (CheckSetup() == 1) + refreshAll = true; + + if (refreshAll) + fp_serdisp_rewrite(dd); + else + fp_serdisp_update(dd); +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/serdisp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/serdisp.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,78 @@ +/* + * GraphLCD driver library + * + * serdisp.h - include support for displays supported by serdisplib (if library is installed) + * http://serdisplib.sourceforge.net + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003-2005 Wolfgang Astleitner + */ + +#ifndef _GLCDDRIVERS_SERDISP_H_ +#define _GLCDDRIVERS_SERDISP_H_ + +#include "driver.h" + + +namespace GLCD +{ + +class cDriverConfig; + +class cDriverSerDisp : public cDriver +{ +private: + + cDriverConfig * config; + cDriverConfig * oldConfig; + + long serdisp_version; + + int supports_options; + long fg_colour; + long bg_colour; + + void* sdhnd; // serdisplib handle + void* dd; // display descriptor + void* sdcd; // serdisp connect descriptor + + long (*fp_serdisp_getversioncode) (); + + void* (*fp_SDCONN_open) (const char sdcdev[]); + + void* (*fp_PP_open) (const char sdcdev[]); + void* (*fp_PP_close) (void* sdcd); + + void* (*fp_serdisp_init) (void* sdcd, const char dispname[], const char extra[]); + void (*fp_serdisp_rewrite) (void* dd); + void (*fp_serdisp_update) (void* dd); + void (*fp_serdisp_clearbuffer) (void* dd); + void (*fp_serdisp_setpixcol) (void* dd, int x, int y, long colour); // serdisp_setpixel or serdisp_setcolour + int (*fp_serdisp_feature) (void* dd, int feature, int value); + int (*fp_serdisp_isoption) (void* dd, const char* optionname); + void (*fp_serdisp_setoption) (void* dd, const char* optionname, long value); + int (*fp_serdisp_getwidth) (void* dd); + int (*fp_serdisp_getheight) (void* dd); + void (*fp_serdisp_quit) (void* dd); + void (*fp_serdisp_close) (void* dd); + + int CheckSetup(); + +public: + + cDriverSerDisp(cDriverConfig * config); + virtual ~cDriverSerDisp(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +#endif + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/simlcd.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/simlcd.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,183 @@ +/* + * GraphLCD driver library + * + * simlcd.c - SimLCD driver class + * Output goes to a file instead of lcd. + * Use SimLCD tool to view this file. + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2001-2004 Carsten Siebholz + */ + +#include +#include + +#include "common.h" +#include "config.h" +#include "simlcd.h" + + +namespace GLCD +{ + +cDriverSimLCD::cDriverSimLCD(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); +} + +cDriverSimLCD::~cDriverSimLCD() +{ + delete oldConfig; +} + +int cDriverSimLCD::Init() +{ + width = config->width; + if (width <= 0) + width = 240; + height = config->height; + if (height <= 0) + height = 128; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "") + { + } + } + + // setup lcd array + LCD = new unsigned char *[(width + 7) / 8]; + if (LCD) + { + for (int x = 0; x < (width + 7) / 8; x++) + { + LCD[x] = new unsigned char[height]; + memset(LCD[x], 0, height); + } + } + + *oldConfig = *config; + + // clear display + Clear(); + + syslog(LOG_INFO, "%s: SIMLCD initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverSimLCD::DeInit() +{ + // free lcd array + if (LCD) + { + for (int x = 0; x < (width + 7) / 8; x++) + { + delete[] LCD[x]; + } + delete[] LCD; + } + + return 0; +} + +int cDriverSimLCD::CheckSetup() +{ + if (config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +void cDriverSimLCD::Clear() +{ + for (int x = 0; x < (width + 7) / 8; x++) + memset(LCD[x], 0, height); +} + +void cDriverSimLCD::Set8Pixels(int x, int y, unsigned char data) +{ + if (x >= width || y >= height) + return; + + if (!config->upsideDown) + { + // normal orientation + LCD[x / 8][y] = LCD[x / 8][y] | data; + } + else + { + // upside down orientation + x = width - 1 - x; + y = height - 1 - y; + LCD[x / 8][y] = LCD[x / 8][y] | ReverseBits(data); + } +} + +void cDriverSimLCD::Refresh(bool refreshAll) +{ + FILE * fp = NULL; + int x; + int y; + int i; + unsigned char c; + + if (CheckSetup() > 0) + refreshAll = true; + + fp = fopen("/tmp/simlcd.sem", "r"); + if (!fp || refreshAll) + { + if (fp) + fclose(fp); + fp = fopen("/tmp/simlcd.dat", "w"); + if (fp) + { + for (y = 0; y < height; y++) + { + for (x = 0; x < (width + 7) / 8; x++) + { + c = LCD[x][y] ^ (config->invert ? 0xff : 0x00); + for (i = 0; i < 8; i++) + { + if (c & 0x80) + { + fprintf(fp,"#"); + } + else + { + fprintf(fp,"."); + } + c = c << 1; + } + } + fprintf(fp,"\n"); + } + fclose(fp); + } + + fp = fopen("/tmp/simlcd.sem", "w"); + fclose(fp); + } + else + { + fclose(fp); + } +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/simlcd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/simlcd.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,48 @@ +/* + * GraphLCD driver library + * + * simlcd.h - SimLCD driver class + * Output goes to a file instead of lcd. + * Use SimLCD tool to view this file. + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2001-2004 Carsten Siebholz + */ + +#ifndef _GLCDDRIVERS_SIMLCD_H_ +#define _GLCDDRIVERS_SIMLCD_H_ + +#include "driver.h" + + +namespace GLCD +{ + +class cDriverConfig; + +class cDriverSimLCD : public cDriver +{ +private: + unsigned char ** LCD; + cDriverConfig * config; + cDriverConfig * oldConfig; + + int CheckSetup(); + +public: + cDriverSimLCD(cDriverConfig * config); + virtual ~cDriverSimLCD(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/t6963c.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/t6963c.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,678 @@ +/* + * GraphLCD driver library + * + * t6963c.c - T6963C driver class + * + * low level routines based on lcdproc 0.5 driver, (c) 2001 Manuel Stahl + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003, 2004 Andreas Regel + */ + +#include + +#include "common.h" +#include "config.h" +#include "port.h" +#include "t6963c.h" + + +namespace GLCD +{ + +// T6963 commands +const unsigned char kSetCursorPointer = 0x21; +const unsigned char kSetOffsetRegister = 0x22; +const unsigned char kSetAddressPointer = 0x24; + +const unsigned char kSetTextHomeAddress = 0x40; +const unsigned char kSetTextArea = 0x41; +const unsigned char kSetGraphicHomeAddress = 0x42; +const unsigned char kSetGraphicArea = 0x43; + +const unsigned char kSetMode = 0x80; +const unsigned char kSetDisplayMode = 0x90; +const unsigned char kSetCursorPattern = 0xA0; + +const unsigned char kDataWriteInc = 0xC0; +const unsigned char kDataReadInc = 0xC1; +const unsigned char kDataWriteDec = 0xC2; +const unsigned char kDataReadDec = 0xC3; +const unsigned char kDataWrite = 0xC4; +const unsigned char kDataRead = 0xC5; + +const unsigned char kAutoWrite = 0xB0; +const unsigned char kAutoRead = 0xB1; +const unsigned char kAutoReset = 0xB2; + + +// T6963 Parameters +const unsigned char kModeOr = 0x00; +const unsigned char kModeXor = 0x01; +const unsigned char kModeAnd = 0x03; +const unsigned char kModeTextAttribute = 0x04; +const unsigned char kModeInternalCG = 0x00; +const unsigned char kModeExternalCG = 0x08; + +const unsigned char kTextAttributeNormal = 0x00; +const unsigned char kTextAttributeInverse = 0x05; +const unsigned char kTextAttributeNoDisplay = 0x03; +const unsigned char kTextAttributeBlink = 0x08; + +const unsigned char kDisplayModeBlink = 0x01; +const unsigned char kDisplayModeCursor = 0x02; +const unsigned char kDisplayModeText = 0x04; +const unsigned char kDisplayModeGraphic = 0x08; + +const unsigned short kGraphicBase = 0x0000; +const unsigned short kTextBase = 0x1500; +const unsigned short kCGRAMBase = 0x1800; + + +// T6963 Wirings +static const std::string kWiringStandard = "Standard"; +static const std::string kWiringWindows = "Windows"; +static const std::string kWiringSerial = "Serial"; + +const unsigned char kStandardWRHI = 0x00; // 01 / nSTRB +const unsigned char kStandardWRLO = 0x01; // +const unsigned char kStandardRDHI = 0x00; // 17 / nSELECT +const unsigned char kStandardRDLO = 0x08; // +const unsigned char kStandardCEHI = 0x00; // 14 / nLINEFEED +const unsigned char kStandardCELO = 0x02; // +const unsigned char kStandardCDHI = 0x04; // 16 / INIT +const unsigned char kStandardCDLO = 0x00; // + +const unsigned char kWindowsWRHI = 0x04; // 16 / INIT +const unsigned char kWindowsWRLO = 0x00; // +const unsigned char kWindowsRDHI = 0x00; // 14 / nLINEFEED +const unsigned char kWindowsRDLO = 0x02; // +const unsigned char kWindowsCEHI = 0x00; // 01 / nSTRB +const unsigned char kWindowsCELO = 0x01; // +const unsigned char kWindowsCDHI = 0x00; // 17 / nSELECT +const unsigned char kWindowsCDLO = 0x08; // + +const unsigned char kSerialWRHI = 0x01; // 01 / nSTRB +const unsigned char kSerialWRLO = 0x00; // +const unsigned char kSerialRDHI = 0x08; // 17 / nSELECT +const unsigned char kSerialRDLO = 0x00; // +const unsigned char kSerialCEHI = 0x02; // 14 / nLINEFEED +const unsigned char kSerialCELO = 0x00; // +const unsigned char kSerialCDHI = 0x00; // 16 / INIT +const unsigned char kSerialCDLO = 0x04; // + + +cDriverT6963C::cDriverT6963C(cDriverConfig * config) +: config(config) +{ + oldConfig = new cDriverConfig(*config); + + port = new cParallelPort(); + + //width = config->width; + //height = config->height; + refreshCounter = 0; + displayMode = 0; + bidirectLPT = 1; + autoWrite = false; + serial = 0; +} + +cDriverT6963C::~cDriverT6963C() +{ + delete port; + delete oldConfig; +} + +int cDriverT6963C::Init() +{ + int x; + + width = config->width; + if (width <= 0) + width = 240; + height = config->height; + if (height <= 0) + height = 128; + + // default values + FS = 6; + WRHI = kStandardWRHI; + WRLO = kStandardWRLO; + RDHI = kStandardRDHI; + RDLO = kStandardRDLO; + CEHI = kStandardCEHI; + CELO = kStandardCELO; + CDHI = kStandardCDHI; + CDLO = kStandardCDLO; + useAutoMode = true; + useStatusCheck = true; + + for (unsigned int i = 0; i < config->options.size(); i++) + { + if (config->options[i].name == "FontSelect") + { + int fontSelect = atoi(config->options[i].value.c_str()); + if (fontSelect == 6) + FS = 6; + else if (fontSelect == 8) + FS = 8; + else + syslog(LOG_ERR, "%s error: font select %d not supported, using default (%d)!\n", + config->name.c_str(), fontSelect, FS); + } + else if (config->options[i].name == "Wiring") + { + if (config->options[i].value == kWiringStandard) + { + WRHI = kStandardWRHI; + WRLO = kStandardWRLO; + RDHI = kStandardRDHI; + RDLO = kStandardRDLO; + CEHI = kStandardCEHI; + CELO = kStandardCELO; + CDHI = kStandardCDHI; + CDLO = kStandardCDLO; + } + else if (config->options[i].value == kWiringWindows) + { + WRHI = kWindowsWRHI; + WRLO = kWindowsWRLO; + RDHI = kWindowsRDHI; + RDLO = kWindowsRDLO; + CEHI = kWindowsCEHI; + CELO = kWindowsCELO; + CDHI = kWindowsCDHI; + CDLO = kWindowsCDLO; + } + else if (config->options[i].value == kWiringSerial) + { + serial = 1; + WRHI = kSerialWRHI; + WRLO = kSerialWRLO; + RDHI = kSerialRDHI; + RDLO = kSerialRDLO; + CEHI = kSerialCEHI; + CELO = kSerialCELO; + CDHI = kSerialCDHI; + CDLO = kSerialCDLO; + } + else + syslog(LOG_ERR, "%s error: wiring %s not supported, using default (Standard)!\n", + config->name.c_str(), config->options[i].value.c_str()); + } + else if (config->options[i].name == "AutoMode") + { + if (config->options[i].value == "yes") + useAutoMode = true; + else if (config->options[i].value == "no") + useAutoMode = false; + else + syslog(LOG_ERR, "%s error: unknown auto mode setting %s, using default (%s)!\n", + config->name.c_str(), config->options[i].value.c_str(), useAutoMode ? "yes" : "no"); + } + else if (config->options[i].name == "StatusCheck") + { + if (config->options[i].value == "yes") + useStatusCheck = true; + else if (config->options[i].value == "no") + useStatusCheck = false; + else + syslog(LOG_ERR, "%s error: unknown status check setting %s, using default (%s)!\n", + config->name.c_str(), config->options[i].value.c_str(), useStatusCheck ? "yes" : "no"); + } + } + + // setup lcd array (wanted state) + newLCD = new unsigned char*[(width + (FS - 1)) / FS]; + if (newLCD) + { + for (x = 0; x < (width + (FS - 1)) / FS; x++) + { + newLCD[x] = new unsigned char[height]; + memset(newLCD[x], 0, height); + } + } + // setup lcd array (current state) + oldLCD = new unsigned char*[(width + (FS - 1)) / FS]; + if (oldLCD) + { + for (x = 0; x < (width + (FS - 1)) / FS; x++) + { + oldLCD[x] = new unsigned char[height]; + memset(oldLCD[x], 0, height); + } + } + + if (config->device == "") + { + // use DirectIO + if (port->Open(config->port) != 0) + return -1; + uSleep(10); + } + else + { + // use ppdev + if (port->Open(config->device.c_str()) != 0) + return -1; + } + + // disable chip + // disable reading from LCD + // disable writing to LCD + // command/status mode + T6963CSetControl(WRHI | CEHI | CDHI | RDHI); + port->SetDirection(kForward); // make 8-bit parallel port an output port + + // Test ECP mode + if (bidirectLPT == 1) + { + syslog(LOG_DEBUG, "%s: Testing ECP mode...\n", config->name.c_str()); + int i = 0; + int ecp_input; + port->SetDirection(kReverse); + for (int i = 0; i < 100; i++) + { + T6963CSetControl(WRHI | CEHI | CDHI | RDHI); // wr, ce, cd, rd + T6963CSetControl(WRHI | CELO | CDHI | RDLO); + T6963CSetControl(WRHI | CELO | CDHI | RDLO); + T6963CSetControl(WRHI | CELO | CDHI | RDLO); + ecp_input = port->ReadData(); + T6963CSetControl(WRHI | CEHI | CDHI | RDHI); + if ((ecp_input & 0x03) == 0x03) + break; + } + port->SetDirection(kForward); + if (i >= 100) + { + syslog(LOG_DEBUG, "%s: ECP mode not working! -> is now disabled\n", config->name.c_str()); + bidirectLPT = 0; + } + else + syslog(LOG_DEBUG, "%s: working!\n", config->name.c_str()); + } + + T6963CCommandWord(kSetGraphicHomeAddress, kGraphicBase); + if (width % FS == 0) + T6963CCommandWord(kSetGraphicArea, width / FS); + else + T6963CCommandWord(kSetGraphicArea, width / FS + 1); + + T6963CCommand(kSetMode | kModeOr | kModeInternalCG); + + T6963CDisplayMode(kDisplayModeText, false); + T6963CDisplayMode(kDisplayModeGraphic, true); + T6963CDisplayMode(kDisplayModeCursor, false); + T6963CDisplayMode(kDisplayModeBlink, false); + + port->Release(); + + *oldConfig = *config; + + // clear display + Clear(); + + syslog(LOG_INFO, "%s: T6963 initialized.\n", config->name.c_str()); + return 0; +} + +int cDriverT6963C::DeInit() +{ + int x; + // free lcd array (wanted state) + if (newLCD) + { + for (x = 0; x < (width + (FS - 1)) / FS; x++) + { + delete[] newLCD[x]; + } + delete[] newLCD; + } + // free lcd array (current state) + if (oldLCD) + { + for (x = 0; x < (width + (FS - 1)) / FS; x++) + { + delete[] oldLCD[x]; + } + delete[] oldLCD; + } + + if (port->Close() != 0) + return -1; + return 0; +} + +int cDriverT6963C::CheckSetup() +{ + if (config->device != oldConfig->device || + config->port != oldConfig->port || + config->width != oldConfig->width || + config->height != oldConfig->height) + { + DeInit(); + Init(); + return 0; + } + + if (config->upsideDown != oldConfig->upsideDown || + config->invert != oldConfig->invert) + { + oldConfig->upsideDown = config->upsideDown; + oldConfig->invert = config->invert; + return 1; + } + return 0; +} + +void cDriverT6963C::Clear() +{ + for (int x = 0; x < (width + (FS - 1)) / FS; x++) + memset(newLCD[x], 0, height); +} + +void cDriverT6963C::Set8Pixels(int x, int y, unsigned char data) +{ + if (x >= width || y >= height) + return; + + if (FS == 6) + { + unsigned char data1 = 0; + unsigned char data2 = 0; + unsigned char data3 = 0; + + if (!config->upsideDown) + { + // normal orientation + x = x - (x % 8); + data1 = data >> (2 + (x % 6)); + if (x % 6 == 5) + { + data2 = data >> 1; + data3 = data << 5; + } + else + data2 = data << (4 - (x % 6)); + + newLCD[x / 6][y] |= data1; + if (x / 6 + 1 < (width + 5) / 6) + newLCD[x / 6 + 1][y] |= data2; + if (x / 6 + 2 < (width + 5) / 6) + if (x % 6 == 5) + newLCD[x / 6 + 2][y] |= data3; + } + else + { + // upside down orientation + x = width - 1 - x; + y = height - 1 - y; + x = x - (x % 8); + data = ReverseBits(data); + + data1 = data >> (2 + (x % 6)); + if (x % 6 == 5) + { + data2 = data >> 1; + data3 = data << 5; + } + else + data2 = data << (4 - (x % 6)); + + newLCD[x / 6][y] |= data1; + if (x / 6 + 1 < (width + 5) / 6) + newLCD[x / 6 + 1][y] |= data2; + if (x / 6 + 2 < (width + 5) / 6) + if (x % 6 == 5) + newLCD[x / 6 + 2][y] |= data3; + } + } + else + { + if (!config->upsideDown) + { + newLCD[x / 8][y] |= data; + } + else + { + x = width - 1 - x; + y = height - 1 - y; + newLCD[x / 8][y] |= ReverseBits(data); + } + } +} + +void cDriverT6963C::Refresh(bool refreshAll) +{ + int x,y; + int addr = 0; + + if (CheckSetup() == 1) + refreshAll = true; + + if (config->refreshDisplay > 0) + { + refreshCounter = (refreshCounter + 1) % config->refreshDisplay; + if (!refreshAll && !refreshCounter) + refreshAll = true; + } + + port->Claim(); + if (refreshAll) + { + // draw all + T6963CCommandWord(kSetAddressPointer, kGraphicBase); + if (useAutoMode) + { + T6963CCommand(kAutoWrite); + autoWrite = true; + } + for (y = 0; y < height; y++) + { + for (x = 0; x < (width + (FS - 1)) / FS; x++) + { + if (autoWrite) + T6963CData((newLCD[x][y]) ^ (config->invert ? 0xff : 0x00)); + else + T6963CCommandByte(kDataWriteInc, (newLCD[x][y]) ^ (config->invert ? 0xff : 0x00)); + oldLCD[x][y] = newLCD[x][y]; + } + } + if (autoWrite) + { + T6963CCommand(kAutoReset); + autoWrite = false; + } + // and reset RefreshCounter + refreshCounter = 0; + } + else + { + // draw only the changed bytes + + bool cs = false; + for (y = 0; y < height; y++) + { + for (x = 0; x < (width + (FS - 1)) / FS; x++) + { + if (oldLCD[x][y] != newLCD[x][y]) + { + if (!cs) + { + if (width % FS == 0) + addr = (y * (width / FS)) + x; + else + addr = (y * (width / FS + 1)) + x; + T6963CCommandWord(kSetAddressPointer, kGraphicBase + addr); + if (useAutoMode) + { + T6963CCommand(kAutoWrite); + autoWrite = true; + } + cs = true; + } + if (autoWrite) + T6963CData((newLCD[x][y]) ^ (config->invert ? 0xff : 0x00)); + else + T6963CCommandByte(kDataWriteInc, (newLCD[x][y]) ^ (config->invert ? 0xff : 0x00)); + oldLCD[x][y] = newLCD[x][y]; + } + else + { + if (autoWrite) + { + T6963CCommand(kAutoReset); + autoWrite = false; + } + cs = false; + } + } + } + if (autoWrite) + { + T6963CCommand(kAutoReset); + autoWrite = false; + } + } + port->Release(); +} + +void cDriverT6963C::T6963CSetControl(unsigned char flags) +{ + unsigned char status = port->ReadControl(); + status &= 0xF0; // mask 4 bits + status |= flags; // add new flags + port->WriteControl(status); +} + +void cDriverT6963C::T6963CDSPReady() +{ + int input = 0; + + port->SetDirection(kReverse); + if (bidirectLPT == 1) + { + for (int i = 0; i < 10; i++) + { + T6963CSetControl(WRHI | CEHI | CDHI | RDHI); + T6963CSetControl(WRHI | CELO | CDHI | RDLO); + input = port->ReadData(); + T6963CSetControl(WRHI | CEHI | CDHI | RDHI); + if (!autoWrite && (input & 3) == 3) + break; + if (autoWrite && (input & 8) == 8) + break; + } + } + else + { + T6963CSetControl(WRHI | CEHI | CDHI | RDHI); + T6963CSetControl(WRHI | CELO | CDHI | RDLO); + T6963CSetControl(WRHI | CEHI | CDHI | RDHI); + } + port->SetDirection(kForward); +} + +void cDriverT6963C::T6963CData(unsigned char data) +{ + if (serial) + { + T6963CSetControl(WRLO | CEHI | CDLO | RDLO); + for (int i = 128; i; i>>=1) + { + if (data & i) + { + T6963CSetControl(WRLO | CEHI | CDHI | RDLO); + T6963CSetControl(WRHI | CEHI | CDHI | RDLO); + } + else + { + T6963CSetControl(WRLO | CEHI | CDLO | RDLO); + T6963CSetControl(WRHI | CEHI | CDLO | RDLO); + } + } + T6963CSetControl(WRLO | CEHI | CDLO | RDLO); // CD down (data) + T6963CSetControl(WRLO | CELO | CDLO | RDLO); // CE down + T6963CSetControl(WRLO | CEHI | CDLO | RDLO); // CE up + } + else + { + if (useStatusCheck) + T6963CDSPReady(); + T6963CSetControl(WRHI | CEHI | CDLO | RDHI); // CD down (data) + T6963CSetControl(WRLO | CELO | CDLO | RDHI); // CE & WR down + port->WriteData(data); + T6963CSetControl(WRHI | CEHI | CDLO | RDHI); // CE & WR up again + T6963CSetControl(WRHI | CEHI | CDHI | RDHI); // CD up again + } +} + +void cDriverT6963C::T6963CCommand(unsigned char cmd) +{ + if (serial) + { + syslog(LOG_DEBUG, "Serial cmd out: "); + T6963CSetControl(WRLO | CEHI | CDLO | RDLO); + for (int i = 128; i; i>>=1) + { + if (cmd & i) + { + T6963CSetControl(WRLO | CEHI | CDHI | RDLO); + T6963CSetControl(WRHI | CEHI | CDHI | RDLO); + } + else + { + T6963CSetControl(WRLO | CEHI | CDLO | RDLO); + T6963CSetControl(WRHI | CEHI | CDLO | RDLO); + } + } + T6963CSetControl(WRLO | CEHI | CDHI | RDLO); // CD up (command) + T6963CSetControl(WRLO | CELO | CDHI | RDLO); // CE down + T6963CSetControl(WRLO | CEHI | CDHI | RDLO); // CE up + T6963CSetControl(WRLO | CEHI | CDLO | RDLO); // CD down + } + else + { + if (useStatusCheck) + T6963CDSPReady(); + T6963CSetControl(WRHI | CEHI | CDHI | RDHI); // CD up (command) + T6963CSetControl(WRLO | CELO | CDHI | RDHI); // CE & WR down + port->WriteData(cmd); + T6963CSetControl(WRHI | CEHI | CDHI | RDHI); // CE & WR up again + T6963CSetControl(WRHI | CEHI | CDLO | RDHI); // CD down again + } +} + +void cDriverT6963C::T6963CCommandByte(unsigned char cmd, unsigned char data) +{ + T6963CData(data); + T6963CCommand(cmd); +} + +void cDriverT6963C::T6963CCommand2Bytes(unsigned char cmd, unsigned char data1, unsigned char data2) +{ + T6963CData(data1); + T6963CData(data2); + T6963CCommand(cmd); +} + +void cDriverT6963C::T6963CCommandWord(unsigned char cmd, unsigned short data) +{ + T6963CData(data % 256); + T6963CData(data >> 8); + T6963CCommand(cmd); +} + +void cDriverT6963C::T6963CDisplayMode(unsigned char mode, bool enable) +{ + if (enable) + displayMode |= mode; + else + displayMode &= ~mode; + T6963CCommand(kSetDisplayMode | displayMode); +} + +} diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcddrivers/t6963c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcddrivers/t6963c.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,76 @@ +/* + * GraphLCD driver library + * + * t6963c.h - T6963C driver class + * + * low level routines based on lcdproc 0.5 driver, (c) 2001 Manuel Stahl + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2003, 2004 Andreas Regel + */ + +#ifndef _GLCDDRIVERS_T6963C_H_ +#define _GLCDDRIVERS_T6963C_H_ + +#include "driver.h" + +namespace GLCD +{ + +class cDriverConfig; +class cParallelPort; + +class cDriverT6963C : public cDriver +{ +private: + cParallelPort * port; + unsigned char ** newLCD; // wanted state + unsigned char ** oldLCD; // current state + cDriverConfig * config; + cDriverConfig * oldConfig; + int refreshCounter; + int bidirectLPT; + int displayMode; + bool useAutoMode; + bool useStatusCheck; + + int serial; + int FS; + int WRHI; + int WRLO; + int RDHI; + int RDLO; + int CEHI; + int CELO; + int CDHI; + int CDLO; + bool autoWrite; + + void T6963CSetControl(unsigned char flags); + void T6963CDSPReady(); + void T6963CData(unsigned char data); + void T6963CCommand(unsigned char cmd); + void T6963CCommandByte(unsigned char cmd, unsigned char data); + void T6963CCommand2Bytes(unsigned char cmd, unsigned char data1, unsigned char data2); + void T6963CCommandWord(unsigned char cmd, unsigned short data); + void T6963CDisplayMode(unsigned char mode, bool enable); + + int CheckSetup(); + +public: + cDriverT6963C(cDriverConfig * config); + virtual ~cDriverT6963C(); + + virtual int Init(); + virtual int DeInit(); + + virtual void Clear(); + virtual void Set8Pixels(int x, int y, unsigned char data); + virtual void Refresh(bool refreshAll = false); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/Makefile Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,68 @@ +# +# Makefile for the GraphLCD graphics library +# + +-include ../Make.config + +CXXFLAGS += -fPIC + +VERMAJOR = 2 +VERMINOR = 0 +VERMICRO = 0 + +BASENAME = libglcdgraphics.so + +LIBNAME = $(BASENAME).$(VERMAJOR).$(VERMINOR).$(VERMICRO) + +OBJS = bitmap.o common.o font.o glcd.o image.o imagefile.o pbm.o + +HEADERS = bitmap.h font.h glcd.h image.h imagefile.h pbm.h + +### 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) + +ifdef HAVE_FREETYPE2 + ifneq ($(shell which freetype-config),) + INCLUDES += $(shell freetype-config --cflags) + LIBS += $(shell freetype-config --libs) + else + INCLUDES += -I/usr/include/freetype -I/usr/local/include/freetype + LIBS += -lfreetype + endif + DEFINES += -DHAVE_FREETYPE2 +endif### Targets: + +all: $(LIBNAME) + +$(LIBNAME): $(OBJS) + $(CXX) $(CXXFLAGS) -shared $(OBJS) $(LIBS) -Wl,-soname="$(BASENAME).$(VERMAJOR)" -o $@ + ln -sf $(LIBNAME) $(BASENAME) + +install: all + install -d $(LIBDIR) + install -m 755 $(LIBNAME) $(LIBDIR)/ + install -d $(INCDIR)/glcdgraphics + install -m 644 $(HEADERS) $(INCDIR)/glcdgraphics/ + ( cd $(LIBDIR); ln -sf $(LIBNAME) $(BASENAME).$(VERMAJOR); ln -sf $(LIBNAME) $(BASENAME) ) + +uninstall: + rm -f $(LIBDIR)/$(BASENAME) + rm -f $(LIBDIR)/$(BASENAME).$(VERMAJOR) + rm -f $(LIBDIR)/$(LIBNAME) + (for i in $(HEADERS); do rm -f $(INCDIR)/glcdgraphics/$$i; done) + rmdir $(INCDIR)/glcdgraphics + +clean: + rm -f $(OBJS) $(DEPFILE) $(LIBNAME) $(BASENAME) *~ + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/bitmap.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/bitmap.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,807 @@ +/* + * GraphLCD graphics library + * + * bitmap.c - cBitmap class + * + * based on graphlcd plugin 0.1.1 for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include +#include +#include + +#include "bitmap.h" +#include "common.h" +#include "font.h" + + +namespace GLCD +{ + +const unsigned char bitmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; +const unsigned char bitmaskl[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; +const unsigned char bitmaskr[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01}; + +cBitmap::cBitmap(int width, int height, unsigned char * data) +: width(width), + height(height), + bitmap(NULL) +{ + // lines are byte aligned + lineSize = (width + 7) / 8; + + bitmap = new unsigned char[lineSize * height]; + if (data) + memcpy(bitmap, data, lineSize * height); +} + +cBitmap::cBitmap(const cBitmap & b) +{ + width = b.width; + height = b.height; + lineSize = b.lineSize; + bitmap = new unsigned char[lineSize * height]; + if (b.bitmap) + memcpy(bitmap, b.bitmap, lineSize * height); +} + +cBitmap::~cBitmap() +{ + delete[] bitmap; +} + +void cBitmap::Clear() +{ + memset(bitmap, 0, lineSize * height); +} + +void cBitmap::Invert() +{ + int i; + + for (i = 0; i < lineSize * height; i++) + { + bitmap[i] ^= 0xFF; + } +} + +void cBitmap::DrawPixel(int x, int y, eColor color) +{ + if (x < 0 || x > width - 1) + return; + if (y < 0 || y > height - 1) + return; + + unsigned char c = 0x80 >> (x % 8); + if (color == clrBlack) + bitmap[lineSize * y + x / 8] |= c; + else + bitmap[lineSize * y + x / 8] &= ~c; +} + +void cBitmap::Draw8Pixels(int x, int y, unsigned char pixels, eColor color) +{ + if (x < 0 || x > width - 1) + return; + if (y < 0 || y > height - 1) + return; + + if (color == clrBlack) + bitmap[lineSize * y + x / 8] |= pixels; + else + bitmap[lineSize * y + x / 8] &= ~pixels; +} + +void cBitmap::DrawLine(int x1, int y1, int x2, int y2, eColor color) +{ + int d, sx, sy, dx, dy; + unsigned int ax, ay; + + dx = x2 - x1; + ax = abs(dx) << 1; + if (dx < 0) + sx = -1; + else + sx = 1; + + dy = y2 - y1; + ay = abs(dy) << 1; + if (dy < 0) + sy = -1; + else + sy = 1; + + DrawPixel(x1, y1, color); + if (ax > ay) + { + d = ay - (ax >> 1); + while (x1 != x2) + { + if (d >= 0) + { + y1 += sy; + d -= ax; + } + x1 += sx; + d += ay; + DrawPixel(x1, y1, color); + } + } + else + { + d = ax - (ay >> 1); + while (y1 != y2) + { + if (d >= 0) + { + x1 += sx; + d -= ay; + } + y1 += sy; + d += ax; + DrawPixel(x1, y1, color); + } + } +} + +void cBitmap::DrawHLine(int x1, int y, int x2, eColor color) +{ + sort(x1,x2); + + if (x1 / 8 == x2 / 8) + { + // start and end in the same byte + Draw8Pixels(x1, y, bitmaskr[x1 % 8] & bitmaskl[x2 % 8], color); + } + else + { + // start and end in different bytes + Draw8Pixels(x1, y, bitmaskr[x1 % 8], color); + x1 = ((x1 + 8) / 8) * 8; + while (x1 < (x2 / 8) * 8) + { + Draw8Pixels(x1, y, 0xff, color); + x1 += 8; + } + Draw8Pixels(x2, y, bitmaskl[x2 % 8], color); + } +} + +void cBitmap::DrawVLine(int x, int y1, int y2, eColor color) +{ + int y; + + sort(y1,y2); + + for (y = y1; y <= y2; y++) + DrawPixel(x, y, color); +} + +void cBitmap::DrawRectangle(int x1, int y1, int x2, int y2, eColor color, bool filled) +{ + int y; + + sort(x1,x2); + sort(y1,y2); + + if (!filled) + { + DrawHLine(x1, y1, x2, color); + DrawVLine(x1, y1, y2, color); + DrawHLine(x1, y2, x2, color); + DrawVLine(x2, y1, y2, color); + } + else + { + for (y = y1; y <= y2; y++) + { + DrawHLine(x1, y, x2, color); + } + } +} + +void cBitmap::DrawRoundRectangle(int x1, int y1, int x2, int y2, eColor color, bool filled, int type) +{ + sort(x1,x2); + sort(y1,y2); + + if (type > (x2 - x1) / 2) + type = (x2 - x1) / 2; + if (type > (y2 - y1) / 2) + type = (y2 - y1) / 2; + + if (filled) + { + DrawHLine(x1 + type, y1, x2 - type, color); + for (int y = y1 + 1; y < y1 + type; y++) + DrawHLine(x1 + 1, y, x2 - 1, color); + for (int y = y1 + type; y <= y2 - type; y++) + DrawHLine(x1, y, x2, color); + for (int y = y2 - type + 1; y < y2; y++) + DrawHLine(x1 + 1, y, x2 - 1, color); + DrawHLine(x1 + type, y2, x2 - type, color); + if (type == 4) + { + // round the ugly fat box... + DrawPixel(x1 + 1, y1 + 1, color == clrWhite ? clrBlack : clrWhite); + DrawPixel(x1 + 1, y2 - 1, color == clrWhite ? clrBlack : clrWhite); + DrawPixel(x2 - 1, y1 + 1, color == clrWhite ? clrBlack : clrWhite); + DrawPixel(x2 - 1, y2 - 1, color == clrWhite ? clrBlack : clrWhite); + } + } + else + { + DrawHLine(x1 + type, y1, x2 - type, color); + DrawVLine(x1, y1 + type, y2 - type, color); + DrawVLine(x2, y1 + type, y2 - type, color); + DrawHLine(x1 + type, y2, x2 - type, color); + if (type > 1) + { + DrawHLine(x1 + 1, y1 + 1, x1 + type - 1, color); + DrawHLine(x2 - type + 1, y1 + 1, x2 - 1, color); + DrawHLine(x1 + 1, y2 - 1, x1 + type - 1, color); + DrawHLine(x2 - type + 1, y2 - 1, x2 - 1, color); + DrawVLine(x1 + 1, y1 + 1, y1 + type - 1, color); + DrawVLine(x1 + 1, y2 - 1, y2 - type + 1, color); + DrawVLine(x2 - 1, y1 + 1, y1 + type - 1, color); + DrawVLine(x2 - 1, y2 - 1, y2 - type + 1, color); + } + } +} + +void cBitmap::DrawEllipse(int x1, int y1, int x2, int y2, eColor color, bool filled, int quadrants) +{ + // Algorithm based on http://homepage.smc.edu/kennedy_john/BELIPSE.PDF + int rx = x2 - x1; + int ry = y2 - y1; + int cx = (x1 + x2) / 2; + int cy = (y1 + y2) / 2; + switch (abs(quadrants)) + { + case 0: rx /= 2; ry /= 2; break; + case 1: cx = x1; cy = y2; break; + case 2: cx = x2; cy = y2; break; + case 3: cx = x2; cy = y1; break; + case 4: cx = x1; cy = y1; break; + case 5: cx = x1; ry /= 2; break; + case 6: cy = y2; rx /= 2; break; + case 7: cx = x2; ry /= 2; break; + case 8: cy = y1; rx /= 2; break; + } + int TwoASquare = 2 * rx * rx; + int TwoBSquare = 2 * ry * ry; + int x = rx; + int y = 0; + int XChange = ry * ry * (1 - 2 * rx); + int YChange = rx * rx; + int EllipseError = 0; + int StoppingX = TwoBSquare * rx; + int StoppingY = 0; + while (StoppingX >= StoppingY) + { + if (filled) + { + switch (quadrants) + { + case 5: DrawRectangle(cx, cy + y, cx + x, cy + y, color, filled); // no break + case 1: DrawRectangle(cx, cy - y, cx + x, cy - y, color, filled); break; + case 7: DrawRectangle(cx - x, cy + y, cx, cy + y, color, filled); // no break + case 2: DrawRectangle(cx - x, cy - y, cx, cy - y, color, filled); break; + case 3: DrawRectangle(cx - x, cy + y, cx, cy + y, color, filled); break; + case 4: DrawRectangle(cx, cy + y, cx + x, cy + y, color, filled); break; + case 0: + case 6: DrawRectangle(cx - x, cy - y, cx + x, cy - y, color, filled); if (quadrants == 6) break; + case 8: DrawRectangle(cx - x, cy + y, cx + x, cy + y, color, filled); break; + case -1: DrawRectangle(cx + x, cy - y, x2, cy - y, color, filled); break; + case -2: DrawRectangle(x1, cy - y, cx - x, cy - y, color, filled); break; + case -3: DrawRectangle(x1, cy + y, cx - x, cy + y, color, filled); break; + case -4: DrawRectangle(cx + x, cy + y, x2, cy + y, color, filled); break; + } + } + else + { + switch (quadrants) + { + case 5: DrawPixel(cx + x, cy + y, color); // no break + case -1: + case 1: DrawPixel(cx + x, cy - y, color); break; + case 7: DrawPixel(cx - x, cy + y, color); // no break + case -2: + case 2: DrawPixel(cx - x, cy - y, color); break; + case -3: + case 3: DrawPixel(cx - x, cy + y, color); break; + case -4: + case 4: DrawPixel(cx + x, cy + y, color); break; + case 0: + case 6: DrawPixel(cx - x, cy - y, color); DrawPixel(cx + x, cy - y, color); if (quadrants == 6) break; + case 8: DrawPixel(cx - x, cy + y, color); DrawPixel(cx + x, cy + y, color); break; + } + } + y++; + StoppingY += TwoASquare; + EllipseError += YChange; + YChange += TwoASquare; + if (2 * EllipseError + XChange > 0) + { + x--; + StoppingX -= TwoBSquare; + EllipseError += XChange; + XChange += TwoBSquare; + } + } + x = 0; + y = ry; + XChange = ry * ry; + YChange = rx * rx * (1 - 2 * ry); + EllipseError = 0; + StoppingX = 0; + StoppingY = TwoASquare * ry; + while (StoppingX <= StoppingY) + { + if (filled) + { + switch (quadrants) + { + case 5: DrawRectangle(cx, cy + y, cx + x, cy + y, color, filled); // no break + case 1: DrawRectangle(cx, cy - y, cx + x, cy - y, color, filled); break; + case 7: DrawRectangle(cx - x, cy + y, cx, cy + y, color, filled); // no break + case 2: DrawRectangle(cx - x, cy - y, cx, cy - y, color, filled); break; + case 3: DrawRectangle(cx - x, cy + y, cx, cy + y, color, filled); break; + case 4: DrawRectangle(cx, cy + y, cx + x, cy + y, color, filled); break; + case 0: + case 6: DrawRectangle(cx - x, cy - y, cx + x, cy - y, color, filled); if (quadrants == 6) break; + case 8: DrawRectangle(cx - x, cy + y, cx + x, cy + y, color, filled); break; + case -1: DrawRectangle(cx + x, cy - y, x2, cy - y, color, filled); break; + case -2: DrawRectangle(x1, cy - y, cx - x, cy - y, color, filled); break; + case -3: DrawRectangle(x1, cy + y, cx - x, cy + y, color, filled); break; + case -4: DrawRectangle(cx + x, cy + y, x2, cy + y, color, filled); break; + } + } + else + { + switch (quadrants) + { + case 5: DrawPixel(cx + x, cy + y, color); // no break + case -1: + case 1: DrawPixel(cx + x, cy - y, color); break; + case 7: DrawPixel(cx - x, cy + y, color); // no break + case -2: + case 2: DrawPixel(cx - x, cy - y, color); break; + case -3: + case 3: DrawPixel(cx - x, cy + y, color); break; + case -4: + case 4: DrawPixel(cx + x, cy + y, color); break; + case 0: + case 6: DrawPixel(cx - x, cy - y, color); DrawPixel(cx + x, cy - y, color); if (quadrants == 6) break; + case 8: DrawPixel(cx - x, cy + y, color); DrawPixel(cx + x, cy + y, color); break; + } + } + x++; + StoppingX += TwoBSquare; + EllipseError += XChange; + XChange += TwoBSquare; + if (2 * EllipseError + YChange > 0) + { + y--; + StoppingY -= TwoASquare; + EllipseError += YChange; + YChange += TwoASquare; + } + } +} + +void cBitmap::DrawSlope(int x1, int y1, int x2, int y2, eColor color, int type) +{ + bool upper = type & 0x01; + bool falling = type & 0x02; + bool vertical = type & 0x04; + if (vertical) + { + for (int y = y1; y <= y2; y++) + { + double c = cos((y - y1) * M_PI / (y2 - y1 + 1)); + if (falling) + c = -c; + int x = int((x2 - x1 + 1) * c / 2); + if (upper && !falling || !upper && falling) + DrawRectangle(x1, y, (x1 + x2) / 2 + x, y, color, true); + else + DrawRectangle((x1 + x2) / 2 + x, y, x2, y, color, true); + } + } + else + { + for (int x = x1; x <= x2; x++) + { + double c = cos((x - x1) * M_PI / (x2 - x1 + 1)); + if (falling) + c = -c; + int y = int((y2 - y1 + 1) * c / 2); + if (upper) + DrawRectangle(x, y1, x, (y1 + y2) / 2 + y, color, true); + else + DrawRectangle(x, (y1 + y2) / 2 + y, x, y2, color, true); + } + } +} + +void cBitmap::DrawBitmap(int x, int y, const cBitmap & bitmap, eColor color) +{ + unsigned char cl = 0; + int xt, yt; + const unsigned char * data = bitmap.Data(); + unsigned short temp; + int h, w; + + w = bitmap.Width(); + h = bitmap.Height(); + + if (data) + { + if (!(x % 8)) + { + // Bitmap is byte alligned (0,8,16,...) + for (yt = 0; yt < h; yt++) + { + for (xt = 0; xt < (w / 8); xt++) + { + cl = *data; + Draw8Pixels(x + (xt * 8), y + yt, cl, color); + data++; + } + if (w % 8) + { + cl = *data; + Draw8Pixels(x + ((w / 8) * 8), y + yt, cl & bitmaskl[w % 8 - 1], color); + data++; + } + } + } + else + { + // Bitmap is not byte alligned + for (yt = 0; yt < h; yt++) + { + temp = 0; + for (xt = 0; xt < (w + (x % 8)) / 8; xt++) + { + cl = *(data + yt * ((w + 7) / 8) + xt); + temp = temp | ((unsigned short) cl << (8 - (x % 8))); + cl = (temp & 0xff00) >> 8; + if (!xt) + { + // first byte + Draw8Pixels(x - (x % 8) + (xt * 8), y + yt, cl & bitmaskr[x % 8], color); + } + else + { + // not the first byte + Draw8Pixels(x - (x % 8) + (xt * 8), y + yt, cl, color); + } + temp <<= 8; + } + if ((w + (x % 8) + 7) / 8 != (w + (x % 8)) / 8) + { + // print the rest + cl = *(data + (yt + 1) * ((w + 7) / 8) - 1); + temp = temp | ((unsigned short) cl << (8 - (x % 8))); + cl = (temp & 0xff00) >> 8; + Draw8Pixels(x - (x % 8) + (((w + (x % 8)) / 8) * 8), y + yt, cl & bitmaskl[(w + x) % 8 - 1], color); + } + } + } + } +} + +int cBitmap::DrawText(int x, int y, int xmax, const std::string & text, const cFont * font, + eColor color, bool proportional, int skipPixels) +{ + int xt; + int yt; + int i; + char c; + int start; + + clip(x, 0, width - 1); + clip(y, 0, height - 1); + + xt = x; + yt = y; + start = 0; + + if (text.length() > 0) + { + if (skipPixels > 0) + { + if (!proportional) + { + if (skipPixels >= (int) text.length() * font->TotalWidth()) + start = text.length(); + else + while (skipPixels > font->TotalWidth()) + { + skipPixels -= font->TotalWidth(); + start++; + } + } + else + { + if (skipPixels >= font->Width(text)) + start = text.length(); + else + while (skipPixels > font->Width(text[start])) + { + skipPixels -= font->Width(text[start]); + skipPixels -= font->SpaceBetween(); + start++; + } + } + } + for (i = start; i < (int) text.length(); i++) + { + c = text[i]; + if (xt > xmax) + { + i = text.length(); + } + else + { + if (!proportional) + { + if (skipPixels > 0) + { + DrawCharacter(xt, yt, xmax, c, font, color, skipPixels); + xt += font->TotalWidth() - skipPixels; + skipPixels = 0; + } + else + { + DrawCharacter(xt, yt, xmax, c, font, color); + xt += font->TotalWidth(); + } + } + else + { + if (skipPixels > 0) + { + xt += DrawCharacter(xt, yt, xmax, c, font, color, skipPixels); + skipPixels = 0; + } + else + { + xt += DrawCharacter(xt, yt, xmax, c, font, color); + } + if (xt <= xmax) + { + xt += font->SpaceBetween(); + } + } + } + } + } + return xt; +} + +int cBitmap::DrawCharacter(int x, int y, int xmax, char c, const cFont * font, + eColor color, int skipPixels) +{ + const cBitmap * charBitmap; + + clip(x, 0, width - 1); + clip(y, 0, height - 1); + + charBitmap = font->GetCharacter(c); + if (charBitmap) + { + cBitmap * drawBitmap = charBitmap->SubBitmap(skipPixels, 0, xmax - x + skipPixels, charBitmap->Height() - 1); + if (drawBitmap) + DrawBitmap(x, y, *drawBitmap, color); + delete drawBitmap; + return charBitmap->Width() - skipPixels; + } + return 0; +} + +unsigned char cBitmap::GetPixel(int x, int y) const +{ + unsigned char value; + + value = bitmap[y * lineSize + x / 8]; + value = (value >> (7 - (x % 8))) & 1; + return value; +} + +cBitmap * cBitmap::SubBitmap(int x1, int y1, int x2, int y2) const +{ + int w, h; + int xt, yt; + cBitmap * bmp; + unsigned char cl; + unsigned char * data; + unsigned short temp; + + sort(x1,x2); + sort(y1,y2); + if (x1 < 0 || x1 > width - 1) + return NULL; + if (y1 < 0 || y1 > height - 1) + return NULL; + clip(x2, 0, width - 1); + clip(y2, 0, height - 1); + + w = x2 - x1 + 1; + h = y2 - y1 + 1; + bmp = new cBitmap(w, h); + if (!bmp || !bmp->Data()) + return NULL; + bmp->Clear(); + if (x1 % 8 == 0) + { + // Bitmap is byte alligned (0,8,16,...) + for (yt = 0; yt < h; yt++) + { + data = &bitmap[(y1 + yt) * lineSize + x1 / 8]; + for (xt = 0; xt < (w / 8) * 8; xt += 8) + { + cl = *data; + bmp->Draw8Pixels(xt, yt, cl, clrBlack); + data++; + } + if (w % 8 != 0) + { + cl = *data; + bmp->Draw8Pixels(xt, yt, cl & bitmaskl[w % 8 - 1], clrBlack); + } + } + } + else + { + // Bitmap is not byte alligned + for (yt = 0; yt < h; yt++) + { + temp = 0; + data = &bitmap[(y1 + yt) * lineSize + x1 / 8]; + for (xt = 0; xt <= ((w / 8)) * 8; xt += 8) + { + cl = *data; + temp = temp | ((unsigned short) cl << (x1 % 8)); + cl = (temp & 0xff00) >> 8; + if (xt > 0) + { + bmp->Draw8Pixels(xt - 8, yt, cl, clrBlack); + } + temp <<= 8; + data++; + } + if (w % 8 != 0) + { + // print the rest + if (8 - (x1 % 8) < w % 8) + { + cl = *data; + temp = temp | ((unsigned short) cl << (x1 % 8)); + } + cl = (temp & 0xff00) >> 8; + bmp->Draw8Pixels(xt - 8, yt, cl & bitmaskl[(w % 8) - 1], clrBlack); + } + } + } + return bmp; +} + +bool cBitmap::LoadPBM(const std::string & fileName) +{ + FILE * pbmFile; + char str[32]; + int i; + int ch; + int w; + int h; + + pbmFile = fopen(fileName.c_str(), "rb"); + if (!pbmFile) + return false; + + i = 0; + while ((ch = getc(pbmFile)) != EOF && i < 31) + { + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') + break; + str[i] = ch; + i++; + } + if (ch == EOF) + { + fclose(pbmFile); + return false; + } + str[i] = 0; + if (strcmp(str, "P4") != 0) + return false; + + while ((ch = getc(pbmFile)) == '#') + { + while ((ch = getc(pbmFile)) != EOF) + { + if (ch == '\n' || ch == '\r') + break; + } + } + if (ch == EOF) + { + fclose(pbmFile); + return false; + } + i = 0; + str[i] = ch; + i += 1; + while ((ch = getc(pbmFile)) != EOF && i < 31) + { + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') + break; + str[i] = ch; + i++; + } + if (ch == EOF) + { + fclose(pbmFile); + return false; + } + str[i] = 0; + w = atoi(str); + + i = 0; + while ((ch = getc(pbmFile)) != EOF && i < 31) + { + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') + break; + str[i] = ch; + i++; + } + if (ch == EOF) + { + fclose(pbmFile); + return false; + } + str[i] = 0; + h = atoi(str); + + delete[] bitmap; + width = w; + height = h; + // lines are byte aligned + lineSize = (width + 7) / 8; + bitmap = new unsigned char[lineSize * height]; + fread(bitmap, lineSize * height, 1, pbmFile); + fclose(pbmFile); + + return true; +} + +void cBitmap::SavePBM(const std::string & fileName) +{ + int i; + char str[32]; + FILE * fp; + + fp = fopen(fileName.c_str(), "wb"); + if (fp) + { + sprintf(str, "P4\n%d %d\n", width, height); + fwrite(str, strlen(str), 1, fp); + for (i = 0; i < lineSize * height; i++) + { + fwrite(&bitmap[i], 1, 1, fp); + } + fclose(fp); + } +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/bitmap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/bitmap.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,75 @@ +/* + * GraphLCD graphics library + * + * bitmap.h - cBitmap class + * + * based on graphlcd plugin 0.1.1 for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDGRAPHICS_BITMAP_H_ +#define _GLCDGRAPHICS_BITMAP_H_ + +#include + +namespace GLCD +{ + +enum eColor +{ + clrBlack, + clrWhite +}; + +class cFont; + +class cBitmap +{ +protected: + int width; + int height; + int lineSize; + unsigned char * bitmap; + +public: + cBitmap(int width, int height, unsigned char * data = NULL); + cBitmap(const cBitmap & b); + ~cBitmap(); + + int Width() const { return width; } + int Height() const { return height; } + int LineSize() const { return lineSize; } + const unsigned char * Data() const { return bitmap; } + + void Clear(); + void Invert(); + void DrawPixel(int x, int y, eColor color); + void Draw8Pixels(int x, int y, unsigned char pixels, eColor color); + void DrawLine(int x1, int y1, int x2, int y2, eColor color); + void DrawHLine(int x1, int y, int x2, eColor color); + void DrawVLine(int x, int y1, int y2, eColor color); + void DrawRectangle(int x1, int y1, int x2, int y2, eColor color, bool filled); + void DrawRoundRectangle(int x1, int y1, int x2, int y2, eColor color, bool filled, int size); + void DrawEllipse(int x1, int y1, int x2, int y2, eColor color, bool filled, int quadrants); + void DrawSlope(int x1, int y1, int x2, int y2, eColor color, int type); + void DrawBitmap(int x, int y, const cBitmap & bitmap, eColor color); + int DrawText(int x, int y, int xmax, const std::string & text, const cFont * font, + eColor color = clrBlack, bool proportional = true, int skipPixels = 0); + int DrawCharacter(int x, int y, int xmax, char c, const cFont * font, + eColor color = clrBlack, int skipPixels = 0); + + cBitmap * SubBitmap(int x1, int y1, int x2, int y2) const; + unsigned char GetPixel(int x, int y) const; + + bool LoadPBM(const std::string & fileName); + void SavePBM(const std::string & fileName); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/common.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/common.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,60 @@ +/* + * GraphLCD graphics library + * + * common.c - various functions + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include + +#include "common.h" + + +namespace GLCD +{ + +void clip(int & value, int min, int max) +{ + if (value < min) + value = min; + if (value > max) + value = max; +} + +void sort(int & value1, int & value2) +{ + if (value2 < value1) + { + int tmp; + tmp = value2; + value2 = value1; + value1 = tmp; + } +} + +std::string trim(const std::string & s) +{ + std::string::size_type start, end; + + start = 0; + while (start < s.length()) + { + if (!isspace(s[start])) + break; + start++; + } + end = s.length() - 1; + while (end >= 0) + { + if (!isspace(s[end])) + break; + end--; + } + return s.substr(start, end - start + 1); +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/common.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/common.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,26 @@ +/* + * GraphLCD graphics library + * + * common.h - various functions + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDGRAPHICS_COMMON_H_ +#define _GLCDGRAPHICS_COMMON_H_ + +#include + +namespace GLCD +{ + +void clip(int & value, int min, int max); +void sort(int & value1, int & value2); +std::string trim(const std::string & s); + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/font.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/font.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,581 @@ +/* + * GraphLCD graphics library + * + * font.c - font handling + * + * based on graphlcd plugin 0.1.1 for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "font.h" + +#ifdef HAVE_FREETYPE2 +#include +#include FT_FREETYPE_H +#include +#endif + +namespace GLCD +{ + +static const char * kFontFileSign = "FNT3"; +static const uint32_t kFontHeaderSize = 16; +static const uint32_t kCharHeaderSize = 4; + +//#pragma pack(1) +//struct tFontHeader +//{ +// char sign[4]; // = FONTFILE_SIGN +// unsigned short height; // total height of the font +// unsigned short ascent; // ascender of the font +// unsigned short line; // line height +// unsigned short reserved; +// unsigned short space; // space between characters of a string +// unsigned short count; // number of chars in this file +//}; +// +//struct tCharHeader +//{ +// unsigned short character; +// unsigned short width; +//}; +//#pragma pack() + +cFont::cFont() +{ + Init(); +} + +cFont::~cFont() +{ + Unload(); +} + +bool cFont::LoadFNT(const std::string & fileName) +{ + // cleanup if we already had a loaded font + Unload(); + + FILE * fontFile; + int i; + uint8_t buffer[10000]; + uint16_t fontHeight; + uint16_t numChars; + int maxWidth = 0; + + fontFile = fopen(fileName.c_str(), "rb"); + if (!fontFile) + return false; + + fread(buffer, kFontHeaderSize, 1, fontFile); + if (buffer[0] != kFontFileSign[0] || + buffer[1] != kFontFileSign[1] || + buffer[2] != kFontFileSign[2] || + buffer[3] != kFontFileSign[3]) + { + fclose(fontFile); + return false; + } + + fontHeight = buffer[4] | (buffer[5] << 8); + totalAscent = buffer[6] | (buffer[7] << 8); + lineHeight = buffer[8] | (buffer[9] << 8); + spaceBetween = buffer[12] | (buffer[13] << 8); + numChars = buffer[14] | (buffer[15] << 8); + for (i = 0; i < numChars; i++) + { + uint8_t chdr[kCharHeaderSize]; + uint16_t charWidth; + uint16_t character; + fread(chdr, kCharHeaderSize, 1, fontFile); + character = chdr[0] | (chdr[1] << 8); + charWidth = chdr[2] | (chdr[3] << 8); + fread(buffer, fontHeight * ((charWidth + 7) / 8), 1, fontFile); + if (characters[character]) + delete characters[character]; + characters[character] = new cBitmap(charWidth, fontHeight, buffer); + if (characters[character]->Width() > maxWidth) + maxWidth = characters[character]->Width(); + } + fclose(fontFile); + + totalWidth = maxWidth; + totalHeight = fontHeight; + + return true; +} + +bool cFont::SaveFNT(const std::string & fileName) const +{ + FILE * fontFile; + uint8_t fhdr[kFontHeaderSize]; + uint8_t chdr[kCharHeaderSize]; + uint16_t numChars; + int i; + + fontFile = fopen(fileName.c_str(),"w+b"); + if (!fontFile) + { + syslog(LOG_ERR, "cFont::SaveFNT(): Cannot open file: %s for writing\n",fileName.c_str()); + return false; + } + + numChars = 0; + for (i = 0; i < 256; i++) + { + if (characters[i]) + { + numChars++; + } + } + + memcpy(fhdr, kFontFileSign, 4); + fhdr[4] = (uint8_t) totalHeight; + fhdr[5] = (uint8_t) (totalHeight >> 8); + fhdr[6] = (uint8_t) totalAscent; + fhdr[7] = (uint8_t) (totalAscent >> 8); + fhdr[8] = (uint8_t) lineHeight; + fhdr[9] = (uint8_t) (lineHeight >> 8); + fhdr[10] = 0; + fhdr[11] = 0; + fhdr[12] = (uint8_t) spaceBetween; + fhdr[13] = (uint8_t) (spaceBetween >> 8); + fhdr[14] = (uint8_t) numChars; + fhdr[15] = (uint8_t) (numChars >> 8); + + // write font file header + fwrite(fhdr, kFontHeaderSize, 1, fontFile); + + for (i = 0; i < 256; i++) + { + if (characters[i]) + { + chdr[0] = (uint8_t) i; + chdr[1] = (uint8_t) (i >> 8); + chdr[2] = (uint8_t) characters[i]->Width(); + chdr[3] = (uint8_t) (characters[i]->Width() >> 8); + fwrite(chdr, kCharHeaderSize, 1, fontFile); + fwrite(characters[i]->Data(), totalHeight * characters[i]->LineSize(), 1, fontFile); + } + } + + fclose(fontFile); + + syslog(LOG_DEBUG, "cFont::SaveFNT(): Font file '%s' written successfully\n", fileName.c_str()); + + return true; +} + +bool cFont::LoadFT2(const std::string & fileName, const std::string & encoding, + int size, bool dingBats) +{ + // cleanup if we already had a loaded font + Unload(); +#ifdef HAVE_FREETYPE2 + if (access(fileName.c_str(), F_OK) != 0) + { + syslog(LOG_ERR, "cFont::LoadFT2: Font file (%s) does not exist!!", fileName.c_str()); + return false; + } + // file exists + FT_Library library; + FT_Face face; + FT_GlyphSlot slot; + + int error = FT_Init_FreeType(&library); + if (error) + { + syslog(LOG_ERR, "cFont::LoadFT2: Could not init freetype library"); + return false; + } + error = FT_New_Face(library, fileName.c_str(), 0, &face); + // everything ok? + if (error == FT_Err_Unknown_File_Format) + { + syslog(LOG_ERR, "cFont::LoadFT2: Font file (%s) could be opened and read, but it appears that its font format is unsupported", fileName.c_str()); + error = FT_Done_Face(face); + syslog(LOG_ERR, "cFont::LoadFT2: FT_Done_Face(..) returned (%d)", error); + error = FT_Done_FreeType(library); + syslog(LOG_ERR, "cFont::LoadFT2: FT_Done_FreeType(..) returned (%d)", error); + return false; + } + else if (error) + { + syslog(LOG_ERR, "cFont::LoadFT2: Font file (%s) could not be opened or read, or simply it is broken,\n error code was %x", fileName.c_str(), error); + error = FT_Done_Face(face); + syslog(LOG_ERR, "cFont::LoadFT2: FT_Done_Face(..) returned (%d)", error); + error = FT_Done_FreeType(library); + syslog(LOG_ERR, "cFont::LoadFT2: FT_Done_FreeType(..) returned (%d)", error); + return false; + } + + // set slot + slot = face->glyph; + + // set Size + FT_Set_Char_Size(face, 0, size * 64, 0, 0); + + wchar_t utf_buff[256]; + if (dingBats) + { +/* + FT_CharMap charmap = 0; + for (int n = 0; n < face->num_charmaps; n++) + { + if (face->charmaps[n]->platform_id == 3 && + face->charmaps[n]->encoding_id == 0) + { + charmap = face->charmaps[n]; + //break; + } + } + if (charmap) + syslog(LOG_ERR, "cFont::LoadFT2: platform_id: %d, encoding_id: %d", charmap->platform_id, charmap->encoding_id); + error = FT_Set_Charmap(_face, charmap); + if (error) + { + syslog(LOG_ERR, "cFont::LoadFT2: FT_Select_Charmap encoding not supported: %d", charmap->encoding_id); + } +*/ + } + else + { + iconv_t cd; + if ((cd = iconv_open("WCHAR_T", encoding.c_str())) == (iconv_t) -1) + { + syslog(LOG_ERR, "cFont::LoadFT2: Iconv encoding not supported: %s", encoding.c_str()); + error = FT_Done_Face(face); + syslog(LOG_ERR, "cFont::LoadFT2: FT_Done_Face(..) returned (%d)", error); + error = FT_Done_FreeType(library); + syslog(LOG_ERR, "cFont::LoadFT2: FT_Done_FreeType(..) returned (%d)", error); + return false; + } + for (int c = 0; c < 256; c++) + { + char char_buff = c; + wchar_t wchar_buff; + char * in_buff,* out_buff; + size_t in_len, out_len, count; + + in_len = 1; + out_len = 4; + in_buff = (char *) &char_buff; + out_buff = (char *) &wchar_buff; + count = iconv(cd, &in_buff, &in_len, &out_buff, &out_len); + if ((size_t) -1 == count) + { + utf_buff[c] = 0; + } + utf_buff[c] = wchar_buff; + } + iconv_close(cd); + } + + // get some global parameters + totalHeight = (face->size->metrics.ascender >> 6) - (face->size->metrics.descender >> 6); + totalWidth = face->size->metrics.max_advance >> 6; + totalAscent = face->size->metrics.ascender >> 6; + lineHeight = face->size->metrics.height >> 6; + spaceBetween = 0; +#if 0 + syslog(LOG_DEBUG, "cFont::LoadFT2: totalHeight = %d", totalHeight); + syslog(LOG_DEBUG, "cFont::LoadFT2: totalWidth = %d", totalWidth); + syslog(LOG_DEBUG, "cFont::LoadFT2: totalAscent = %d", totalAscent); + syslog(LOG_DEBUG, "cFont::LoadFT2: lineHeight = %d", lineHeight); + syslog(LOG_DEBUG, "cFont::LoadFT2: spaceBetween = %d", spaceBetween); +#endif + // render glyphs for ASCII codes 0 to 255 in our bitmap class + FT_UInt glyph_index; + int num_char; + + for (num_char = 0; num_char < 256; num_char++) + { + if (dingBats) + { + //Get FT char index & load the char + error = FT_Load_Char(face, num_char, FT_LOAD_DEFAULT); + } + else + { + //Get FT char index + glyph_index = FT_Get_Char_Index(face, utf_buff[num_char]); + //Load the char + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); + } + if (error) + { + syslog(LOG_ERR, "cFont::LoadFT2: ERROR when calling FT_Load_Glyph: %x", error); + } + + // convert to a mono bitmap + error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); + if (error) + { + syslog(LOG_ERR, "cFont::LoadFT2: ERROR when calling FT_Render_Glyph: %x", error); + } + + // now, fill our pixel data + cBitmap * charBitmap = new cBitmap(face->glyph->advance.x >> 6, totalHeight); + charBitmap->Clear(); + unsigned char * bufPtr = face->glyph->bitmap.buffer; + unsigned char pixel; + for (int y = 0; y < face->glyph->bitmap.rows; y++) + { + for (int x = 0; x < face->glyph->bitmap.width; x++) + { + pixel = (bufPtr[x / 8] >> (7 - x % 8)) & 1; + if (pixel) + charBitmap->DrawPixel((face->glyph->metrics.horiBearingX >> 6) + x, + (face->size->metrics.ascender >> 6) - (face->glyph->metrics.horiBearingY >> 6) + y, + GLCD::clrBlack); + } + bufPtr += face->glyph->bitmap.pitch; + } + SetCharacter((char) num_char, charBitmap); + } + error = FT_Done_Face(face); + if (error) + { + syslog(LOG_ERR, "cFont::LoadFT2: FT_Done_Face(..) returned (%d)", error); + } + error = FT_Done_FreeType(library); + if (error) + { + syslog(LOG_ERR, "cFont::LoadFT2: FT_Done_FreeType(..) returned (%d)", error); + } + return true; +#else + syslog(LOG_ERR, "cFont::LoadFT2: glcdgraphics was compiled without FreeType2 support!!!"); + return false; +#endif +} + +int cFont::Width(char ch) const +{ + if (characters[(unsigned char) ch]) + return characters[(unsigned char) ch]->Width(); + else + return 0; +} + +int cFont::Width(const std::string & str) const +{ + unsigned int i; + int sum = 0; + + for (i = 0; i < str.length(); i++) + { + sum += Width(str[i]); + } + if (str.length() > 1) + { + sum += spaceBetween * (str.length() - 1); + } + return sum; +} + +int cFont::Width(const std::string & str, unsigned int len) const +{ + unsigned int i; + int sum = 0; + + for (i = 0; i < str.length() && i < len; i++) + { + sum += Width(str[i]); + } + if (std::min(str.length(), (size_t) len) > 1) + { + sum += spaceBetween * (std::min(str.length(), (size_t) len) - 1); + } + return sum; +} + +int cFont::Height(char ch) const +{ + if (characters[(unsigned char) ch]) + return characters[(unsigned char) ch]->Height(); + else + return 0; +} + +int cFont::Height(const std::string & str) const +{ + unsigned int i; + int sum = 0; + + for (i = 0; i < str.length(); i++) + sum = std::max(sum, Height(str[i])); + return sum; +} + +int cFont::Height(const std::string & str, unsigned int len) const +{ + unsigned int i; + int sum = 0; + + for (i = 0; i < str.length() && i < len; i++) + sum = std::max(sum, Height(str[i])); + return sum; +} + +const cBitmap * cFont::GetCharacter(char ch) const +{ + return characters[(unsigned char) ch]; +} + +void cFont::SetCharacter(char ch, cBitmap * bitmapChar) +{ + // adjust maxwidth if necessary + if (totalWidth < bitmapChar->Width()) + totalWidth = bitmapChar->Width(); + + // delete if already allocated + if (characters[(unsigned char) ch]) + delete characters[(unsigned char) ch]; + + // store new character + characters[(unsigned char) ch] = bitmapChar; +} + +void cFont::Init() +{ + totalWidth = 0; + totalHeight = 0; + totalAscent = 0; + spaceBetween = 0; + lineHeight = 0; + for (int i = 0; i < 256; i++) + { + characters[i] = NULL; + } +} + +void cFont::Unload() +{ + // cleanup + for (int i = 0; i < 256; i++) + { + if (characters[i]) + { + delete characters[i]; + } + } + // re-init + Init(); +} + +void cFont::WrapText(int Width, int Height, std::string & Text, + std::vector & Lines, int * ActualWidth) const +{ + int maxLines; + int lineCount; + int textWidth; + std::string::size_type start; + std::string::size_type pos; + std::string::size_type posLast; + + Lines.clear(); + maxLines = 2000; + if (Height > 0) + { + maxLines = Height / LineHeight(); + if (maxLines == 0) + maxLines = 1; + } + lineCount = 0; + + pos = 0; + start = 0; + posLast = 0; + textWidth = 0; + while (pos < Text.length() && (Height == 0 || lineCount < maxLines)) + { + if (Text[pos] == '\n') + { + Lines.push_back(trim(Text.substr(start, pos - start))); + start = pos + 1; + posLast = pos + 1; + textWidth = 0; + lineCount++; + } + else if (textWidth > Width && (lineCount + 1) < maxLines) + { + if (posLast > start) + { + Lines.push_back(trim(Text.substr(start, posLast - start))); + start = posLast + 1; + posLast = start; + textWidth = this->Width(Text.substr(start, pos - start + 1)) + spaceBetween; + } + else + { + Lines.push_back(trim(Text.substr(start, pos - start))); + start = pos + 1; + posLast = start; + textWidth = this->Width(Text[pos]) + spaceBetween; + } + lineCount++; + } + else if (Text[pos] == ' ') + { + posLast = pos; + textWidth += this->Width(Text[pos]) + spaceBetween; + } + else + { + textWidth += this->Width(Text[pos]) + spaceBetween; + } + pos++; + } + + if (Height == 0 || lineCount < maxLines) + { + if (textWidth > Width && (lineCount + 1) < maxLines) + { + if (posLast > start) + { + Lines.push_back(trim(Text.substr(start, posLast - start))); + start = posLast + 1; + posLast = start; + textWidth = this->Width(Text.substr(start, pos - start + 1)) + spaceBetween; + } + else + { + Lines.push_back(trim(Text.substr(start, pos - start))); + start = pos + 1; + posLast = start; + textWidth = this->Width(Text[pos]) + spaceBetween; + } + lineCount++; + } + if (pos > start) + { + Lines.push_back(trim(Text.substr(start))); + lineCount++; + } + textWidth = 0; + for (int i = 0; i < lineCount; i++) + textWidth = std::max(textWidth, this->Width(Lines[i])); + textWidth = std::min(textWidth, Width); + } + else + textWidth = Width; + if (ActualWidth) + *ActualWidth = textWidth; +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/font.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/font.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,75 @@ +/* + * GraphLCD graphics library + * + * font.h - font handling + * + * based on graphlcd plugin 0.1.1 for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDGRAPHICS_FONT_H_ +#define _GLCDGRAPHICS_FONT_H_ + +#include +#include + +#include "bitmap.h" + +namespace GLCD +{ + +class cFont +{ +private: + int totalWidth; + int totalHeight; + int totalAscent; + int spaceBetween; + int lineHeight; + + cBitmap * characters[256]; +protected: + void Init(); + void Unload(); +public: + cFont(); + ~cFont(); + + bool LoadFNT(const std::string & fileName); + bool SaveFNT(const std::string & fileName) const; + bool LoadFT2(const std::string & fileName, const std::string & encoding, + int size, bool dingBats = false); + int TotalWidth() const { return totalWidth; }; + int TotalHeight() const { return totalHeight; }; + int TotalAscent() const { return totalAscent; }; + int SpaceBetween() const { return spaceBetween; }; + int LineHeight() const { return lineHeight; }; + + void SetTotalWidth(int width) { totalWidth = width; }; + void SetTotalHeight(int height) { totalHeight = height; }; + void SetTotalAscent(int ascent) { totalAscent = ascent; }; + void SetSpaceBetween(int width) { spaceBetween = width; }; + void SetLineHeight(int height) { lineHeight = height; }; + + int Width(char ch) const; + int Width(const std::string & str) const; + int Width(const std::string & str, unsigned int len) const; + int Height(char ch) const; + int Height(const std::string & str) const; + int Height(const std::string & str, unsigned int len) const; + + const cBitmap * GetCharacter(char ch) const; + void SetCharacter(char ch, cBitmap * bitmapChar); + + void WrapText(int Width, int Height, std::string & Text, + std::vector & Lines, int * TextWidth = NULL) const; +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/glcd.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/glcd.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,277 @@ +/* + * GraphLCD graphics library + * + * glcd.c - GLCD file loading and saving + * + * based on graphlcd plugin 0.1.1 for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include +#include + +#include + +#include "bitmap.h" +#include "glcd.h" +#include "image.h" + + +namespace GLCD +{ + +using namespace std; + +const char * kGLCDFileSign = "GLC"; + +/* +#pragma pack(1) +struct tGLCDHeader +{ + char sign[3]; // = "GLC" + char format; // D - single image, A - animation + uint16_t width; // width in pixels + uint16_t height; // height in pixels + // only for animations + uint16_t count; // number of pictures + uint32_t delay; // delay in ms +}; +#pragma pack() +*/ + +cGLCDFile::cGLCDFile() +{ +} + +cGLCDFile::~cGLCDFile() +{ +} + +bool cGLCDFile::Load(cImage & image, const string & fileName) +{ + FILE * fp; + long fileSize; + char sign[4]; + uint8_t buf[6]; + uint16_t width; + uint16_t height; + uint16_t count; + uint32_t delay; + + fp = fopen(fileName.c_str(), "rb"); + if (!fp) + { + syslog(LOG_ERR, "glcdgraphics: open %s failed (cGLCDFile::Load).", fileName.c_str()); + return false; + } + + // get len of file + if (fseek(fp, 0, SEEK_END) != 0) + { + fclose(fp); + return false; + } + fileSize = ftell(fp); + + // rewind and get Header + if (fseek(fp, 0, SEEK_SET) != 0) + { + fclose(fp); + return false; + } + + // read header sign + if (fread(sign, 4, 1, fp) != 1) + { + fclose(fp); + return false; + } + + // check header sign + if (strncmp(sign, kGLCDFileSign, 3) != 0) + { + syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong header (cGLCDFile::Load).", fileName.c_str()); + fclose(fp); + return false; + } + + // read width and height + if (fread(buf, 4, 1, fp) != 1) + { + fclose(fp); + return false; + } + + width = (buf[1] << 8) | buf[0]; + height = (buf[3] << 8) | buf[2]; + if (width == 0 || height == 0) + { + syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong header (cGLCDFile::Load).", fileName.c_str()); + fclose(fp); + return false; + } + + if (sign[3] == 'D') + { + count = 1; + delay = 10; + // check file length + if (fileSize != (long) (height * ((width + 7) / 8) + 8)) + { + syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong size (cGLCDFile::Load).", fileName.c_str()); + fclose(fp); + return false; + } + } + else if (sign[3] == 'A') + { + // read count and delay + if (fread(buf, 6, 1, fp) != 1) + { + syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong header (cGLCDFile::Load).", fileName.c_str()); + fclose(fp); + return false; + } + count = (buf[1] << 8) | buf[0]; + delay = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2]; + // check file length + if (count == 0 || + fileSize != (long) (count * (height * ((width + 7) / 8)) + 14)) + { + syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong size (cGLCDFile::Load).", fileName.c_str()); + fclose(fp); + return false; + } + // Set minimal limit for next image + if (delay < 10) + delay = 10; + } + else + { + syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong header (cGLCDFile::Load).", fileName.c_str()); + fclose(fp); + return false; + } + + image.Clear(); + image.SetWidth(width); + image.SetHeight(height); + image.SetDelay(delay); + unsigned char * bmpdata = new unsigned char[height * ((width + 7) / 8)]; + if (bmpdata) + { + for (unsigned int n = 0; n < count; n++) + { + if (fread(bmpdata, height * ((width + 7) / 8), 1, fp) != 1) + { + delete[] bmpdata; + fclose(fp); + image.Clear(); + return false; + } + image.AddBitmap(new cBitmap(width, height, bmpdata)); + } + delete[] bmpdata; + } + else + { + syslog(LOG_ERR, "glcdgraphics: malloc failed (cGLCDFile::Load)."); + fclose(fp); + image.Clear(); + return false; + } + fclose(fp); + + syslog(LOG_DEBUG, "glcdgraphics: image %s loaded.", fileName.c_str()); + return true; +} + +bool cGLCDFile::Save(cImage & image, const string & fileName) +{ + FILE * fp; + uint8_t buf[14]; + uint16_t width; + uint16_t height; + uint16_t count; + uint32_t delay; + const cBitmap * bitmap; + int i; + + if (image.Count() == 0) + return false; + + fp = fopen(fileName.c_str(), "wb"); + if (!fp) + { + syslog(LOG_ERR, "glcdgraphics: open %s failed (cGLCDFile::Save).", fileName.c_str()); + return false; + } + + memcpy(buf, kGLCDFileSign, 3); + count = image.Count(); + delay = image.Delay(); + if (count == 1) + { + buf[3] = 'D'; + } + else + { + buf[3] = 'A'; + } + bitmap = image.GetBitmap(0); + width = bitmap->Width(); + height = bitmap->Height(); + buf[4] = (uint8_t) width; + buf[5] = (uint8_t) (width >> 8); + buf[6] = (uint8_t) height; + buf[7] = (uint8_t) (height >> 8); + if (count == 1) + { + if (fwrite(buf, 8, 1, fp) != 1) + { + fclose(fp); + return false; + } + } + else + { + buf[8] = (uint8_t) count; + buf[9] = (uint8_t) (count >> 8); + buf[10] = (uint8_t) delay; + buf[11] = (uint8_t) (delay >> 8); + buf[12] = (uint8_t) (delay >> 16); + buf[13] = (uint8_t) (delay >> 24); + if (fwrite(buf, 14, 1, fp) != 1) + { + fclose(fp); + return false; + } + } + for (i = 0; i < count; i++) + { + bitmap = image.GetBitmap(i); + if (bitmap) + { + if (bitmap->Width() == width && bitmap->Height() == height) + { + if (fwrite(bitmap->Data(), height * ((width + 7) / 8), 1, fp) != 1) + { + fclose(fp); + return false; + } + } + } + } + fclose(fp); + + syslog(LOG_DEBUG, "glcdgraphics: image %s saved.", fileName.c_str()); + return true; +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/glcd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/glcd.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,36 @@ +/* + * GraphLCD graphics library + * + * glcd.h - GLCD file loading and saving + * + * based on graphlcd plugin 0.1.1 for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDGRAPHICS_GLCD_H_ +#define _GLCDGRAPHICS_GLCD_H_ + +#include "imagefile.h" + +namespace GLCD +{ + +class cImage; + +class cGLCDFile : public cImageFile +{ +public: + cGLCDFile(); + virtual ~cGLCDFile(); + virtual bool Load(cImage & image, const std::string & fileName); + virtual bool Save(cImage & image, const std::string & fileName); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/image.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/image.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,67 @@ +/* + * GraphLCD graphics library + * + * image.c - image and animation handling + * + * based on graphlcd plugin 0.1.1 for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include "bitmap.h" +#include "image.h" + + +namespace GLCD +{ + +using namespace std; + +cImage::cImage() +: width(0), + height(0), + delay(0), + curBitmap(0), + lastChange(0) +{ +} + +cImage::~cImage() +{ + Clear(); +} + +cBitmap * cImage::GetBitmap() const +{ + if (curBitmap < bitmaps.size()) + return bitmaps[curBitmap]; + return NULL; +} + +cBitmap * cImage::GetBitmap(unsigned int nr) const +{ + if (nr < bitmaps.size()) + return bitmaps[nr]; + return NULL; +} + +void cImage::Clear() +{ + vector ::iterator it; + for (it = bitmaps.begin(); it != bitmaps.end(); it++) + { + delete *it; + } + bitmaps.clear(); + width = 0; + height = 0; + delay = 0; + curBitmap = 0; + lastChange = 0; +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/image.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/image.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,58 @@ +/* + * GraphLCD graphics library + * + * image.h - image and animation handling + * + * based on graphlcd plugin 0.1.1 for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#ifndef _GLCDGRAPHICS_IMAGE_H_ +#define _GLCDGRAPHICS_IMAGE_H_ + +#include + +#include + +namespace GLCD +{ + +class cBitmap; + +class cImage +{ +private: + unsigned int width; + unsigned int height; + unsigned int delay; + unsigned int curBitmap; + uint64_t lastChange; + std::vector bitmaps; +public: + cImage(); + ~cImage(); + + unsigned int Width() const { return width; } + unsigned int Height() const { return height; } + unsigned int Count() const { return bitmaps.size(); } + unsigned int Delay() const { return delay; } + uint64_t LastChange() const { return lastChange; } + void First(uint64_t t) { lastChange = t; curBitmap = 0; } + bool Next(uint64_t t) { lastChange = t; curBitmap++; return curBitmap < bitmaps.size(); } + void SetWidth(unsigned int Width) { width = Width; } + void SetHeight(unsigned int Height) { height = Height; } + void SetDelay(unsigned int d) { delay = d; } + cBitmap * GetBitmap(unsigned int nr) const; + cBitmap * GetBitmap() const; + void AddBitmap(cBitmap * Bitmap) { bitmaps.push_back(Bitmap); } + void Clear(); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/imagefile.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/imagefile.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,35 @@ +/* + * GraphLCD graphics library + * + * imagefile.h - base class for file loading and saving + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2006 Andreas Regel + */ + +#include "image.h" +#include "imagefile.h" + +namespace GLCD +{ + +cImageFile::cImageFile(void) +{ +} +cImageFile::~cImageFile(void) +{ +} + +bool cImageFile::Load(cImage & image, const std::string & fileName) +{ + return false; +} + +bool cImageFile::Save(cImage & image, const std::string & fileName) +{ + return false; +} + +} // end of namespace diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/imagefile.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/imagefile.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,33 @@ +/* + * GraphLCD graphics library + * + * imagefile.h - base class for file loading and saving + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2006 Andreas Regel + */ + +#ifndef _GLCDGRAPHICS_IMAGEFILE_H_ +#define _GLCDGRAPHICS_IMAGEFILE_H_ + +#include + +namespace GLCD +{ + +class cImage; + +class cImageFile +{ +public: + cImageFile(); + virtual ~cImageFile(); + virtual bool Load(cImage & image, const std::string & fileName); + virtual bool Save(cImage & image, const std::string & fileName); +}; + +} // end of namespace + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/pbm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/pbm.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,187 @@ +/* + * GraphLCD graphics library + * + * pbm.c - PBM file loading and saving + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2006 Andreas Regel + */ + +#include +#include +#include + +#include + +#include "bitmap.h" +#include "pbm.h" +#include "image.h" + + +namespace GLCD +{ + +cPBMFile::cPBMFile() +{ +} + +cPBMFile::~cPBMFile() +{ +} + +bool cPBMFile::Load(cImage & image, const std::string & fileName) +{ + FILE * pbmFile; + char str[32]; + int i; + int ch; + int w; + int h; + + pbmFile = fopen(fileName.c_str(), "rb"); + if (!pbmFile) + return false; + + i = 0; + while ((ch = getc(pbmFile)) != EOF && i < 31) + { + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') + break; + str[i] = ch; + i++; + } + if (ch == EOF) + { + fclose(pbmFile); + return false; + } + str[i] = 0; + if (strcmp(str, "P4") != 0) + return false; + + while ((ch = getc(pbmFile)) == '#') + { + while ((ch = getc(pbmFile)) != EOF) + { + if (ch == '\n' || ch == '\r') + break; + } + } + if (ch == EOF) + { + fclose(pbmFile); + return false; + } + i = 0; + str[i] = ch; + i += 1; + while ((ch = getc(pbmFile)) != EOF && i < 31) + { + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') + break; + str[i] = ch; + i++; + } + if (ch == EOF) + { + fclose(pbmFile); + return false; + } + str[i] = 0; + w = atoi(str); + + i = 0; + while ((ch = getc(pbmFile)) != EOF && i < 31) + { + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') + break; + str[i] = ch; + i++; + } + if (ch == EOF) + { + fclose(pbmFile); + return false; + } + str[i] = 0; + h = atoi(str); + + image.Clear(); + image.SetWidth(w); + image.SetHeight(h); + image.SetDelay(100); + unsigned char * bmpdata = new unsigned char[h * ((w + 7) / 8)]; + if (bmpdata) + { + if (fread(bmpdata, h * ((w + 7) / 8), 1, pbmFile) != 1) + { + delete[] bmpdata; + fclose(pbmFile); + image.Clear(); + return false; + } + image.AddBitmap(new cBitmap(w, h, bmpdata)); + delete[] bmpdata; + } + else + { + syslog(LOG_ERR, "glcdgraphics: malloc failed (cPBMFile::Load)."); + fclose(pbmFile); + return false; + } + fclose(pbmFile); + syslog(LOG_DEBUG, "glcdgraphics: image %s loaded.", fileName.c_str()); + + return true; +} + +bool cPBMFile::Save(cImage & image, const std::string & fileName) +{ + FILE * fp; + char str[32]; + const cBitmap * bitmap; + + if (image.Count() == 1) + { + fp = fopen(fileName.c_str(), "wb"); + if (fp) + { + bitmap = image.GetBitmap(0); + if (bitmap) + { + sprintf(str, "P4\n%d %d\n", bitmap->Width(), bitmap->Height()); + fwrite(str, strlen(str), 1, fp); + fwrite(bitmap->Data(), bitmap->LineSize() * bitmap->Height(), 1, fp); + } + fclose(fp); + } + } + else + { + uint16_t i; + char tmpStr[256]; + + for (i = 0; i < image.Count(); i++) + { + sprintf(tmpStr, "%.248s.%05d", fileName.c_str(), i); + fp = fopen(tmpStr, "wb"); + if (fp) + { + bitmap = image.GetBitmap(i); + if (bitmap) + { + sprintf(str, "P4\n%d %d\n", bitmap->Width(), bitmap->Height()); + fwrite(str, strlen(str), 1, fp); + fwrite(bitmap->Data(), bitmap->LineSize() * bitmap->Height(), 1, fp); + } + fclose(fp); + } + } + } + return true; +} + +} // end of namespace + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/glcdgraphics/pbm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/glcdgraphics/pbm.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,34 @@ +/* + * GraphLCD graphics library + * + * pbm.h - PBM file loading and saving + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2006 Andreas Regel + */ + +#ifndef _GLCDGRAPHICS_PBM_H_ +#define _GLCDGRAPHICS_PBM_H_ + +#include "imagefile.h" + +namespace GLCD +{ + +class cImage; + +class cPBMFile : public cImageFile +{ +public: + cPBMFile(); + virtual ~cPBMFile(); + virtual bool Load(cImage & image, const std::string & fileName); + virtual bool Save(cImage & image, const std::string & fileName); +}; + +} // end of namespace + +#endif + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/graphlcd.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/graphlcd.conf Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,528 @@ +# graphlcd.conf.sample +# +# This file contains a sample configuration for the graphlcd driver +# library. +# +# The format is ini-file-like. It is divided into sections that start +# at markers that look like [section]. Comments are all line-based +# comments, and are lines that start with '#'. +# +# The file starts with general settings, that are used by several +# drivers, followed by the sections. Each section represents a single +# display with a driver definition and specific settings which define +# how the driver acts. Some of these parameters like device, port and +# size are already parsed by the library but the drivers can also read +# their own options from the config file. The library passes them to +# the drivers. + +# WaitMethod +# Select the method that is used for sleeping. +# Possible values: +# 0 - usleep +# 1 - nanosleep +# 2 - nanosleep (sched_rr) - This is recommended on kernel 2.4 systems +# 3 - gettimeofday - This is recommended on kernel 2.6 systems +# Defaukt value: 3 +WaitMethod=3 + +# WaitPriority +# Select the process priority that is used when sleeping. +# Possible values: -20 <= x <= 19 +# Default value: 0 +WaitPriority=0 + +# General driver settings +# This section lists the display settings that are parsed and +# recognized by the driver library. +# +# Driver +# Sets the display's driver. +# Currently available are: framebuffer, gu140x32f, gu256x64-372, +# gu256x64C-3xx0, hd61830, image, ks0108, +# sed1520, sed1330, simlcd, t6963c, +# gu126x64D-K610A4 +# +# Device +# Instead of using the direct output via port address (see Port), you +# can use the parport device (/dev/parportX). The advantage over the +# direct output via port address is that this works for non-root users +# also. But it's a little bit slower. The modules ppdev.o, parport.o +# and parport_pc.o must be loaded or compiled into the kernel. +# +# Port +# Sets the port address of the parallel port. If this parameter is not +# given, 0x378 is used. To use this direct output, the program that +# uses the driver library has to be started with user 'root'. +# +# Width +# Sets the horizontal size of the display. If this parameter is not +# given, a default one specific to the driver is used. +# +# Height +# Sets the vertical size of the display. If this parameter is not +# given, a default one specific to the driver is used. +# +# UpsideDown +# Rotates the display output by 180 degrees. This might be useful, if +# the LCD is mounted upside-down. +# Possible values: 'yes', 'no' +# Default value: 'no' +# +# Invert +# Inverts the display. +# Possible values: 'yes', 'no' +# Default value: 'no' +# +# Brightness +# Sets the brightness of your display's backlight if supported by its +# driver. +# Supported by: gu140x32f, gu256x64-372, gu256x64-3900, gu126x64D-K610A4 +# Possible values: 0 <= x <= 100) +# Default value: 100 +# +# Contrast +# Sets the contrast of your display if supported by its driver. +# Supported by: serdisplib +# Possible values: 0 <= x <= 10 +# Default value: 5 +# +# Backlight +# Switches the backlight of your display on and off if supported by +# its driver. +# Supported by: serdisplib +# Possible values: 'yes', 'no' +# Default value: 'yes' +# +# AdjustTiming +# To get a timing that is as accurate as possible, the drivers measure +# the time for port commands (see: benchmark in syslog). You might +# decrease or increase the time to wait after port commands with this +# parameter. Normally, there is no need to change this parameter. +# (used by gu140x32f, gu256x64-372, gu256x64-3900, hd61830, ks0108, +# sed1330, sed1520, gu126x64D-K610A4) +# Possible values: -50 <= x <= 50 +# Default value: 0 +# +# RefreshDisplay +# Normally, most of the drivers do not update the whole display, but +# only the areas that have changed since last update. So it might be, +# that some faulty pixels would stay a longer time. To avoid this, the +# plugin makes a complete refresh from time to time. This parameter +# defines how often a complete refresh will be done. +# e.g.: A value of 5 means, that the plugin will make a complete +# refresh on every 5th update. +# A value of 0 completely disables complete refreshs. +# Possible values: 0 <= x <= 50 +# Default value: 5 + +######################################################################## + +[framebuffer] +# framebuffer driver +# Output goes to a framebuffer device +# Default size: 320 x 240 +Driver=framebuffer + +#Width=320 +#Height=240 +#UpsideDown=no +#Invert=no + +# Zoom +# Determines if pixels should be drawn double sized. +# Possible values: 0, 1 +Zoom=1 + +######################################################################## + +[gu140x32f] +# gu140x32f driver +# This is an 8-bit driver module for Noritake GU140x32-F7806 VFD +# displays. The VFD is operating in it's 8 bit-mode connected to a +# single PC parallel port. +# Default size: 140 x 32 +Driver=gu140x32f + +Port=0x378 +#Device=/dev/parport0 +#Width=140 +#Height=32 +#UpsideDown=no +#Invert=no +#Brightness=100 +#AdjustTiming=0 +#RefreshDisplay=1 + +# Wiring +# Select the type of wiring your display is connected with. +# Possible values: 'Standard', 'Windows' +# Default value: 'Standard' +Wiring=Standard + +######################################################################## + +[gu256x64-372] +# gu256x64-372 driver +# This is an 8-bit driver module for Noritake GU256x64-372 VFD +# displays. The VFD is operating in it's 8 bit-mode connected to a +# single PC parallel port. +# Default size: 256 x 64 +Driver=gu256x64-372 + +Port=0x378 +#Device=/dev/parport0 +#Width=256 +#Height=64 +#UpsideDown=no +#Invert=no +#Brightness=100 +#AdjustTiming=0 +#RefreshDisplay=1 + +######################################################################## + +[gu256x64-3900] +# gu256x64-3900 driver +# This is a driver module for Noritake GU256X64x-3900 VFD displays. The +# VFD is either operating in 8 bit-mode connected to a single PC +# parallel port or in serial mode connected to a single PC serial port. +# Default size: 256 x 64 +Driver=gu256x64-3900 + +Port=0x378 +#Device=/dev/parport0 +#Width=256 +#Height=64 +#UpsideDown=no +#Invert=no +#Brightness=100 +#AdjustTiming=0 +#RefreshDisplay=1 + +# Wiring +# Select the type of wiring your display is connected with. +# Possible values: 'Standard', 'Satyr' +# Default value: 'Standard' +Wiring=Standard + +# Interface +# Select the interface your display is connnected to. +# Possible values: 'Parallel', 'Serial' +# Default value: 'Parallel' +Interface=Parallel + +# DMA +# Enables/disables the usage of the controller's DMA mode which +# increases writing speed. This only works in parallel interface mode. +# Possible values: 'yes', 'no' +# Default value: 'yes' +DMA=yes + +######################################################################## + +[gu126x64D-K610A4] +# GU126x64D-K610A4 driver +# This is a driver module for Noritake GU126x64D-K610A4 VFD displays. +# The VFD is operating in 8 bit-mode connected to a single PC +# parallel port. +# Default size: 126 x 64 +Driver=gu126x64D-K610A4 + +Port=0x378 +# Device=/dev/parport0 + +#Width=126 +#Height=64 +#UpsideDown=no +#Invert=no +#Brightness=100 +#RefreshDisplay=1 +#AdjustTiming=30 + +# Debug some methods of the driver +# (add the values of interest) +# +# 1: show a log at the start of a refresh +# 2: show a log at the end of a refresh with timing information +# 4: show the rows (8 pixel) refreshed +# 8: show every commands/bytes sent to the display +# 16: log every unsuccessful waiting for display acknowledge +# +#Debug=0 + +######################################################################## + +[hd61830] +# hd61830 driver +# This is a driver module for the Hitachi HD61830 LCD controller. +# Default size: 240 x 128 +Driver=hd61830 +Port=0x378 +#Device=/dev/parport0 +#Width=240 +#Height=128 +#UpsideDown=no +#Invert=no +#AdjustTiming=0 +#RefreshDisplay=1 + +######################################################################## + +[image] +# image driver +# This is a driver module for writing image sequences in PBM (Portable +# Bit Map) format that show the plugin's output. +# Default size: 240 x 128 +Driver=image +#Width=240 +#Height=128 +#UpsideDown=no +#Invert=no + +######################################################################## + +[ks0108] +# ks0108 driver +# This is a driver module for the Samsung KS0108 LCD controller. +# Default size: 128 x 64 +Driver=ks0108 +Port=0x378 +#Device=/dev/parport0 +#Width=128 +#Height=64 +#UpsideDown=no +#Invert=no +#AdjustTiming=0 +#RefreshDisplay=1 + +# Control +# Select the variant of triggering the display's control lines. +# Possible values: '0', '1' +# Default value: '1' +Control=1 + +######################################################################## + +[sed1330] +# sed1330 driver +# This is a driver module for the Epson SED1330/1335 LCD controller. +# Default size: 320 x 240 +Driver=sed1330 +Port=0x378 +#Device=/dev/parport0 +#Width=320 +#Height=240 +#UpsideDown=no +#Invert=no +#AdjustTiming=0 +#refreshDisplay=1 + +# Wiring +# Select the type of wiring your display is connected with. +# Possible values: 'Original', 'PowerLCD', 'LCDProc', 'Tweakers', +# 'YASEDW' +# Default value: 'Original' +Wiring=Original + +# OscillatorFrequency +# Select the frequency the oscillator on your LCD board uses in kHz. +# Possible values: 1000 <= x <= 15000) +# Default value: 9600 +OscillatorFrequency=9600 + +# Interface +# Select the interface mode your display is connected with. +# Possible values: '6800', '8080' +# Default value: '6800' +Interface=6800 + +######################################################################## + +[sed1520] +# sed1520 driver +# This is a driver module for the Epson SED1520 LCD controller. +# Default size: 120 x 32 +Driver=sed1520 +Port=0x378 +#Device=/dev/parport0 +#Width=120 +#Height=32 +#UpsideDown=no +#Invert=no +#AdjustTiming=0 +#RefreshDisplay=1 + +######################################################################## + +[simlcd] +# simlcd driver +# This is the SimLCD driver module. Output goes to a file instead of +# LCD. Use SimLCD tool to view this file. +# Default size: 240 x 128 +Driver=simlcd +#Width=240 +#Height=128 +#UpsideDown=no +#Invert=no + +######################################################################## + +[t6963c] +# t6963c driver +# This is a driver module for the Toshiba T6963C LCD controller. +# Default size: 240 x 128 +Driver=t6963c +Port=0x378 +#Device=/dev/parport0 +#Width=240 +#Height=128 +#UpsideDown=no +#Invert=no +#RefreshDisplay=1 + +# Wiring +# Select the type of wiring your display is connected with. +# Possible values: 'Standard', 'Windows', 'Serial' +# Default value: 'Standard' +Wiring=Standard + +# FontSelect +# Select the font width your display uses for text mode. In most cases +# this is selectable through one of the pins of your LCD board +# Possible values: '6', '8' +# Default value: '6' +FontSelect=6 + +# AutoMode +# Enables or disables the usage of T6963C's auto mode which doubles +# writing speed when enabled. +# Possible values: 'yes', 'no' +# Default value: 'yes' +AutoMode=yes + +# StatusCheck +# Enables or disables the usage of T6963C's status check. When using a +# shielded cable for connecting your display, the disabling may be +# possible. This results in doubling the speed of writing data to the +# LCD. +# Possible values: 'yes', 'no' +# Default value: 'yes' +StatusCheck=yes + +######################################################################## + +[serdisp] +Driver=serdisp +# Controller +# Select the serdisplib name of your display. +# Possible values: See README in serdisplib package or http://serdisplib.sourceforge.net +#Controller=nokia7110 +#Controller=sed1335 +Controller=optrex323 + +# Options +# Pass display specific options +# Possible values: See driver-specific hardware page at http://serdisplib.sourceforge.net +# +# IMPORTANT: when using generic controllers like sed1330,sed1335,t6963c, width and height +# need to be set here (if different from default settings)! +# (serdisplib needs to be extended to be able to use 'Width' and 'Height' +# settings directly - this will be added later) +# +#Options=MODE=8080 +#Options=DELAY=2000;FONTWIDTH=8;CHECK=1 +#Options=WIDTH=128;HEIGHT=64 +#Options=WIDTH=128;HEIGHT=64;DELAY=2000;FONTWIDTH=8;CHECK=1 + +# Wiring +# Select Wiring +# Possible values: See driver-specific hardware page at http://serdisplib.sourceforge.net +#Wiring=1 +#Wiring=PowerLCD +#Wiring=DATA8,CS:nAUTO,A0:INIT,WR:nSTRB,RD:nSELIN + +# FGColour +# Drawing colour for non-monochrome displays +# Possible values: 0xRRGGBB (eg.: 0xFF0000) +# Defaults to black (0x000000) if not set +#FGColour=0x000000 + +# BGColour +# Background colour for non-monochrome displays +# Possible values: 0xRRGGBB (eg.: 0x00FFFF) +# Defaults to white (0xFFFFFF) if not set +#BGColour=0xFFFFFF + +Port=0x378 +#Device=/dev/parport0 +#UpsideDown=no +#Invert=no +Contrast=5 +Backlight=yes + +# Settings 'Width' and 'Height' are ignored at the moment. For generic controllers # (sed1330/1335, t6963) width and height need to be set using setting 'Options' (look above) +##Width=240 +##Height=128 + +######################################################################## + +[noritake800] +# noritake800 driver +# This is an 8-bit driver module for Noritake Noritake 800(A) series VFD +# displays. The VFD is operating in it's 8 bit-mode connected to a +# single PC parallel port. +# Default size: 128 x 64 +Driver=noritake800 +Port=0x378 +#Device=/dev/parport0 +Width=128 +Height=64 +#UpsideDown=no +#Invert=no +Brightness=50 +#AdjustTiming=0 # not used +#RefreshDisplay=0 # not used + +# Wiring +# Select the type of wiring your display is connected with. +# Possible values: 'LiquidMp3', 'MZ' +# Default value: 'LiquidMp3' +Wiring=LiquidMp3 + +######################################################################## + +[avrctl] +# avrctl driver +# This is an driver module for my AVR controlled LCD display connected via +# USB port. It uses some simple commands to update the display content. +# Default size: 256 x 128 +Driver=avrctl +Device=/dev/ttyUSB0 +Width=256 +Height=128 +#UpsideDown=no +#Invert=no +Brightness=50 +RefreshDisplay=1 + +######################################################################## + +[g15daemon] +# pseudo device for the g15daemon meta driver +# Output goes to the g15daemon which then displays it +Driver=g15daemon +Width=160 +Height=43 + +######################################################################## + +[network] +# network driver +# Default size: 240 x 128 +Driver=network +Width=256 +Height=128 +UpsideDown=no +Invert=no +Brightness=10 +RefreshDisplay=1 diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/Makefile Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,47 @@ +# +# Makefile for the graphlcd tools +# + + +-include ../Make.config + +### Targets: + +all: + @$(MAKE) -C convpic all + @$(MAKE) -C crtfont all +ifdef HAVE_FREETYPE2 + @$(MAKE) -C genfont all +endif + @$(MAKE) -C showpic all + @$(MAKE) -C showtext all + @$(MAKE) -C lcdtestpattern all + +install: + @$(MAKE) -C convpic install + @$(MAKE) -C crtfont install +ifdef HAVE_FREETYPE2 + @$(MAKE) -C genfont install +endif + @$(MAKE) -C showpic install + @$(MAKE) -C showtext install + @$(MAKE) -C lcdtestpattern install + +uninstall: + @$(MAKE) -C convpic uninstall + @$(MAKE) -C crtfont uninstall +ifdef HAVE_FREETYPE2 + @$(MAKE) -C genfont uninstall +endif + @$(MAKE) -C showpic uninstall + @$(MAKE) -C showtext uninstall + @$(MAKE) -C lcdtestpattern uninstall + +clean: + @$(MAKE) -C convpic clean + @$(MAKE) -C crtfont clean + @$(MAKE) -C genfont clean + @$(MAKE) -C showpic clean + @$(MAKE) -C showtext clean + @$(MAKE) -C lcdtestpattern clean + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/Makefile Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,46 @@ +# +# Makefile for the GraphLCD tool convpic +# + +-include ../../Make.config + +PRGNAME = convpic + +OBJS = $(PRGNAME).o bmp.o tiff.o tuxbox.o + +INCLUDES += -I../../ +LIBDIRS += -L../../glcdgraphics/ + + +all: $(PRGNAME) +.PHONY: all + +# Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + +# Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +# The main program: + +$(PRGNAME): $(OBJS) + $(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(LIBS) $(LIBDIRS) -lglcdgraphics -lstdc++ -o $(PRGNAME) + +install: $(PRGNAME) + install -d $(BINDIR) + install -m 755 -o root -g root -s $(PRGNAME) $(BINDIR) + +uninstall: + rm -f $(BINDIR)/$(PRGNAME) + +clean: + @-rm -f $(OBJS) $(DEPFILE) $(PRGNAME) *~ + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/bmp.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/bmp.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,375 @@ +/** + * GraphLCD plugin for the Video Disk Recorder + * + * bmp.c - bmp logo class + * + * (C) 2004 Andreas Brachold + * (C) 2001-2004 Carsten Siebholz + **/ + +/*************************************************************************** + * * + * 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 * + * * + ***************************************************************************/ + +#include +#include +#include + +#include + +#include +#include + +#include "bmp.h" + + +#pragma pack(1) +typedef struct BMPH { + uint16_t bmpIdentifier; + uint32_t bmpFileSize; + uint32_t bmpReserved; + uint32_t bmpBitmapDataOffset; + uint32_t bmpBitmapHeaderSize; + uint32_t bmpWidth; + uint32_t bmpHeight; + uint16_t bmpPlanes; + uint16_t bmpBitsPerPixel; + uint32_t bmpCompression; + uint32_t bmpBitmapDataSize; + uint32_t bmpHResolution; + uint32_t bmpVResolution; + uint32_t bmpColors; + uint32_t bmpImportantColors; +} BMPHEADER; // 54 bytes + +typedef struct RGBQ { + uint8_t rgbBlue; + uint8_t rgbGreen; + uint8_t rgbRed; + uint8_t rgbReserved; +} RGBQUAD; // 4 bytes +#pragma pack() + + +uint8_t bitmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; +uint8_t bitmaskl[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; +uint8_t bitmaskr[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01}; + +cBMPFile::cBMPFile() +{ +} + +cBMPFile::~cBMPFile() +{ +} + +bool cBMPFile::Load(GLCD::cImage & image, const std::string & fileName) +{ + FILE *fIN; + BMPHEADER bmpHeader; + RGBQUAD *pPalette; + char *pByte; + char Dummy; + long iNumColors; + long iSize; + uint32_t x, y; + uint16_t iRead; + uint8_t * bitmap = NULL; + bool bInvert = false; + + if (fileName.length() > 0) + { + fIN = fopen(fileName.c_str(), "rb"); + if (fIN) + { + if (fread(&bmpHeader, sizeof(BMPHEADER), 1, fIN)!=1) + { + fclose(fIN); + return false; + } + + // check for Windows BMP + if (bmpHeader.bmpBitmapHeaderSize != 0x00000028 ) + { + fprintf(stderr, "ERROR: only Windows BMP images are allowed.\n"); + fclose(fIN); + return false; + } + + // check for 2 color + iNumColors = (1 << bmpHeader.bmpBitsPerPixel); + if (iNumColors != 2) + { + fprintf(stderr, "ERROR: the image has %ld colors, but only images with 2 colors are allowed.\n", iNumColors); + fclose(fIN); + return false; + } + + iSize = bmpHeader.bmpHeight * bmpHeader.bmpWidth; + + pPalette = (RGBQUAD *) malloc( iNumColors*sizeof(RGBQUAD)); + if (!pPalette) + { + fprintf(stderr, "ERROR: cannot allocate memory\n"); + fclose(fIN); + return false; + } + + if (fread( pPalette, iNumColors*sizeof(RGBQUAD), 1, fIN)!=1) + { + free(pPalette); + fclose(fIN); + return false; + } + + // check colors + if (pPalette->rgbBlue+pPalette->rgbGreen+pPalette->rgbRed < + (pPalette+1)->rgbBlue+(pPalette+1)->rgbGreen+(pPalette+1)->rgbRed) + { + // index 0 represents 'black', index 1 'white' + bInvert = !bInvert; + } + else + { + // index 0 represents 'white', index 1 'black' + } + + if (fseek(fIN, bmpHeader.bmpBitmapDataOffset, SEEK_SET)==EOF) + { + free(pPalette); + fclose(fIN); + return false; + } + + switch (bmpHeader.bmpCompression) + { + case 0: // BI_RGB no compression + image.Clear(); + image.SetWidth(bmpHeader.bmpWidth); + image.SetHeight(bmpHeader.bmpHeight); + image.SetDelay(100); + bitmap = new unsigned char[bmpHeader.bmpHeight * ((bmpHeader.bmpWidth + 7) / 8)]; + if (!bitmap) + { + fprintf(stderr, "ERROR: cannot allocate memory\n"); + free(pPalette); + fclose(fIN); + image.Clear(); + return false; + } + + for (y = bmpHeader.bmpHeight; y > 0; y--) + { + pByte = (char*)bitmap + (y-1)*((bmpHeader.bmpWidth+7)/8); + iRead = 0; + for (x = 0; x < bmpHeader.bmpWidth / 8; x++) + { + if (fread(pByte, sizeof(char), 1, fIN) != 1) + { + delete[] bitmap; + free(pPalette); + fclose(fIN); + image.Clear(); + return false; + } + iRead++; + if (bInvert) + *pByte = *pByte ^ 0xff; + pByte++; + } + + if (bmpHeader.bmpWidth % 8) + { + if (fread(pByte, sizeof(char), 1, fIN) != 1) + { + delete [] bitmap; + free(pPalette); + fclose(fIN); + image.Clear(); + return false; + } + iRead++; + if (bInvert) + *pByte = *pByte^0xff; + *pByte = *pByte & bitmaskl[bmpHeader.bmpWidth%8]; + pByte++; + } + + // Scan line must be 4-byte-alligned + while (iRead % 4) + { + if (fread(&Dummy, sizeof(char), 1, fIN) != 1) + { + delete [] bitmap; + free(pPalette); + fclose(fIN); + image.Clear(); + return false; + } + iRead++; + } + } + image.AddBitmap(new GLCD::cBitmap(bmpHeader.bmpWidth, bmpHeader.bmpHeight, bitmap)); + break; + case 1: // BI_RLE4 RLE 4bit/pixel + case 2: // BI_RLE8 RLE 8bit/pixel + case 3: // BI_BITFIELDS + default: + fprintf(stderr, "ERROR: only uncompressed RGB images are allowed.\n"); + + free(pPalette); + fclose(fIN); + return false; + } + fclose(fIN); + } + else + { + fprintf(stderr, "ERROR: cannot open picture %s\n", fileName.c_str()); + } + } + else + { + fprintf(stderr, "ERROR: no FileName given!\n"); + } + return true; +} + +bool cBMPFile::Save(const GLCD::cBitmap * bitmap, const std::string & fileName) +{ + FILE *fOut; + BMPHEADER bmpHeader; + RGBQUAD bmpColor1, bmpColor2; + uint32_t dBDO, dBDSx, dBDS; + char *pByte; + char Dummy = 0x00; + uint32_t x, y; + uint16_t iWrote; + const uint8_t * bmpdata = bitmap->Data(); + + if (bitmap + && bitmap->Width() > 0 + && bitmap->Height() > 0) + { + memset(&bmpHeader, 0, sizeof(BMPHEADER)); + + dBDO = sizeof(BMPHEADER)+2*sizeof(RGBQUAD); + dBDSx = ((bitmap->Width() + 7) / 8 + 3) & 0xfffffffc; + dBDS = dBDSx * bitmap->Height(); + + bmpHeader.bmpIdentifier = 0x4d42; // "BM" + bmpHeader.bmpFileSize = dBDO + dBDS; + bmpHeader.bmpBitmapDataOffset = dBDO; + bmpHeader.bmpBitmapHeaderSize = 0x28; + bmpHeader.bmpWidth = bitmap->Width(); + bmpHeader.bmpHeight = bitmap->Height(); + bmpHeader.bmpPlanes = 0x01; + bmpHeader.bmpBitsPerPixel = 0x01; + bmpHeader.bmpCompression = 0x00; + bmpHeader.bmpBitmapDataSize = dBDS; + bmpHeader.bmpHResolution = 0xb13; // 72dpi + bmpHeader.bmpVResolution = 0xb13; // 72dpi + bmpHeader.bmpColors = 0x02; + bmpHeader.bmpImportantColors = 0x02; + + bmpColor1.rgbBlue = 0x00; + bmpColor1.rgbGreen = 0x00; + bmpColor1.rgbRed = 0x00; + bmpColor1.rgbReserved = 0x00; + bmpColor2.rgbBlue = 0xff; + bmpColor2.rgbGreen = 0xff; + bmpColor2.rgbRed = 0xff; + bmpColor2.rgbReserved = 0x00; + + + fOut = fopen(fileName.c_str(), "wb"); + if (!fOut) + { + fprintf(stderr,"Cannot create file: %s\n", fileName.c_str()); + return false; + } + fwrite(&bmpHeader, sizeof(BMPHEADER), 1, fOut); + fwrite(&bmpColor1, sizeof(RGBQUAD), 1, fOut); + fwrite(&bmpColor2, sizeof(RGBQUAD), 1, fOut); + + for (y=bitmap->Height(); y>0; y--) + { + pByte = (char*)bmpdata + (y-1)*((bitmap->Width()+7)/8); + iWrote = 0; + for (x=0; x<(uint32_t) bitmap->Width()/8; x++) + { + *pByte = *pByte^0xff; + if (fwrite(pByte, sizeof(char), 1, fOut)!=1) + { + fclose(fOut); + return false; + } + iWrote++; + pByte++; + } + // Scan line must be 4-byte-alligned + while (iWrote%4) + { + if (fwrite(&Dummy, sizeof(char), 1, fOut)!=1) + { + fclose(fOut); + return 3; + } + iWrote++; + } + } + fclose(fOut); + } + return true; +} + +bool cBMPFile::Save(GLCD::cImage & image, const std::string & fileName) +{ + const GLCD::cBitmap * bitmap; + + if (image.Count() == 1) + { + bitmap = image.GetBitmap(0); + if (bitmap) + { + if (!Save(bitmap, fileName)) + { + return false; + } + } + } + else + { + uint16_t i; + char tmpStr[256]; + + for (i = 0; i < image.Count(); i++) + { + sprintf(tmpStr, "%.248s.%05d", fileName.c_str(), i); + bitmap = image.GetBitmap(i); + if (bitmap) + { + if (!Save(bitmap, tmpStr)) + { + return false; + } + } + } + } + return true; +} diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/bmp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/bmp.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,45 @@ +/** + * GraphLCD plugin for the Video Disk Recorder + * + * bmp.h - bmp logo class + * + * (C) 2004 Andreas Brachold + * (C) 2001-2004 Carsten Siebholz + **/ + +/*************************************************************************** + * * + * 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 * + * * + ***************************************************************************/ + +#ifndef _BMP_H_ +#define _BMP_H_ + +#include + +class cBMPFile : public GLCD::cImageFile +{ +private: + bool Save(const GLCD::cBitmap * bitmap, const std::string & fileName); +public: + cBMPFile(); + virtual ~cBMPFile(); + virtual bool Load(GLCD::cImage & image, const std::string & fileName); + virtual bool Save(GLCD::cImage & image, const std::string & fileName); +}; + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/c_bmp2glcd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/c_bmp2glcd Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,10 @@ +#!/bin/sh +# Converts all BMP images to *.glcd + +old=bmp +new=glcd + +for file in ./*."$old"; do + convpic -i "$file" -o "`basename \"$file\" \"$old\"`$new" +done + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/c_tif2glcd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/c_tif2glcd Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,10 @@ +#!/bin/sh +# Converts all TIFF images to *.glcd + +old=tif +new=glcd + +for file in ./*."$old"; do + convpic -i "$file" -o "`basename \"$file\" \"$old\"`$new" +done + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/convall --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/convall Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,10 @@ +#!/bin/sh +# Converts all images in current directory + +old=$1 +new=$2 + +for file in ./*."$old"; do + convpic -i "$file" -o "`basename \"$file\" \"$old\"`$new" +done + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/convpic.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/convpic.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,279 @@ +/** + * convpic.c - a tool to convert images to + * own proprietary format of the logos and pictures + * for graphlcd plugin + * + * (C) 2004 Andreas Brachold + * (C) 2001-2003 by Carsten Siebholz + **/ + +/*************************************************************************** + * * + * 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 * + * * + ***************************************************************************/ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "bmp.h" +#include "tiff.h" +#include "tuxbox.h" + +static const char *prgname = "convpic"; +static const char *VERSION = "0.1.1"; + +unsigned int delay = 250; + + +enum ePicFormat +{ + pfUndefined, + pfTIFF, + pfBMP, + pfGLCD, + pfPBM, + pfTUXBOX +}; + +void usage(void); + +ePicFormat getFormat(const char* szFile) +{ + static const struct tagformats {const char* szExt; ePicFormat picformat;} formats[] = + { + {".tiff", pfTIFF }, + {".tif", pfTIFF }, + {".bmp", pfBMP }, + {".glcd", pfGLCD }, + {".pbm", pfPBM }, + {".ani", pfTUXBOX} + }; + ePicFormat pf = pfUndefined; + + if (szFile) + { + for (int i = strlen(szFile) - 1; i >= 0; i--) + { + if (*(szFile+i) == '.' && strlen(szFile + i + 1)) + { + for (unsigned int n = 0; n < sizeof(formats)/sizeof(*formats); n++) + { + if (!strcasecmp((szFile+i), formats[n].szExt)) + { + return formats[n].picformat; + } + } + } + } + } + return pf; +} + +GLCD::cImageFile * GetFileTranslator(ePicFormat Format) +{ + switch (Format) + { + case pfGLCD: + return new GLCD::cGLCDFile(); + + case pfPBM: + return new GLCD::cPBMFile(); + + case pfBMP: + return new cBMPFile(); + + case pfTIFF: + return new cTIFFFile(); + + case pfTUXBOX: + return new cTuxBoxFile(); + + default: + return NULL; + } + +} + +int main(int argc, char *argv[]) { + ePicFormat inFormat = pfUndefined; + ePicFormat outFormat = pfUndefined; + std::string inFile = ""; + std::string outFile = ""; + GLCD::cImage image; + GLCD::cImage nextImage; + GLCD::cImageFile * pInBitmap = NULL; + GLCD::cImageFile * pOutBitmap = NULL; + bool bError = false; + bool bInvert = false; + bool bDelay = false; + + + static struct option long_options[] = + { + {"invert", no_argument, NULL, 'n'}, + {"infile", required_argument, NULL, 'i'}, + {"outfile", required_argument, NULL, 'o'}, + {"delay", required_argument, NULL, 'd'}, + { NULL} + }; + + int c, option_index = 0; + while ((c=getopt_long(argc,argv,"ni:o:d:",long_options, &option_index))!=-1) { + switch (c) { + case 'n': + bInvert = true; + break; + + case 'i': + inFile = optarg; + break; + + case 'o': + outFile = optarg; + break; + + case 'd': + delay = atoi(optarg); + bDelay = true; + if (delay < 10) + { + fprintf(stderr, "Warning: You have specify a to short delay, minimum are 10 ms\n"); + delay = 10; + } + break; + + default: + return 1; + } + } + + if (inFile.length() == 0) + { + fprintf(stderr, "ERROR: You have to specify the infile (-i filename)\n"); + bError = true; + } + + if (pfUndefined == (inFormat = getFormat(inFile.c_str()))) + { + fprintf(stderr, "ERROR: You have to specify a correct extension for the %s\n", inFile.c_str()); + bError = true; + } + + if (outFile.length() == 0) + { + fprintf(stderr, "ERROR: You have to specify the outfile (-o filename)\n"); + bError = true; + } + + if (pfUndefined == (outFormat = getFormat(outFile.c_str()))) + { + fprintf(stderr, "ERROR: You have to specify a correct extension for the %s \n", outFile.c_str()); + bError = true; + } + + if (bError) + { + usage(); + return 1; + } + + + pInBitmap = GetFileTranslator(inFormat); + if (!pInBitmap) + return 2; + + pOutBitmap = GetFileTranslator(outFormat); + if (!pOutBitmap) + return 3; + + // Load Picture + fprintf(stdout, "loading %s\n", inFile.c_str()); + bError = !pInBitmap->Load(image, inFile); + if (!bError) + { + // Load more in files + while (optind < argc && !bError) + { + inFile = argv[optind++]; + inFormat = getFormat(inFile.c_str()); + if (inFormat == pfUndefined) + { + fprintf(stderr, "ERROR: You have to specify a correct extension for the %s\n", inFile.c_str()); + bError = true; + break; + } + pInBitmap = GetFileTranslator(inFormat); + if (!pInBitmap) + break; + + fprintf(stdout, "loading %s\n", inFile.c_str()); + if (pInBitmap->Load(nextImage, inFile)) + { + uint16_t i; + for (i = 0; i < nextImage.Count(); i++) + { + image.AddBitmap(new GLCD::cBitmap(*nextImage.GetBitmap(i))); + } + } + } + if (bDelay) + image.SetDelay(delay); + if (bInvert) + { + uint16_t i; + for (i = 0; i < image.Count(); i++) + { + image.GetBitmap(i)->Invert(); + } + } + fprintf(stdout, "saving %s\n", outFile.c_str()); + bError = !pOutBitmap->Save(image, outFile); + } + if (bError) { + return 4; + } + + fprintf(stdout, "conversion compeleted successfully.\n\n"); + + return 0; +} + +void usage(void) +{ + fprintf(stdout, "\n"); + fprintf(stdout, "%s v%s\n", prgname, VERSION); + fprintf(stdout, "%s is a tool to convert images to a simple format (*.glcd)\n", prgname); + fprintf(stdout, " that is used by the graphlcd plugin for VDR.\n\n"); + fprintf(stdout, " Usage: %s [-n] -i file[s...] -o outfile \n\n", prgname); + fprintf(stdout, " -n --invert inverts the output (default: none)\n"); + fprintf(stdout, " -i --infile specifies the name of the input file[s]\n"); + fprintf(stdout, " -o --outfile specifies the name of the output file\n"); + fprintf(stdout, " -d --delay specifies the delay between multiple images [Default: %d ms] \n",delay); + fprintf(stdout, "\n" ); + fprintf(stdout, " example: %s -i vdr-logo.bmp -o vdr-logo.glcd \n", prgname ); +} diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/formats.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/formats.txt Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,32 @@ +Dateiformat von "Graphlcd-Logo" + + +Einzelbild für LCD +================================= + +HEADER +Position Typ Name Bedeutung +0x0000 char[4] magic - "GLCD" +0x0004 word width - Breite der Bilder (LE) +0x0006 word height - Höhe der Bilder (LE) +0x0008 char[] data - Einzel-Bild + +DATEN +char[height][width/8], pro Byte 8 nebeneinander liegende Pixel + +Animation für LCD +================================= + +HEADER +Position Typ Name Bedeutung +0x0000 char[4] magic - "GLCA" +0x0004 word width - Breite der Bilder (LE) +0x0006 word height - Höhe der Bilder (LE) +0x0008 word count - Anzahl der Bilder (LE) +0x000a long delay - Wartezeit zwischen den Bildern (in ms; LE) +0x0010 char[] data - Einzel-Bilder + +DATEN +char[height][width/8], pro Byte 8 nebeneinander liegende Pixel (1 = Pixel gesetzt) + +LE = Little Endian byte order = wie bei intel ;) diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/tiff.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/tiff.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,201 @@ +/** + * GraphLCD plugin for the Video Disk Recorder + * + * tiff.c - tiff logo class + * + * (c) 2004 Andreas Brachold + * (c) 2001-2004 Carsten Siebholz + **/ + +/*************************************************************************** + * * + * 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 * + * * + ***************************************************************************/ + +#include +#include + +#include + +#include +#include + +#include "tiff.h" + + +#pragma pack(1) +typedef struct TIFFT{ + unsigned short tag; + unsigned short type; + unsigned long length; + /* 1 = BYTE. 8-bit unsigned integer. */ + /* 2 = ASCII. 8-bit bytes that store ASCII codes; the last byte must be null. */ + /* 3 = SHORT. A 16-bit (2-byte) unsigned integer. */ + /* 4 = LONG. A 32-bit (4-byte) unsigned integer. */ + /* 5 = RATIONAL. Two LONGs: the first represents the numerator of a fraction, the second the denominator. */ + unsigned long off_val; +} TIFFTAG; +#pragma pack() + +#define GETANDCHECK { t=fgetc(fIN);if(t==EOF) {fclose(fIN);return false;};} + +cTIFFFile::cTIFFFile() +{ +} + +cTIFFFile::~cTIFFFile() +{ +} + +bool cTIFFFile::Load(GLCD::cImage & image, const std::string & fileName) +{ + FILE *fIN; + TIFFTAG tifftag; + unsigned int tiff_header, tiff_anztags, tiff_data; + unsigned char cl,ch,y,i; + unsigned char height, width, strip, invert; + unsigned char fLittleEndian=0; + int j; + int t; + unsigned char *bitmap = NULL; + bool bInvert = false; + + if (fileName.length() > 0) + { + fIN = fopen(fileName.c_str(), "rb"); + if (fIN) + { + // isyslog("graphlcd plugin: try to load logo %s.", szFileName); + if (fseek(fIN, 0, SEEK_SET)==EOF) + { + fclose(fIN); + return false; + } + GETANDCHECK; cl=(unsigned char)t; + GETANDCHECK; ch=(unsigned char)t; + if ((cl==0x49) && (ch==0x49)) + { + fLittleEndian=1; + } + + if (fseek(fIN, 4, SEEK_SET)==EOF) + { + fclose(fIN); + return false; + } + GETANDCHECK; cl=(unsigned char)t; + GETANDCHECK; ch=(unsigned char)t; + tiff_header = cl+256*ch; + //printf("tiff_header:%d %x\n", tiff_header, tiff_header); + + if (fseek(fIN, tiff_header, SEEK_SET)==EOF) + { + fclose(fIN); + return false; + } + + GETANDCHECK; cl=(unsigned char)t; + GETANDCHECK; ch=(unsigned char)t; + tiff_anztags = cl+256*ch; + //printf("tiff_anztags:%d %x\n", tiff_anztags, tiff_anztags); + + height=0; + width=0; + strip=0; + invert=0; + for (i=0; (i>(8-width%8))<<(8-width%8); + } + } + image.AddBitmap(new GLCD::cBitmap(width, height, bitmap)); + } + else + { + fprintf(stderr, "ERROR: cannot allocate memory\n"); + } + fclose(fIN); + } + else + { + fprintf(stderr, "ERROR: cannot open picture %s\n", fileName.c_str()); + } + } + else + { + fprintf(stderr, "ERROR: no szFileName given!\n"); + } + return true; +} diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/tiff.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/tiff.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,42 @@ +/** + * GraphLCD plugin for the Video Disk Recorder + * + * tiff.h - tiff logo class + * + * (c) 2004 Andreas Brachold + * (c) 2001-2004 Carsten Siebholz + **/ + +/*************************************************************************** + * * + * 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 * + * * + ***************************************************************************/ + +#ifndef _TIFF_H_ +#define _TIFF_H_ + +#include + +class cTIFFFile : public GLCD::cImageFile +{ +public: + cTIFFFile(); + virtual ~cTIFFFile(); + virtual bool Load(GLCD::cImage & image, const std::string & fileName); +}; + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/tuxbox.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/tuxbox.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,280 @@ +/** + * GraphLCD plugin for the Video Disk Recorder + * + * tuxbox.c - tuxbox logo class + * + * (c) 2004 Andreas Brachold + **/ + +/*************************************************************************** + * * + * 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 * + * * + ***************************************************************************/ + +#include +#include +#include + +#include + +#include +#include + +#include "tuxbox.h" + +#pragma pack(1) +struct ani_header { + unsigned char magic[4]; // = "LCDA" + unsigned short format; // Format + unsigned short width; // Breite + unsigned short height; // Höhe + unsigned short count; // Anzahl Einzelbilder + unsigned long delay; // µs zwischen Einzelbildern +}; +#pragma pack() + +cTuxBoxFile::cTuxBoxFile() +{ +} + +cTuxBoxFile::~cTuxBoxFile() +{ +} + +bool cTuxBoxFile::Load(GLCD::cImage & image, const std::string & fileName) +{ + bool ret = false; + FILE * fIN; + long fileLen; + struct ani_header header; + bool bInvert = false; + + fIN = fopen(fileName.c_str(), "rb"); + if (fIN) + { + // get len of file + if (fseek(fIN, 0, SEEK_END)) + { + fclose(fIN); + return false; + } + fileLen = ftell(fIN); + + // rewind and get Header + if (fseek(fIN, 0, SEEK_SET)) + { + fclose(fIN); + return false; + } + + // Read header + if (fread(&header, sizeof(header), 1, fIN) != 1) + { + fclose(fIN); + return false; + } + + image.Clear(); + image.SetWidth(ntohs(header.width)); + image.SetHeight(ntohs(header.height)); + image.SetDelay(ntohl(header.delay) / 1000); + + // check Header + if (strncmp((const char*)header.magic, "LCDA", sizeof(header.magic)) || + !image.Width() || !image.Height() || ntohs(header.format) != 0) + { + fprintf(stderr, "ERROR: load %s failed, wrong header.\n", fileName.c_str()); + fclose(fIN); + return false; + } + + //fprintf(stderr,"%d %dx%d (%d %d) %d\n",ntohs(header.count),image.Width(),image.Height(),fileLen, ( (ntohs(header.count) * (image.Width() * ((image.Height() + 7) / 8))) + sizeof(header)),lhdr.delay); + + // check file length + if (!ntohs(header.count) + || (fileLen != (long) ( (ntohs(header.count) * (image.Width() * ((image.Height() + 7) / 8))) + sizeof(header)))) + { + fprintf(stderr, "ERROR: load %s failed, wrong size.\n", fileName.c_str()); + fclose(fIN); + return false; + } + // Set minimal limit for next image + if (image.Delay() < 10) + image.SetDelay(10); + for (unsigned int n=0;n 0 + && image.Width() + && image.Height()) + { + memcpy(header.magic, "LCDA", 4); + header.format = htons(0); + header.width = htons(image.Width()); + header.height = htons(image.Height()); + header.count = htons(image.Count()); + header.delay = htonl(image.Delay() * 1000); + + + if (image.Width() != 120 || image.Height() != 64) + { + fprintf(stderr,"WARNING: Maybe wrong image dimension (for all I know is 120x64 wanted) %s\n", fileName.c_str()); + } + + fOut = fopen(fileName.c_str(), "wb"); + if (!fOut) { + fprintf(stderr,"ERROR: Cannot create file: %s\n", fileName.c_str()); + return false; + } + + if (1 != fwrite(&header, sizeof(header), 1, fOut)) + { + fprintf(stderr,"ERROR: Cannot write fileheader: %s\n", fileName.c_str()); + fclose(fOut); + return false; + } + + for (unsigned int n = 0; n < image.Count(); n++) + { + bRet = false; + unsigned int nAniSize = image.Width() * ((image.Height() + 7) / 8); + unsigned char *pAni = new unsigned char[nAniSize]; + if (!pAni) + { + fprintf(stderr, "ERROR: malloc failed."); + break; + } + horz2vert(image.GetBitmap(n)->Data(), pAni, image.Width(), image.Height()); + + if (1 != fwrite(pAni, nAniSize, 1, fOut)) + { + delete [] pAni; + fprintf(stderr,"ERROR: Cannot write filedata: %s\n", fileName.c_str()); + break; + } + delete [] pAni; + bRet = true; + } + + fclose(fOut); + } + return bRet; +} + +/** Translate memory alignment from vertical to horizontal +rotate from {Byte} to {Byte} +{o}[o][o][o][o][o][o][o] => { oooooooo } +{o}[o][o][o][o][o][o][o] => [ oooooooo ] +{o}[o][o][o][o][o][o][o] => [ oooooooo ] +{o}[o][o][o][o][o][o][o] => [ oooooooo ] +{o}[o][o][o][o][o][o][o] => [ oooooooo ] +{o}[o][o][o][o][o][o][o] => [ oooooooo ] +{o}[o][o][o][o][o][o][o] => [ oooooooo ] +{o}[o][o][o][o][o][o][o] => [ oooooooo ]*/ +void cTuxBoxFile::vert2horz(const unsigned char* source, unsigned char* dest, int width, int height) { + int x, y, off; + memset(dest,0,height*((width+7)/8)); + + for (y=0; y> (x % 8)); + } + } + } +} + +/** Translate memory alignment from horizontal to vertical (rotate byte) +rotate from {Byte} to {Byte} +{ oooooooo } => {o}[o][o][o][o][o][o][o] +[ oooooooo ] => {o}[o][o][o][o][o][o][o] +[ oooooooo ] => {o}[o][o][o][o][o][o][o] +[ oooooooo ] => {o}[o][o][o][o][o][o][o] +[ oooooooo ] => {o}[o][o][o][o][o][o][o] +[ oooooooo ] => {o}[o][o][o][o][o][o][o] +[ oooooooo ] => {o}[o][o][o][o][o][o][o] +[ oooooooo ] => {o}[o][o][o][o][o][o][o]*/ +void cTuxBoxFile::horz2vert(const unsigned char* source, unsigned char* dest, int width, int height) { + int x, y, off; + memset(dest,0,width*((height+7)/8)); + + for (y=0; y> (x % 8))) + { + off = x + ((y/8) * width); + dest[off] |= (unsigned char)(0x1 << (y % 8)); + } + } + } +} diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/convpic/tuxbox.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/convpic/tuxbox.h Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,44 @@ +/** + * GraphLCD plugin for the Video Disk Recorder + * + * tuxbox.h - tuxbox logo class + * + * (c) 2004 Andreas Brachold + **/ + +/*************************************************************************** + * * + * 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 * + * * + ***************************************************************************/ +#ifndef _TUXBOX_H_ +#define _TUXBOX_H_ + +#include + +class cTuxBoxFile : public GLCD::cImageFile +{ +private: + void vert2horz(const unsigned char* source, unsigned char* dest, int width, int height); + void horz2vert(const unsigned char* source, unsigned char* dest, int width, int height); +public: + cTuxBoxFile(); + virtual ~cTuxBoxFile(); + virtual bool Load(GLCD::cImage & image, const std::string & fileName); + virtual bool Save(GLCD::cImage & image, const std::string & fileName); +}; + +#endif diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/crtfont/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/crtfont/Makefile Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,45 @@ +# +# Makefile for the GraphLCD tool crtfont +# + +-include ../../Make.config + +PRGNAME = crtfont + +OBJS = crtfont.o + +INCLUDES += -I../../ +LIBDIRS += -L../../glcdgraphics/ + +all: $(PRGNAME) +.PHONY: all + +# Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + +# Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +# The main program: + +$(PRGNAME): $(OBJS) + $(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(LIBDIRS) -lglcdgraphics -lstdc++ -o $(PRGNAME) + +install: $(PRGNAME) + install -d $(BINDIR) + install -m 755 -o root -g root -s $(PRGNAME) $(BINDIR) + +uninstall: + rm -f $(BINDIR)/$(PRGNAME) + +clean: + @-rm -f $(OBJS) $(DEPFILE) $(PRGNAME) *~ + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/crtfont/crtfont.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/crtfont/crtfont.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,305 @@ +/* + * GraphLCD tool crtfont + * + * crtfont.c - a tool to create *.fnt files for use with the GraphLCD + * graphics library + * + * based on graphlcd plugin 0.1.1 for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include +#include +#include +#include +#include +#include + +static const char *prgname = "crtfont"; +static const char *version = "0.1.6"; + +const int kMaxLineLength = 1024; + +enum ePicFormat +{ + undefined, + PBM +}; + + +void usage(void); + +char * trimleft(char * str) +{ + char * s = str; + while (*s == ' ' || *s == '\t') + s++; + strcpy(str, s); + return str; +} + +char * trimright(char * str) +{ + char * s = str + strlen(str) - 1; + while (s >= str && (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')) + *s-- = 0; + return str; +} + +char * trim(char * str) +{ + return trimleft(trimright(str)); +} + + +int main(int argc, char *argv[]) +{ + ePicFormat picFormat = undefined; + GLCD::cFont font; + char * picName = NULL; + char * descName = NULL; + char * fontName = NULL; + FILE * descFile; + bool error = false; + GLCD::cBitmap * bitmap = NULL; + GLCD::cBitmap * tmpBitmap = NULL; + GLCD::cBitmap * charBitmap = NULL; + char line[kMaxLineLength]; + int l = 0; + char * token; + int startOffset, endOffset; + int spaceWidth; + int version; + char * ptr; + + static struct option long_options[] = + { + { "format", required_argument, NULL, 'f'}, + { "bmpfile", required_argument, NULL, 'b'}, + { "descfile", required_argument, NULL, 'd'}, + { "outfile", required_argument, NULL, 'o'}, + { NULL} + }; + + int c, option_index = 0; + while ((c = getopt_long(argc, argv, "f:b:d:o:", long_options, &option_index)) != -1) + { + switch (c) + { + case 'f': + if (strcasecmp(optarg, "PBM") == 0) + picFormat = PBM; + break; + + case 'b': + picName = strdup(optarg); + break; + + case 'd': + descName = strdup(optarg); + break; + + case 'o': + fontName = strdup(optarg); + break; + + default: + return 1; + } + } + + if (picFormat == undefined) + { + fprintf(stderr, "ERROR: You have to specify the format (-f )\n"); + error = true; + } + if (!picName) + { + fprintf(stderr, "ERROR: You have to specify the bmpfile (-b bmpfile)\n"); + error = true; + } + if (!descName) + { + fprintf(stderr, "ERROR: You have to specify the descfile (-d descfile)\n"); + error = true; + } + if (!fontName) + { + fprintf(stderr, "ERROR: You have to specify the outfile (-o outfile)\n"); + error = true; + } + + if (error) + { + usage(); + return 1; + } + + descFile = fopen(descName,"r"); + if (!descFile) + { + fprintf(stderr, "Cannot open file: %s\n",descName); + return 2; + } + + // Load Picture + switch (picFormat) + { + case PBM: + bitmap = new GLCD::cBitmap(0, 0); + bitmap->LoadPBM(picName); + if (!bitmap) + { + fprintf(stderr, "Cannot open file: %s\n",picName); + return 2; + } + break; + + default: + return 2; + } + + if (!bitmap) + return 3; + + spaceWidth = 0; + + version = 0; + fgets(line, sizeof(line), descFile); + trim(line); + if (strstr(line, "version") != NULL) + { + ptr = strstr(line, ":"); + version = atoi(ptr + 1); + } + if (version != 1) + { + fprintf(stderr, "Wrong description file format version (found %d, expected 1)!\n", version); + return 2; + } + while (!feof(descFile)) + { + fgets(line, sizeof(line), descFile); + trim(line); + if (strstr(line, "fontheight") != NULL) + { + ptr = strstr(line, ":"); + font.SetTotalHeight(atoi(ptr + 1)); + } + else if (strstr(line, "fontascent") != NULL) + { + ptr = strstr(line, ":"); + font.SetTotalAscent(atoi(ptr + 1)); + } + else if (strstr(line, "lineheight") != NULL) + { + ptr = strstr(line, ":"); + font.SetLineHeight(atoi(ptr + 1)); + } + else if (strstr(line, "spacebetween") != NULL) + { + ptr = strstr(line, ":"); + font.SetSpaceBetween(atoi(ptr + 1)); + } + else if (strstr(line, "spacewidth") != NULL) + { + ptr = strstr(line, ":"); + spaceWidth = atoi(ptr + 1); + } + else + { + token = strtok(line, " "); + if (token) + { + startOffset = atoi(token); + + // get character + token = strtok(NULL, " "); + while (token) + { + uint16_t character; + if (strlen(token) == 1) + character = (uint8_t) token[0]; + else + character = atoi(token); + + // get EndOffset + token = strtok(NULL, " "); + endOffset = atoi(token); + tmpBitmap = bitmap->SubBitmap(startOffset, l * font.TotalHeight(), endOffset - 1, (l + 1) * font.TotalHeight() - 1); + if (spaceWidth > 0) + { + // calculate width of this character + int x; + int y; + int left = 255; + int right = 0; + for (y = 0; y < tmpBitmap->Height(); y++) + { + for (x = 0; x < tmpBitmap->Width(); x++) + { + if (tmpBitmap->GetPixel(x, y)) + break; + } + if (x < tmpBitmap->Width() && x < left) + left = x; + for (x = tmpBitmap->Width() - 1; x >= 0; x--) + { + if (tmpBitmap->GetPixel(x, y)) + break; + } + if (x >= 0 && x > right) + right = x; + } + if (left > right) + { + left = 0; + right = spaceWidth - 1; + } + charBitmap = tmpBitmap->SubBitmap(left, 0, right, font.TotalHeight() - 1); + font.SetCharacter(character, charBitmap); + delete tmpBitmap; + } + else + { + font.SetCharacter(character, tmpBitmap); + } + startOffset = endOffset; + + // get next character + token = strtok(NULL, " "); + } + } + l++; + } + } + fclose(descFile); + delete bitmap; + + if (font.SaveFNT(fontName)) + fprintf(stdout,"Font '%s' created successfully\n", fontName); + + return 0; +} + +void usage(void) +{ + fprintf(stdout, "\n"); + fprintf(stdout, "%s v%s\n", prgname, version); + fprintf(stdout, "%s is a tool to create *.fnt files that are used by the\n", prgname); + fprintf(stdout, " graphlcd plugin for VDR.\n\n"); + fprintf(stdout, " Usage: %s -f -b bmpfile -d descfile -o outfile\n\n", prgname); + fprintf(stdout, " -f --format specifies the format of the bitmap. Possible values are:\n"); + fprintf(stdout, " PBM : file is an binary PBM file\n" ); + fprintf(stdout, " -b --bmpfile specifies the name of the bitmap file (*.pbm)\n"); + fprintf(stdout, " -d --descfile specifies the name of the description file (*.desc)\n"); + fprintf(stdout, " -o --outfile specifies the name of the output file (*.fnt)\n"); + fprintf(stdout, "\n" ); + fprintf(stdout, " example: %s -f PBM -b f12.pbm -d f12.desc -o f12.fnt\n", prgname); +} diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/genfont/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/genfont/Makefile Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,48 @@ +# +# Makefile for the GraphLCD tool crtfont +# + +-include ../../Make.config + +PRGNAME = genfont + +OBJS = genfont.o + +INCLUDES += -I../../ +INCLUDES += `freetype-config --cflags` + +LIBDIRS += -L../../glcdgraphics/ +LIBS += `freetype-config --libs` + +all: $(PRGNAME) +.PHONY: all + +# Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + +# Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +# The main program: + +$(PRGNAME): $(OBJS) + $(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(LIBDIRS) $(LIBS) -lglcdgraphics -lstdc++ -o $(PRGNAME) + +install: $(PRGNAME) + install -d $(BINDIR) + install -m 755 -o root -g root -s $(PRGNAME) $(BINDIR) + +uninstall: + rm -f $(BINDIR)/$(PRGNAME) + +clean: + @-rm -f $(OBJS) $(DEPFILE) $(PRGNAME) *~ + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/genfont/genfont.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/genfont/genfont.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,167 @@ +/* + * GraphLCD tool genfont + * + * genfont.c - a tool to create *.fnt files for use with the GraphLCD + * graphics library + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include +#include +#include + +#include +#include + +static const char *prgname = "genfont"; +static const char *version = "0.0.2"; + +void usage(void) +{ + fprintf(stdout, "\n"); + fprintf(stdout, "%s v%s\n", prgname, version); + fprintf(stdout, "%s is a tool to create *.fnt files that are used by the\n", prgname); + fprintf(stdout, " graphlcd plugin for VDR.\n\n"); + fprintf(stdout, " Usage: %s -f -i infile -o outfile -s size\n\n", prgname); + fprintf(stdout, " -f --format specifies the format of the output files:\n"); + fprintf(stdout, " 0 - fnt (default)\n"); + fprintf(stdout, " 1 - pbm & desc\n"); + fprintf(stdout, " -i --input specifies the name of the input font file (*.ttf)\n"); + fprintf(stdout, " -o --output specifies the base name of the output files\n"); + fprintf(stdout, " -s --size font size of the generated font file\n"); + fprintf(stdout, "\n" ); + fprintf(stdout, " example: %s -i verdana.ttf -o verdana20 -s 20\n", prgname); + fprintf(stdout, " %s -f 1 -i verdana.ttf -o verdana20 -s 20\n", prgname); +} + + +int main(int argc, char *argv[]) +{ + static struct option long_options[] = + { + { "format", required_argument, NULL, 'f'}, + { "input", required_argument, NULL, 'i'}, + { "output", required_argument, NULL, 'o'}, + { "size", required_argument, NULL, 's'}, + { NULL} + }; + + int c; + int option_index = 0; + int format = 0; + std::string inputFontFile = ""; + std::string outputName = ""; + int size = 30; + + while ((c = getopt_long(argc, argv, "f:i:o:s:", long_options, &option_index)) != -1) + { + switch (c) + { + case 'f': + format = atoi(optarg); + break; + + case 'i': + inputFontFile = optarg; + break; + + case 'o': + outputName = optarg; + break; + + case 's': + size = atoi(optarg); + break; + + default: + usage(); + break; + } + } + if (format > 1) + { + usage(); + return 1; + } + if (inputFontFile == "") + { + usage(); + return 1; + } + if (outputName == "") + { + outputName = inputFontFile; + } + + GLCD::cFont font; + if (!font.LoadFT2(inputFontFile, "iso-8859-1", size, false)) + { + return 1; + } + + GLCD::cBitmap * bitmap = NULL; + std::string fileName; + FILE * descFile = NULL; + int posX = 0; + int posY = 0; + + if (format == 0) + { + fileName = outputName + ".fnt"; + if (!font.SaveFNT(fileName)) + { + return 1; + } + } + else + { + fileName = outputName + ".desc"; + descFile = fopen(fileName.c_str(), "wb"); + if (!descFile) + { + fprintf(stderr, "Cannot open file: %s\n", fileName.c_str()); + return 1; + } + bitmap = new GLCD::cBitmap(32 * font.TotalWidth(), 8 * font.TotalHeight()); + bitmap->Clear(); + fprintf(descFile, "version:1\n"); + fprintf(descFile, "fontheight:%d\n", font.TotalHeight()); + fprintf(descFile, "fontascent:%d\n", font.TotalAscent()); + fprintf(descFile, "lineheight:%d\n", font.LineHeight()); + fprintf(descFile, "spacebetween:%d\n", 0); + fprintf(descFile, "spacewidth:%d\n", 0); + + for (unsigned int i = 0; i < 256; i++) + { + const GLCD::cBitmap * charBitmap = font.GetCharacter((char) i); + if (charBitmap == NULL) + continue; + + bitmap->DrawBitmap(posX, posY, *charBitmap, GLCD::clrBlack); + fprintf(descFile, "%d %d ", posX, i); + posX += charBitmap->Width(); + if ((i % 32) == 31) + { + fprintf(descFile, "%d\n", posX); + posY += font.TotalHeight(); + posX = 0; + } + } + + if (posX > 0) // write last end marker + fprintf(descFile, "%d\n", posX); + fileName = outputName + ".pbm"; + bitmap->SavePBM(fileName); + delete bitmap; + fclose(descFile); + } + + fprintf(stdout, "Font successfully generated.\n"); + + return 0; +} diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/lcdtestpattern/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/lcdtestpattern/Makefile Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,46 @@ +# +# Makefile for the GraphLCD tool showpic +# + +-include ../../Make.config + +PRGNAME = lcdtestpattern + +OBJS = lcdtestpattern.o + +INCLUDES += -I../../ +LIBDIRS += -L../../glcdgraphics/ -L../../glcddrivers/ + + +all: $(PRGNAME) +.PHONY: all + +# Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + +# Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +# The main program: + +$(PRGNAME): $(OBJS) + $(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(LIBS) $(LIBDIRS) -lglcdgraphics -lglcddrivers -lstdc++ -o $(PRGNAME) + +install: $(PRGNAME) + install -d $(BINDIR) + install -m 755 -o root -g root -s $(PRGNAME) $(BINDIR) + +uninstall: + rm -f $(BINDIR)/$(PRGNAME) + +clean: + @-rm -f $(OBJS) $(DEPFILE) $(PRGNAME) *~ + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/lcdtestpattern/lcdtestpattern.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/lcdtestpattern/lcdtestpattern.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,260 @@ +/* + * GraphLCD tool lcdtestpattern + * + * lcdtestpattern.c - a tool to display some testpattern on an GLCD + * + * based on showpic.c of graphlcd-base + * (c) 2004 Andreas Regel + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2007 Alexander Rieger (Alexander.Rieger AT inka.de) + */ + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +//----------------------------------------------------------------------------- +static const char *prgname = "lcdtestpattern"; +static const char *version = "0.1.0"; + +static const int kDefaultSleepMs = 0; +static const char * kDefaultConfigFile = "/etc/graphlcd.conf"; + +static volatile bool stopProgramm = false; + +//----------------------------------------------------------------------------- +static void sighandler(int signal) +{ + switch (signal) + { + case SIGINT: + case SIGQUIT: + case SIGTERM: + stopProgramm = true; + } // switch +} // sighandler() + +//----------------------------------------------------------------------------- +void usage() +{ + fprintf(stdout, "\n"); + fprintf(stdout, "%s v%s\n", prgname, version); + fprintf(stdout, "%s is a tool to show test patterns on a LCD.\n", prgname); + fprintf(stdout, "\n"); + fprintf(stdout, " Usage: %s [-c CONFIGFILE] [-d DISPLAY] [-s SLEEP] [-uie]\n\n", prgname); + fprintf(stdout, " -c --config specifies the location of the config file\n"); + fprintf(stdout, " (default: /etc/graphlcd.conf)\n"); + fprintf(stdout, " -d --display specifies the output display (default is the first one)\n"); + fprintf(stdout, " -u --upsidedown rotates the output by 180 degrees (default: no)\n"); + fprintf(stdout, " -i --invert inverts the output (default: no)\n"); + fprintf(stdout, " -e --endless show all images in endless loop (default: no)\n"); + fprintf(stdout, " -s --sleep set sleeptime between two patterns [ms] (default: %d ms)\n", kDefaultSleepMs); + fprintf(stdout, " -b --brightness set brightness for display if driver support it [%%]\n"); + fprintf(stdout, " (default: config file value)\n"); + fprintf(stdout, "\n" ); + fprintf(stdout, " examples: %s -c /etc/graphlcd.conf\n", prgname); + fprintf(stdout, " %s -c /etc/graphlcd.conf -d LCD_T6963 -u -i\n", prgname); + fprintf(stdout, "\n" ); +} // usage() + +//----------------------------------------------------------------------------- +int main(int argc, char *argv[]) +{ + static struct option long_options[] = + { + {"config", required_argument, NULL, 'c'}, + {"display", required_argument, NULL, 'd'}, + {"sleep", required_argument, NULL, 's'}, + {"endless", no_argument, NULL, 'e'}, + {"upsidedown", no_argument, NULL, 'u'}, + {"invert", no_argument, NULL, 'i'}, + {"brightness", required_argument, NULL, 'b'}, + {NULL} + }; + + std::string configName = ""; + std::string displayName = ""; + bool upsideDown = false; + bool invert = false; + int brightness = -1; + bool delay = false; + int sleepMs = kDefaultSleepMs; + bool endless = false; + unsigned int displayNumber = 0; + + int c, option_index = 0; + while ((c = getopt_long(argc, argv, "c:d:s:euib:", long_options, &option_index)) != -1) + { + switch(c) + { + case 'c': + configName = optarg; + break; + + case 'd': + displayName = optarg; + break; + + case 'u': + upsideDown = true; + break; + + case 'i': + invert = true; + break; + + case 's': + sleepMs = atoi(optarg); + delay = true; + break; + + case 'e': + endless = true; + break; + + case 'b': + brightness = atoi(optarg); + if (brightness < 0) brightness = 0; + if (brightness > 100) brightness = 100; + break; + + default: + usage(); + return 1; + } // switch + } // while + + if (configName.length() == 0) + { + configName = kDefaultConfigFile; + syslog(LOG_INFO, "Error: No config file specified, using default (%s).\n", configName.c_str()); + } // if + + if (GLCD::Config.Load(configName) == false) + { + fprintf(stdout, "Error loading config file!\n"); + return 2; + } // if + + if (GLCD::Config.driverConfigs.size() > 0) + { + if (displayName.length() > 0) + { + for (displayNumber = 0; displayNumber < GLCD::Config.driverConfigs.size(); displayNumber++) + { + if (GLCD::Config.driverConfigs[displayNumber].name == displayName) + break; + } // for + + if (displayNumber == GLCD::Config.driverConfigs.size()) + { + fprintf(stdout, "ERROR: Specified display %s not found in config file!\n", displayName.c_str()); + return 3; + } // if + } + else + { + fprintf(stdout, "WARNING: No display specified, using first one.\n"); + displayNumber = 0; + } // if + } + else + { + fprintf(stdout, "ERROR: No displays specified in config file!\n"); + return 4; + } // if + + GLCD::Config.driverConfigs[displayNumber].upsideDown ^= upsideDown; + GLCD::Config.driverConfigs[displayNumber].invert ^= invert; + + if (brightness != -1) + { + GLCD::Config.driverConfigs[displayNumber].brightness = brightness; + } // if + + GLCD::cDriver * lcd = GLCD::CreateDriver(GLCD::Config.driverConfigs[displayNumber].id, &GLCD::Config.driverConfigs[displayNumber]); + if (!lcd) + { + fprintf(stderr, "ERROR: Failed creating display object %s\n", displayName.c_str()); + return 6; + } // if + + if (lcd->Init() != 0) + { + fprintf(stderr, "ERROR: Failed initializing display %s\n", displayName.c_str()); + delete lcd; + return 7; + } // if + + lcd->SetBrightness(GLCD::Config.driverConfigs[displayNumber].brightness); + + signal(SIGINT, sighandler); + signal(SIGQUIT, sighandler); + signal(SIGTERM, sighandler); + signal(SIGHUP, sighandler); + + //----- show horizontal lines ----- + for (int aByte = 1; aByte <= 255 && !stopProgramm; ++aByte) + { + unsigned char aData = GLCD::ReverseBits(aByte); + printf("clear and test byte: 0x%02X\n", aByte); + lcd->Clear(); + + for (int y = 0; y < lcd->Height() && !stopProgramm; ++y) + { + for (int x = 0; x < lcd->Width() && !stopProgramm; x += 8) + { + lcd->Set8Pixels(x, y, aData); + } // for + } // for + + lcd->Refresh(true); + usleep(sleepMs * 1000); + } // for + + //----- show vertial lines ----- + for (int aByte = 1; aByte <= 255 && !stopProgramm; ++aByte) + { + printf("clear and test byte: 0x%02X\n", aByte); + lcd->Clear(); + + for (int y = 0; y < lcd->Height() && !stopProgramm; ++y) + { + unsigned char aData = (((1 << (y % 8)) & aByte) == 0) ? 0x00 : 0xFF; + for (int x = 0; x < lcd->Width() && !stopProgramm; x += 8) + { + lcd->Set8Pixels(x, y, aData); + } // for + } // for + + lcd->Refresh(true); + usleep(sleepMs * 1000); + } // for + + //----- cleanup ----- + lcd->Clear(); + lcd->Refresh(true); + lcd->DeInit(); + delete lcd; + + return 0; +} // main() diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/showpic/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/showpic/Makefile Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,46 @@ +# +# Makefile for the GraphLCD tool showpic +# + +-include ../../Make.config + +PRGNAME = showpic + +OBJS = showpic.o + +INCLUDES += -I../../ +LIBDIRS += -L../../glcdgraphics/ -L../../glcddrivers/ + + +all: $(PRGNAME) +.PHONY: all + +# Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + +# Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +# The main program: + +$(PRGNAME): $(OBJS) + $(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(LIBS) $(LIBDIRS) -lglcdgraphics -lglcddrivers -lstdc++ -o $(PRGNAME) + +install: $(PRGNAME) + install -d $(BINDIR) + install -m 755 -o root -g root -s $(PRGNAME) $(BINDIR) + +uninstall: + rm -f $(BINDIR)/$(PRGNAME) + +clean: + @-rm -f $(OBJS) $(DEPFILE) $(PRGNAME) *~ + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/showpic/showpic.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/showpic/showpic.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,256 @@ +/* + * GraphLCD tool showpic + * + * showpic.c - a tool to show image files in GLCD format on a LCD + * + * based on graphlcd plugin 0.1.1 for the Video Disc Recorder + * (c) 2001-2004 Carsten Siebholz + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +static const char *prgname = "showpic"; +static const char *version = "0.1.2"; + +static const int kDefaultSleepMs = 100; +static const char * kDefaultConfigFile = "/etc/graphlcd.conf"; + +static volatile bool stopProgramm = false; + +static void sighandler(int signal) +{ + switch (signal) + { + case SIGINT: + case SIGQUIT: + case SIGTERM: + stopProgramm = true; + } +} + +void usage() +{ + fprintf(stdout, "\n"); + fprintf(stdout, "%s v%s\n", prgname, version); + fprintf(stdout, "%s is a tool to show an image on a LCD.\n", prgname); + fprintf(stdout, "The image must be in a special format (*.glcd).\n"); + fprintf(stdout, "You can create such images with the convpic tool.\n\n"); + fprintf(stdout, " Usage: %s [-c CONFIGFILE] [-d DISPLAY] [-s SLEEP] [-uie] file [more files]\n\n", prgname); + fprintf(stdout, " -c --config specifies the location of the config file\n"); + fprintf(stdout, " (default: /etc/graphlcd.conf)\n"); + fprintf(stdout, " -d --display specifies the output display (default is the first one)\n"); + fprintf(stdout, " -u --upsidedown rotates the output by 180 degrees (default: no)\n"); + fprintf(stdout, " -i --invert inverts the output (default: no)\n"); + fprintf(stdout, " -e --endless show all images in endless loop (default: no)\n"); + fprintf(stdout, " -s --sleep set sleeptime between two images [ms] (default: %d ms)\n", kDefaultSleepMs); + fprintf(stdout, " -b --brightness set brightness for display if driver support it [%%]\n"); + fprintf(stdout, " (default: config file value)\n"); + fprintf(stdout, "\n" ); + fprintf(stdout, " examples: %s -c /etc/graphlcd.conf vdr-logo.glcd\n", prgname); + fprintf(stdout, " %s -c /etc/graphlcd.conf -d LCD_T6963 -u -i vdr-logo.glcd\n", prgname); + fprintf(stdout, "\n" ); +} + +int main(int argc, char *argv[]) +{ + static struct option long_options[] = + { + {"config", required_argument, NULL, 'c'}, + {"display", required_argument, NULL, 'd'}, + {"sleep", required_argument, NULL, 's'}, + {"endless", no_argument, NULL, 'e'}, + {"upsidedown", no_argument, NULL, 'u'}, + {"invert", no_argument, NULL, 'i'}, + {"brightness", required_argument, NULL, 'b'}, + {NULL} + }; + + std::string configName = ""; + std::string displayName = ""; + bool upsideDown = false; + bool invert = false; + int brightness = -1; + bool delay = false; + int sleepMs = 100; + bool endless = false; + unsigned int displayNumber = 0; + + int c, option_index = 0; + while ((c = getopt_long(argc, argv, "c:d:s:euib:", long_options, &option_index)) != -1) + { + switch(c) + { + case 'c': + configName = optarg; + break; + + case 'd': + displayName = optarg; + break; + + case 'u': + upsideDown = true; + break; + + case 'i': + invert = true; + break; + + case 's': + sleepMs = atoi(optarg); + delay = true; + break; + + case 'e': + endless = true; + break; + + case 'b': + brightness = atoi(optarg); + if (brightness < 0) brightness = 0; + if (brightness > 100) brightness = 100; + break; + + default: + usage(); + return 1; + } + } + + if (configName.length() == 0) + { + configName = kDefaultConfigFile; + syslog(LOG_INFO, "Error: No config file specified, using default (%s).\n", configName.c_str()); + } + + if (GLCD::Config.Load(configName) == false) + { + fprintf(stdout, "Error loading config file!\n"); + return 2; + } + if (GLCD::Config.driverConfigs.size() > 0) + { + if (displayName.length() > 0) + { + for (displayNumber = 0; displayNumber < GLCD::Config.driverConfigs.size(); displayNumber++) + { + if (GLCD::Config.driverConfigs[displayNumber].name == displayName) + break; + } + if (displayNumber == GLCD::Config.driverConfigs.size()) + { + fprintf(stdout, "ERROR: Specified display %s not found in config file!\n", displayName.c_str()); + return 3; + } + } + else + { + fprintf(stdout, "WARNING: No display specified, using first one.\n"); + displayNumber = 0; + } + } + else + { + fprintf(stdout, "ERROR: No displays specified in config file!\n"); + return 4; + } + + if (optind == argc) + { + usage(); + fprintf(stderr, "ERROR: You have to specify the image\n"); + return 5; + } + + GLCD::Config.driverConfigs[displayNumber].upsideDown ^= upsideDown; + GLCD::Config.driverConfigs[displayNumber].invert ^= invert; + if (brightness != -1) + GLCD::Config.driverConfigs[displayNumber].brightness = brightness; + GLCD::cDriver * lcd = GLCD::CreateDriver(GLCD::Config.driverConfigs[displayNumber].id, &GLCD::Config.driverConfigs[displayNumber]); + if (!lcd) + { + fprintf(stderr, "ERROR: Failed creating display object %s\n", displayName.c_str()); + return 6; + } + if (lcd->Init() != 0) + { + fprintf(stderr, "ERROR: Failed initializing display %s\n", displayName.c_str()); + delete lcd; + return 7; + } + lcd->SetBrightness(GLCD::Config.driverConfigs[displayNumber].brightness); + + signal(SIGINT, sighandler); + signal(SIGQUIT, sighandler); + signal(SIGTERM, sighandler); + signal(SIGHUP, sighandler); + + const GLCD::cBitmap * bitmap; + GLCD::cImage image; + GLCD::cGLCDFile glcd; + int optFile; + std::string picFile; + + optFile = optind; + while (optFile < argc && !stopProgramm) + { + picFile = argv[optFile++]; + if (glcd.Load(image, picFile) == false) + { + fprintf(stderr, "ERROR: Failed loading file %s\n", picFile.c_str()); + return 8; + } + + if (delay) + image.SetDelay(sleepMs); + + while ((bitmap = image.GetBitmap()) != NULL && !stopProgramm) + { + lcd->SetScreen(bitmap->Data(), bitmap->Width(), bitmap->Height(), bitmap->LineSize()); + lcd->Refresh(true); + + if (image.Next(0)) // Select next image + { + usleep(image.Delay() * 1000); + } + else if (endless && argc == (optind + 1)) // Endless and one and only image + { + image.First(0); + usleep(image.Delay() * 1000); + } + else + break; + } + + if (optFile < argc || endless) + usleep(sleepMs * 1000); + if (optFile >= argc && endless) + optFile = optind; + } + + lcd->DeInit(); + delete lcd; + + return 0; +} diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/showtext/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/showtext/Makefile Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,46 @@ +# +# Makefile for the GraphLCD tool showtext +# + +-include ../../Make.config + +PRGNAME = showtext + +OBJS = showtext.o + +INCLUDES += -I../../ +LIBDIRS += -L../../glcdgraphics/ -L../../glcddrivers/ + + +all: $(PRGNAME) +.PHONY: all + +# Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + +# Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +# The main program: + +$(PRGNAME): $(OBJS) + $(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(LIBS) $(LIBDIRS) -lglcdgraphics -lglcddrivers -lstdc++ -o $(PRGNAME) + +install: $(PRGNAME) + install -d $(BINDIR) + install -m 755 -o root -g root -s $(PRGNAME) $(BINDIR) + +uninstall: + rm -f $(BINDIR)/$(PRGNAME) + +clean: + @-rm -f $(OBJS) $(DEPFILE) $(PRGNAME) *~ + diff -r d0e62fc47285 -r df6a40031aa5 graphlcd-base/tools/showtext/showtext.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphlcd-base/tools/showtext/showtext.c Wed Feb 06 17:32:55 2008 +0000 @@ -0,0 +1,279 @@ +/* + * GraphLCD tool showtext + * + * showtext.c - a tool to show a text on a LCD + * + * This file is released under the GNU General Public License. Refer + * to the COPYING file distributed with this package. + * + * (c) 2004 Andreas Regel + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +static const char *prgname = "showtext"; +static const char *version = "0.0.3"; + +static const char * kDefaultConfigFile = "/etc/graphlcd.conf"; + +static const int kFontFNT = 0; +static const int kFontFT2 = 1; + +void usage() +{ + fprintf(stdout, "\n"); + fprintf(stdout, "%s v%s\n", prgname, version); + fprintf(stdout, "%s is a tool to show a text on a LCD.\n", prgname); + fprintf(stdout, "\n"); + fprintf(stdout, " Usage: %s [-c CONFIGFILE] [-d DISPLAY] [-f FONT] [-x XPOS] [-y YPOS] [-uib] text [more text]\n\n", prgname); + fprintf(stdout, " -c --config specifies the location of the config file\n"); + fprintf(stdout, " (default: /etc/graphlcd.conf)\n"); + fprintf(stdout, " -d --display specifies the output display (default is the first one)\n"); + fprintf(stdout, " -f --font specifies the font that is used for the text:\n"); + fprintf(stdout, " fnt:/path/to/font.fnt for GraphLCD font format\n"); + fprintf(stdout, " ft2:/path/to/font.ttf:size for FreeType2 supported fonts\n"); + fprintf(stdout, " -e --encoding specifies the encoding that is used for the text\n"); + fprintf(stdout, " (p.e. iso8859-1)\n"); + fprintf(stdout, " -x --xpos specifies the x-position where the text starts\n"); + fprintf(stdout, " -y --ypos specifies the y-position where the text starts\n"); + fprintf(stdout, " -u --upsidedown rotates the output by 180 degrees (default: no)\n"); + fprintf(stdout, " -i --invert inverts the output (default: no)\n"); + fprintf(stdout, " -b --brightness set brightness for display if driver support it [%%]\n"); + fprintf(stdout, " (default: config file value)\n"); + fprintf(stdout, "\n" ); + fprintf(stdout, " example: %s -c /etc/graphlcd.conf -f fnt:f17.fnt \"Line1\" \"Line2\"\n", prgname); + fprintf(stdout, "\n" ); +} + +int main(int argc, char *argv[]) +{ + static struct option long_options[] = + { + {"config", required_argument, NULL, 'c'}, + {"display", required_argument, NULL, 'd'}, + {"font", required_argument, NULL, 'f'}, + {"encoding", required_argument, NULL, 'e'}, + {"upsidedown", no_argument, NULL, 'u'}, + {"invert", no_argument, NULL, 'i'}, + {"brightness", required_argument, NULL, 'b'}, + {"xpos", required_argument, NULL, 'x'}, + {"ypos", required_argument, NULL, 'y'}, + {NULL} + }; + + std::string configName = ""; + std::string displayName = ""; + std::string fontName; + std::string fontFileName = ""; + std::string encoding = ""; + int fontType; + int fontSize = 16; + bool upsideDown = false; + bool invert = false; + int brightness = -1; + int x = 0; + int y = 0; + unsigned int displayNumber = 0; + + int c, option_index = 0; + while ((c = getopt_long(argc, argv, "c:d:f:e:uib:x:y:", long_options, &option_index)) != -1) + { + switch (c) + { + case 'c': + configName = optarg; + break; + + case 'd': + displayName = optarg; + break; + + case 'f': + fontName = optarg; + break; + + case 'e': + encoding = optarg; + break; + + case 'u': + upsideDown = true; + break; + + case 'i': + invert = true; + break; + + case 'b': + brightness = atoi(optarg); + if (brightness < 0) brightness = 0; + if (brightness > 100) brightness = 100; + break; + + case 'x': + x = atoi(optarg); + break; + + case 'y': + y = atoi(optarg); + break; + + default: + usage(); + return 1; + } + } + + if (configName.length() == 0) + { + configName = kDefaultConfigFile; + fprintf(stdout, "WARNING: No config file specified, using default (%s).\n", configName.c_str()); + } + + if (GLCD::Config.Load(configName) == false) + { + fprintf(stderr, "Error loading config file!\n"); + return 2; + } + if (GLCD::Config.driverConfigs.size() > 0) + { + if (displayName.length() > 0) + { + for (displayNumber = 0; displayNumber < GLCD::Config.driverConfigs.size(); displayNumber++) + { + if (GLCD::Config.driverConfigs[displayNumber].name == displayName) + break; + } + if (displayNumber == GLCD::Config.driverConfigs.size()) + { + fprintf(stderr, "ERROR: Specified display %s not found in config file!\n", displayName.c_str()); + return 3; + } + } + else + { + fprintf(stdout, "WARNING: No display specified, using first one.\n"); + displayNumber = 0; + } + } + else + { + fprintf(stderr, "ERROR: No displays specified in config file!\n"); + return 4; + } + + if (encoding.length() == 0) + { + encoding = "iso8859-1"; + fprintf(stdout, "WARNING: No encoding specified, using default (%s).\n", encoding.c_str()); + } + + if (fontName.length() == 0) + { + fprintf(stderr, "Error: No font specified!\n"); + return 5; + } + if (fontName.find("fnt:") == 0) + { + fontType = kFontFNT; + fontFileName = fontName.substr(4); + } + else if (fontName.find("ft2:") == 0) + { + fontType = kFontFT2; + std::string::size_type pos = fontName.find(":", 4); + if (pos == std::string::npos) + { + fontSize = 16; + fprintf(stdout, "WARNING: No font size specified, using default (%d).\n", fontSize); + fontFileName = fontName.substr(4); + } + else + { + std::string tmp = fontName.substr(pos + 1); + fontSize = atoi(tmp.c_str()); + fontFileName = fontName.substr(4, pos - 4); + } + } + else + { + fprintf(stderr, "Error: Unknown font type!\n"); + return 6; + } + + if (optind == argc) + { + usage(); + fprintf(stderr, "ERROR: You have to specify a text\n"); + return 7; + } + + GLCD::Config.driverConfigs[displayNumber].upsideDown ^= upsideDown; + GLCD::Config.driverConfigs[displayNumber].invert ^= invert; + if (brightness != -1) + GLCD::Config.driverConfigs[displayNumber].brightness = brightness; + + GLCD::cFont font; + if (fontType == kFontFNT) + { + if (font.LoadFNT(fontFileName) == false) + { + fprintf(stderr, "ERROR: Failed loading font file %s\n", fontFileName.c_str()); + return 8; + } + } + else + { + if (font.LoadFT2(fontFileName, encoding, fontSize) == false) + { + fprintf(stderr, "ERROR: Failed loading font file %s\n", fontFileName.c_str()); + return 8; + } + } + GLCD::cDriver * lcd = GLCD::CreateDriver(GLCD::Config.driverConfigs[displayNumber].id, &GLCD::Config.driverConfigs[displayNumber]); + if (!lcd) + { + fprintf(stderr, "ERROR: Failed creating display object %s\n", displayName.c_str()); + return 9; + } + if (lcd->Init() != 0) + { + fprintf(stderr, "ERROR: Failed initializing display %s\n", displayName.c_str()); + delete lcd; + return 10; + } + + GLCD::cBitmap * bitmap = new GLCD::cBitmap(lcd->Width(), lcd->Height()); + int optText; + std::string text; + + bitmap->Clear(); + optText = optind; + while (optText < argc) + { + text = argv[optText]; + optText++; + + bitmap->DrawText(x, y, bitmap->Width() - 1, text, &font); + y += font.LineHeight(); + } + lcd->SetScreen(bitmap->Data(), bitmap->Width(), bitmap->Height(), bitmap->LineSize()); + lcd->Refresh(true); + + lcd->DeInit(); + delete lcd; + + return 0; +}