Initial import start
authorChris Tallon <chris@vomp.tv>
Tue, 28 Jun 2005 22:16:29 +0000 (22:16 +0000)
committerChris Tallon <chris@vomp.tv>
Tue, 28 Jun 2005 22:16:29 +0000 (22:16 +0000)
117 files changed:
COPYING [new file with mode: 0644]
Makefile [new file with mode: 0644]
afeed.cc [new file with mode: 0644]
afeed.h [new file with mode: 0644]
afeedr.cc [new file with mode: 0644]
afeedr.h [new file with mode: 0644]
audio.cc [new file with mode: 0644]
audio.h [new file with mode: 0644]
bogl.h [new file with mode: 0644]
box.cc [new file with mode: 0644]
box.h [new file with mode: 0644]
callback.h [new file with mode: 0644]
channel.cc [new file with mode: 0644]
channel.h [new file with mode: 0644]
command.cc [new file with mode: 0644]
command.h [new file with mode: 0644]
defines.h [new file with mode: 0644]
demuxer.cc [new file with mode: 0644]
demuxer.h [new file with mode: 0644]
directory.cc [new file with mode: 0644]
directory.h [new file with mode: 0644]
dsock.cc [new file with mode: 0644]
dsock.h [new file with mode: 0644]
fonts/helvB18-ISO8859-1.pcf [new file with mode: 0644]
fonts/helvB18.bdf [new file with mode: 0644]
fonts/helvB18.cc [new file with mode: 0644]
fonts/helvB24-ISO8859-1.pcf [new file with mode: 0644]
fonts/helvB24.bdf [new file with mode: 0644]
fonts/helvB24.cc [new file with mode: 0644]
fonts/licence.txt [new file with mode: 0644]
led.cc [new file with mode: 0644]
led.h [new file with mode: 0644]
list.cc [new file with mode: 0644]
list.h [new file with mode: 0644]
log.cc [new file with mode: 0644]
log.h [new file with mode: 0644]
main.cc [new file with mode: 0644]
message.cc [new file with mode: 0644]
message.h [new file with mode: 0644]
messagequeue.cc [new file with mode: 0644]
messagequeue.h [new file with mode: 0644]
mtd.cc [new file with mode: 0644]
mtd.h [new file with mode: 0644]
node.cc [new file with mode: 0644]
node.h [new file with mode: 0644]
osd.cc [new file with mode: 0644]
osd.h [new file with mode: 0644]
other/licence.txt [new file with mode: 0644]
other/vdr.jpg [new file with mode: 0644]
other/wallpaper.jpg [new file with mode: 0644]
player.cc [new file with mode: 0644]
player.h [new file with mode: 0644]
playerradio.cc [new file with mode: 0644]
playerradio.h [new file with mode: 0644]
queue.cc [new file with mode: 0644]
queue.h [new file with mode: 0644]
recording.cc [new file with mode: 0644]
recording.h [new file with mode: 0644]
remote.cc [new file with mode: 0644]
remote.h [new file with mode: 0644]
stb.h [new file with mode: 0644]
stream.cc [new file with mode: 0644]
stream.h [new file with mode: 0644]
surface.cc [new file with mode: 0644]
surface.h [new file with mode: 0644]
tcp.cc [new file with mode: 0644]
tcp.h [new file with mode: 0644]
thread.cc [new file with mode: 0644]
thread.h [new file with mode: 0644]
vchannellist.cc [new file with mode: 0644]
vchannellist.h [new file with mode: 0644]
vchannelselect.cc [new file with mode: 0644]
vchannelselect.h [new file with mode: 0644]
vdr.cc [new file with mode: 0644]
vdr.h [new file with mode: 0644]
vfeed.cc [new file with mode: 0644]
vfeed.h [new file with mode: 0644]
video.cc [new file with mode: 0644]
video.h [new file with mode: 0644]
view.cc [new file with mode: 0644]
view.h [new file with mode: 0644]
viewman.cc [new file with mode: 0644]
viewman.h [new file with mode: 0644]
vinfo.cc [new file with mode: 0644]
vinfo.h [new file with mode: 0644]
vlivebanner.cc [new file with mode: 0644]
vlivebanner.h [new file with mode: 0644]
vmute.cc [new file with mode: 0644]
vmute.h [new file with mode: 0644]
vquestion.cc [new file with mode: 0644]
vquestion.h [new file with mode: 0644]
vradiolive.cc [new file with mode: 0644]
vradiolive.h [new file with mode: 0644]
vrecordinglist.cc [new file with mode: 0644]
vrecordinglist.h [new file with mode: 0644]
vrecordingmenu.cc [new file with mode: 0644]
vrecordingmenu.h [new file with mode: 0644]
vserverselect.cc [new file with mode: 0644]
vserverselect.h [new file with mode: 0644]
vvideolive.cc [new file with mode: 0644]
vvideolive.h [new file with mode: 0644]
vvideorec.cc [new file with mode: 0644]
vvideorec.h [new file with mode: 0644]
vvolume.cc [new file with mode: 0644]
vvolume.h [new file with mode: 0644]
vwallpaper.cc [new file with mode: 0644]
vwallpaper.h [new file with mode: 0644]
vwelcome.cc [new file with mode: 0644]
vwelcome.h [new file with mode: 0644]
wbutton.cc [new file with mode: 0644]
wbutton.h [new file with mode: 0644]
wjpeg.cc [new file with mode: 0644]
wjpeg.h [new file with mode: 0644]
wselectlist.cc [new file with mode: 0644]
wselectlist.h [new file with mode: 0644]
wsymbol.cc [new file with mode: 0644]
wsymbol.h [new file with mode: 0644]

diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..3912109
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  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.
+\f
+                   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.)
+\f
+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.
+\f
+  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.
+\f
+  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
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..aae4319
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,47 @@
+CC = /opt/crosstool/powerpc-405-linux-gnu/gcc-2.95.3-glibc-2.2.5/bin/powerpc-405-linux-gnu-g++
+STRIP = /opt/crosstool/powerpc-405-linux-gnu/gcc-2.95.3-glibc-2.2.5/bin/powerpc-405-linux-gnu-strip
+CXX = $(CC)
+INCLUDES = -I../jpeg-6b
+CXXFLAGS = -Wall -Woverloaded-virtual -Werror $(INCLUDES)
+LDFLAGS = -Wall -static
+
+LIBPATHS =
+LIBS = -lpthread -lrt
+CROSSLIBS = ../jpeg-6b/libjpeg.a
+
+OBJECTS = main.o command.o log.o remote.o led.o mtd.o video.o audio.o tcp.o directory.o thread.o \
+          player.o demuxer.o stream.o vfeed.o afeed.o afeedr.o osd.o surface.o viewman.o vdr.o dsock.o box.o \
+          list.o queue.o node.o recording.o channel.o message.o playerradio.o messagequeue.o \
+          view.o vinfo.o vwallpaper.o vvolume.o vrecordinglist.o vlivebanner.o vmute.o \
+          vrecordingmenu.o vquestion.o vchannellist.o vwelcome.o vvideolive.o vvideorec.o vradiolive.o \
+          vchannelselect.o vserverselect.o \
+          wselectlist.o wjpeg.o wsymbol.o wbutton.o \
+          fonts/helvB24.o fonts/helvB18.o
+
+.PHONY: clean fresh all install strip
+
+default: vompclient
+fresh:   clean all
+all:     vompclient
+
+clean:
+       rm -f *.o deps vompclient test *~ fonts/*.o fonts/*~
+
+vompclient: $(OBJECTS)
+       $(CC) $(LDFLAGS) $(LIBPATHS) -o vompclient $(OBJECTS) $(CROSSLIBS) $(LIBS)
+
+strip:
+       $(STRIP) vompclient
+
+install:
+       rm /diskless/nfs/mvp/vompclient
+       cp vompclient /diskless/nfs/mvp
+
+dongle: strip
+       cp vompclient ../dongle
+       cd ../dongle ; ./go
+
+deps: Makefile
+       $(CC) -MM $(INCLUDES) $(OBJECTS:%.o=%.cc) > deps
+
+-include deps
diff --git a/afeed.cc b/afeed.cc
new file mode 100644 (file)
index 0000000..bfdfe1c
--- /dev/null
+++ b/afeed.cc
@@ -0,0 +1,92 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "afeed.h"
+
+AFeed::AFeed(Callback* tcb)
+: cb(*tcb)
+{
+  delayTime.tv_sec = 0;
+  delayTime.tv_nsec = 100000000;
+  audioEnabled = 1;
+}
+
+int AFeed::init(int tfd)
+{
+  fd = tfd;
+  return 1;
+}
+
+int AFeed::shutdown()
+{
+  // FIXME
+  return 1;
+}
+
+void AFeed::disable()
+{
+  audioEnabled = 0;
+}
+
+void AFeed::enable()
+{
+  audioEnabled = 1;
+}
+
+int AFeed::start()
+{
+  return threadStart();
+}
+
+void AFeed::stop()
+{
+  threadCancel();
+}
+
+void AFeed::threadMethod()
+{
+  Log::getInstance()->log("AFeed", Log::DEBUG, "Started");
+
+  int alen;
+
+  while(1)
+  {
+    if (audioEnabled)
+    {
+      alen = Demuxer::getInstance()->writeAudio(fd); // FIXME ?
+
+      if (alen)
+      {
+        Log::getInstance()->log("AFeed", Log::DEBUG, "Written %i", alen);
+        cb.call();
+      }
+      else
+      {
+        nanosleep(&delayTime, NULL);
+      }
+    }
+    else
+    {
+      Demuxer::getInstance()->flushAudio(); // FIXME, no delay here now
+//      if (demux_get_audio(demuxHandle, buffer, 1000) != 1000) nanosleep(&delayTime, NULL);
+    }
+  }
+}
+
diff --git a/afeed.h b/afeed.h
new file mode 100644 (file)
index 0000000..b858e96
--- /dev/null
+++ b/afeed.h
@@ -0,0 +1,54 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef AFEED_H
+#define AFEED_H
+
+#include <stdio.h>
+#include <time.h>
+
+#include "log.h"
+#include "thread.h"
+#include "demuxer.h"
+#include "callback.h"
+
+class AFeed : public Thread
+{
+  public:
+    AFeed(Callback* tcb);
+
+    int init(int fd);
+    int shutdown();
+
+    int start();
+    void stop();
+    void enable();
+    void disable();
+
+  private:
+    void threadMethod();
+    int audioEnabled;
+    int fd;
+    Callback& cb;
+    struct timespec delayTime;
+
+};
+
+#endif
diff --git a/afeedr.cc b/afeedr.cc
new file mode 100644 (file)
index 0000000..1dd8a01
--- /dev/null
+++ b/afeedr.cc
@@ -0,0 +1,73 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "afeedr.h"
+
+AFeedR::AFeedR(Callback* tcb, Stream* tstream)
+: cb(*tcb), stream(*tstream)
+{
+  delayTime.tv_sec = 0;
+  delayTime.tv_nsec = 100000000;
+}
+
+int AFeedR::init(int tfd)
+{
+  fd = tfd;
+  return 1;
+}
+
+int AFeedR::shutdown()
+{
+  // FIXME
+  return 1;
+}
+
+int AFeedR::start()
+{
+  return threadStart();
+}
+
+void AFeedR::stop()
+{
+  threadCancel();
+}
+
+void AFeedR::threadMethod()
+{
+  Log::getInstance()->log("AFeedR", Log::DEBUG, "Started");
+
+  int alen;
+
+  while(1)
+  {
+    alen = stream.drain(fd);
+
+    if (alen)
+    {
+      Log::getInstance()->log("AFeedR", Log::DEBUG, "Written %i", alen);
+      cb.call();
+    }
+    else
+    {
+      nanosleep(&delayTime, NULL);
+    }
+  }
+}
+
diff --git a/afeedr.h b/afeedr.h
new file mode 100644 (file)
index 0000000..eb94db2
--- /dev/null
+++ b/afeedr.h
@@ -0,0 +1,52 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef AFEEDR_H
+#define AFEEDR_H
+
+#include <stdio.h>
+#include <time.h>
+
+#include "log.h"
+#include "thread.h"
+#include "callback.h"
+#include "stream.h"
+
+class AFeedR : public Thread
+{
+  public:
+    AFeedR(Callback* tcb, Stream* tstream);
+
+    int init(int fd);
+    int shutdown();
+
+    int start();
+    void stop();
+
+  private:
+    void threadMethod();
+    int fd;
+    Callback& cb;
+    Stream& stream;
+    struct timespec delayTime;
+
+};
+
+#endif
diff --git a/audio.cc b/audio.cc
new file mode 100644 (file)
index 0000000..bacdc8f
--- /dev/null
+++ b/audio.cc
@@ -0,0 +1,281 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "audio.h"
+
+Audio* Audio::instance = NULL;
+
+Audio::Audio()
+{
+  if (instance) return;
+  instance = this;
+  initted = 0;
+  fdAudio = 0;
+  streamType = 0;
+  volume = 20;
+  muted = 0;
+  userMute = 0;
+  systemMute = 0;
+}
+
+Audio::~Audio()
+{
+  instance = NULL;
+}
+
+Audio* Audio::getInstance()
+{
+  return instance;
+}
+
+int Audio::init(UCHAR streamType)
+{
+  if (initted) return 0;
+  initted = 1;
+
+//  if ((fdAudio = open("/dev/adec_mpg", O_RDWR | O_NONBLOCK)) < 0) return 0;
+  if ((fdAudio = open("/dev/adec_mpg", O_WRONLY)) < 0) return 0;
+
+  this->streamType = streamType;
+
+  if (!initAllParams())
+  {
+    shutdown();
+    return 0;
+  }
+
+  unMute();
+
+  return 1;
+}
+
+int Audio::initAllParams()
+{
+  return (setStreamType(streamType) && setChannel() && setSource());
+}
+
+int Audio::shutdown()
+{
+  if (!initted) return 0;
+  initted = 0;
+  close(fdAudio);
+  return 1;
+}
+
+int Audio::getFD()
+{
+  if (!initted) return 0;
+
+  return fdAudio;
+}
+
+int Audio::write(char *buf, int len)
+{
+  return 0; //write(fdAudio, buf, len);
+}
+
+int Audio::setStreamType(UCHAR type)
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdAudio, AV_SET_AUD_STREAMTYPE, type) != 0) return 0;
+  return 1;
+}
+
+int Audio::setChannel()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdAudio, AV_SET_AUD_CHANNEL, 0) != 0) return 0;
+  return 1;
+}
+
+int Audio::setSource()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdAudio, AV_SET_AUD_SRC, 1) != 0) return 0;
+  return 1;
+}
+
+int Audio::sync()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdAudio, AV_SET_AUD_SYNC, 2) != 0) return 0;
+  return 1;
+}
+
+int Audio::play()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
+  return 1;
+}
+
+int Audio::stop()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
+  return 1;
+}
+
+int Audio::mute()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdAudio, AV_SET_AUD_MUTE, 1) != 0) return 0;
+  Log::getInstance()->log("Audio", Log::DEBUG, "MUTE MUTE MUTE");
+
+  muted = 1;
+  return 1;
+}
+
+int Audio::unMute()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdAudio, AV_SET_AUD_MUTE, 0) != 0) return 0;
+  Log::getInstance()->log("Audio", Log::DEBUG, "MUTE OFF OFF OFF");
+
+  muted = 0;
+  return 1;
+}
+
+int Audio::pause()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdAudio, AV_SET_AUD_PAUSE, 1) != 0) return 0;
+  return 1;
+}
+
+int Audio::unPause()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdAudio, AV_SET_AUD_UNPAUSE, 1) != 0) return 0;
+  return 1;
+}
+
+int Audio::reset()
+{
+  if (!initted) return 0;
+//test();
+  if (ioctl(fdAudio, AV_SET_AUD_RESET, 0x11) != 0) return 0;
+  if (ioctl(fdAudio, AV_SET_AUD_PLAY, 0) != 0) return 0;
+
+  doMuting();
+  return 1;
+}
+
+int Audio::setVolume(int volume)
+{
+  // parameter: 0 for silence, 20 for full
+
+  if ((volume < 0) || (volume > 20)) return 0;
+
+  volume = 2 * (20 - volume);
+
+  unsigned long vol = (volume << 24) | (volume << 16);
+
+  Log::getInstance()->log("Audio", Log::DEBUG, "%lx", vol);
+  Log::getInstance()->log("Audio", Log::DEBUG, "%i", volume);
+
+  if (ioctl(fdAudio, AV_SET_AUD_VOLUME, &vol) != 0) return 0;
+  return 1;
+}
+
+int Audio::test()
+{
+  ULLONG stc = 0;
+  return ioctl(fdAudio, AV_SET_AUD_STC, &stc);
+}
+
+int Audio::volumeUp()
+{
+  if (!initted) return 0;
+  if (volume == 20) return volume;
+  volume++;
+  setVolume(volume);
+  return volume;
+}
+
+int Audio::volumeDown()
+{
+  if (!initted) return 0;
+  if (volume == 0) return 0;
+  volume--;
+  setVolume(volume);
+  return volume;
+}
+
+int Audio::getVolume()
+{
+  if (!initted) return 0;
+  return volume;
+}
+
+int Audio::toggleUserMute()
+{
+  if (!initted) return 0;
+
+  if (userMute)
+  {
+    userMute = 0;
+  }
+  else
+  {
+    userMute = 1;
+  }
+
+  doMuting();
+
+  return userMute;
+}
+
+int Audio::systemMuteOn()
+{
+  systemMute = 1;
+  return doMuting();
+}
+
+int Audio::systemMuteOff()
+{
+  systemMute = 0;
+  return doMuting();
+}
+
+int Audio::doMuting()
+{
+  Log::getInstance()->log("Audio", Log::DEBUG, "doMuting: user=%i sys=%i", userMute, systemMute);
+
+
+  if (userMute || systemMute)
+  {
+    return mute();
+  }
+  else
+  {
+    return unMute();
+  }
+}
diff --git a/audio.h b/audio.h
new file mode 100644 (file)
index 0000000..190513e
--- /dev/null
+++ b/audio.h
@@ -0,0 +1,89 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+// Thanks to Jon Gettler and BtB for all the ioctl information
+
+#ifndef AUDIO_H
+#define AUDIO_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include "defines.h"
+#include "log.h"
+#include "stb.h"
+
+class Audio
+{
+  public:
+    Audio();
+    ~Audio();
+    static Audio* getInstance();
+
+    int init(UCHAR streamType);
+    int shutdown();
+
+    // Audio stream type
+    const static UCHAR MPEG2_PES = 2;
+    const static UCHAR MPEG1_PES = 3; // unused
+
+    int setStreamType(UCHAR streamType);
+    int setChannel();
+    int setSource();
+    int sync();
+    int play();
+    int stop();
+    int pause();
+    int unPause();
+    int reset();
+    int setVolume(int volume);
+    int volumeUp();
+    int volumeDown();
+    int getVolume();
+    int toggleUserMute();
+    int systemMuteOn();
+    int systemMuteOff();
+    int test();
+
+    int write(char *buf, int len);
+
+    int getFD();
+
+    int doMuting();
+  private:
+    static Audio* instance;
+    int initted;
+    int volume;
+    UCHAR muted;
+    UCHAR userMute;
+    UCHAR systemMute;
+
+    int mute();
+    int unMute();
+    int initAllParams();
+
+    UCHAR streamType;
+
+    int fdAudio;
+};
+
+#endif
diff --git a/bogl.h b/bogl.h
new file mode 100644 (file)
index 0000000..be7a623
--- /dev/null
+++ b/bogl.h
@@ -0,0 +1,17 @@
+#ifndef BOGL_H
+#define BOGL_H
+
+/*
+ * This header file is here for font .c files that are created with the
+ * bdftobogl utility that comes with bogl.
+ */
+
+typedef struct bogl_font {
+  char *name;     /* Font name. */
+  int height;     /* Height in pixels. */
+  unsigned long *content;   /* 32-bit right-padded bitmap array. */
+  short *offset;      /* 256 offsets into content. */
+  unsigned char *width;   /* 256 character widths. */
+} osd_font_t;
+
+#endif /* BOGL_H */
diff --git a/box.cc b/box.cc
new file mode 100644 (file)
index 0000000..b15980b
--- /dev/null
+++ b/box.cc
@@ -0,0 +1,192 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "box.h"
+
+char Box::numBoxes = 0;
+
+Box::Box()
+{
+  height = 0;
+  width = 0;
+  screenX = 0;
+  screenY = 0;
+
+  numBoxes++;
+  Log::getInstance()->log("Box", Log::DEBUG, "Construct, now %u", numBoxes);
+
+  surface = Surface::getObject(Surface::BUFFER);
+}
+
+Box::~Box()
+{
+  numBoxes--;
+  Log::getInstance()->log("Box", Log::DEBUG, "Destruct, now %u", numBoxes);
+}
+
+void Box::draw()
+{
+}
+
+void Box::setDimensions(int h, int w)
+{
+  height = h;
+  width = w;
+}
+
+void Box::setScreenPos(int x, int y)
+{
+  screenX = x;
+  screenY = y;
+}
+
+void Box::show()
+{
+  Log::getInstance()->log("Box", Log::DEBUG, "Show data %u %u %u %u", screenX, screenY, width, height);
+  surface->updateToScreen(screenX, screenY, width, height);
+}
+
+void Box::showAll()
+{
+  Surface::bufferToScreen();
+}
+
+int Box::getScreenX()
+{
+  return screenX;
+}
+
+int Box::getScreenY()
+{
+  return screenY;
+}
+
+int Box::getWidth()
+{
+  return width;
+}
+
+int Box::getHeight()
+{
+  return height;
+}
+
+// Level 1 drawing functions
+
+void Box::fillColour(int r, int g, int b, int a)
+{
+  rectangle(0, 0, width, height, r, g, b, a);
+}
+
+void Box::drawPara(char* text, int x, int y, int r, int g, int b)
+{
+  char line[256];
+  int lineHeight = surface->getFontHeight() + 6;
+
+  int lineWidth;
+  int thisCharWidth;
+  int textPos;
+  int linePos;
+  int ypos;
+  int printLine;
+
+  textPos = 0;
+  ypos = y;
+
+  while(1)
+  {
+    linePos = 0;
+    lineWidth = 0;
+    while(1)
+    {
+      printLine = 0;
+
+      if (text[textPos] == '\0') break;
+
+      if (text[textPos] == '\n')
+      {
+        textPos++; // ignore the \n
+        printLine = 1;
+        break;
+      }
+
+      thisCharWidth = surface->getCharWidth(text[textPos]);
+      if ((lineWidth + thisCharWidth) > (width - (2 * paraMargin)))
+      {
+        // this character would break the right margin
+        if (text[textPos] == ' ')
+        {
+          // this char is a space, ignore and break
+          textPos++;
+          break;
+        }
+        else
+        {
+          // Need to go back to the last space in the line
+          while ((text[textPos] != ' ') && (linePos >= 0))
+          {
+            textPos--;
+            linePos--;
+          }
+          // Now take the space we just found
+          textPos++;
+          break;
+        }
+      }
+      line[linePos++] = text[textPos];
+      lineWidth += thisCharWidth;
+      textPos++;
+    }
+
+    line[linePos++] = '\0';
+    if (printLine || (linePos > 1)) // if some text was put in line
+    {
+      drawText(line, x, ypos, r, g, b);
+      ypos += lineHeight;
+      if (ypos > (height - lineHeight)) break;
+    }
+    else
+    {
+      break;
+    }
+  }
+}
+
+// Level 0 drawing functions
+
+void Box::rectangle(int x1, int y1, int width, int height, int r, int g, int b, int a)
+{
+  surface->fillblt(screenX + x1, screenY + y1, width, height, surface->rgba(r, g, b, a));
+}
+
+void Box::drawText(char* text, int x, int y, int r, int g, int b)
+{
+  surface->drawText(text, screenX + x, screenY + y, r, g, b);
+}
+
+void Box::drawTextRJ(char* text, int x, int y, int r, int g, int b)
+{
+  surface->drawTextRJ(text, screenX + x, screenY + y, r, g, b);
+}
+
+void Box::drawPixel(int x, int y, int c)
+{
+  surface->drawPixel(screenX + x, screenY + y, c);
+}
diff --git a/box.h b/box.h
new file mode 100644 (file)
index 0000000..ee80e49
--- /dev/null
+++ b/box.h
@@ -0,0 +1,75 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef BOX_H
+#define BOX_H
+
+#include <stdio.h>
+
+#include "log.h"
+#include "surface.h"
+
+// Abstract ???????
+class Box
+{
+  public:
+    Box();
+    virtual ~Box();
+
+    void setScreenPos(int x, int y);
+    void setDimensions(int h, int w);
+    void show();
+
+    virtual void draw();
+
+    // Drawing functions level 1
+    void fillColour(int r, int g, int b, int a);
+    void drawPara(char* text, int x, int y, int r, int g, int b);
+
+    // Drawing functions level 0
+    void rectangle(int x1, int y1, int x2, int y2, int r, int g, int b, int a);
+    void drawText(char* text, int x, int y, int r, int g, int b);
+    void drawTextRJ(char* text, int x, int y, int r, int g, int b);
+    void drawPixel(int x, int y, int c);
+
+    int getScreenX();
+    int getScreenY();
+    int getWidth();
+    int getHeight();
+
+    static void showAll();
+
+  private:
+
+  protected:
+    Surface* surface;
+    int width;
+    int height;
+
+    int screenX;
+    int screenY;
+
+    static char numBoxes;
+
+    static const int paraMargin = 10;
+
+};
+
+#endif
diff --git a/callback.h b/callback.h
new file mode 100644 (file)
index 0000000..3fbc2e0
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef CALLBACK_H
+#define CALLBACK_H
+
+class Callback
+{
+  public:
+    virtual void call()=0;
+};
+
+#endif
diff --git a/channel.cc b/channel.cc
new file mode 100644 (file)
index 0000000..cc01b23
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "channel.h"
+
+Channel::Channel()
+{
+  number = 0;
+  type = 0;
+  name = NULL;
+
+  index = -1;
+}
+
+Channel::~Channel()
+{
+  if (name) delete[] name;
+  index = -1; // just in case
+}
diff --git a/channel.h b/channel.h
new file mode 100644 (file)
index 0000000..e17bdd3
--- /dev/null
+++ b/channel.h
@@ -0,0 +1,41 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef CHANNEL_H
+#define CHANNEL_H
+
+#include <stdio.h>
+
+#include "defines.h"
+
+class Channel
+{
+  public:
+    Channel();
+    ~Channel();
+
+    ULONG number;
+    ULONG type;
+    char* name;
+
+    int index;
+};
+
+#endif
diff --git a/command.cc b/command.cc
new file mode 100644 (file)
index 0000000..f438d88
--- /dev/null
@@ -0,0 +1,393 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "command.h"
+
+Command* Command::instance = NULL;
+
+Command::Command()
+{
+  if (instance) return;
+  instance = this;
+  initted = 0;
+  state = 0;
+}
+
+Command::~Command()
+{
+  instance = NULL;
+}
+
+Command* Command::getInstance()
+{
+  return instance;
+}
+
+int Command::init()
+{
+  if (initted) return 0;
+  initted = 1;
+
+  logger = Log::getInstance();
+  viewman = ViewMan::getInstance();
+  remote = Remote::getInstance();
+
+  if (!logger || !viewman || !remote)
+  {
+    initted = 0;
+    return 0;
+  }
+
+  return 1;
+}
+
+int Command::shutdown()
+{
+  if (!initted) return 0;
+  initted = 0;
+  return 1;
+}
+
+void Command::stop()
+{
+  VDR::getInstance()->cancelFindingServer();
+  irun = 0;
+}
+
+void Command::run()
+{
+  if (!initted) return;
+  irun = 1;
+
+  mainPid = getpid();
+
+  // moved from startup because surface delete doesn't work
+
+  // just in case
+  Video::getInstance()->signalOn();
+  Led::getInstance()->on();
+
+  // Blue background
+  View* v = new View();
+  v->setDimensions(SCREENHEIGHT, SCREENWIDTH);
+  v->setBackgroundColour(0, 0, 150, 255);
+  v->draw();
+  v->show();
+  viewman->add(v);
+  viewman->removeView(v);
+
+  // Wallpaper
+  VWallpaper* w = new VWallpaper();
+  w->init("/wallpaper.jpg");
+  w->draw();
+  w->show();
+  viewman->add(w);
+
+
+//  handleCommand(Remote::TWO);
+//  handleCommand(Remote::UP);
+//  handleCommand(Remote::PLAY);
+
+//  handleCommand(Remote::DOWN);
+//  handleCommand(Remote::OK);
+
+//  handleCommand(Remote::DOWN);
+//  handleCommand(Remote::DOWN);
+//  handleCommand(Remote::DOWN);
+//  handleCommand(Remote::OK);
+
+  // state values:
+  // 0 = not connected
+  // 1 = got servers
+  // 2 = multiple servers, showing select box
+  // 3 = a server has been selected
+  // 4 = connected
+  // 5 = standby
+
+  int selectServer;
+  UCHAR button = 0;
+  while(irun)
+  {
+    if (state != 4) // not really necessary, but chops out all the connecting rubbish if already connected
+    {
+      if (state == 0)
+      {
+        clearServerIPs();
+        broadcastForServers();
+        if (!irun) break;
+        state = 1;
+      }
+
+      if (state == 1)
+      {
+        if (serverIPs.size() == 1)
+        {
+          selectServer = 0;
+          state = 3;
+        }
+        else
+        {
+          selectServer = -1;
+          state = 2;
+          VServerSelect* vs = new VServerSelect(&serverIPs, &selectServer);
+          vs->draw();
+          vs->show();
+          viewman->add(vs);
+        }
+      }
+
+      if (state == 2)
+      {
+        // entering loop for 2nd time.. has a server been selected?
+        if (selectServer != -1) state = 3;
+      }
+
+      if (state == 3)
+      {
+        Log::getInstance()->log("Command", Log::DEBUG, "Server selected: %i", selectServer);
+
+        int success = connectToServer(selectServer);
+        clearServerIPs();
+
+        if (success)
+        {
+          VWelcome* vw = new VWelcome();
+          vw->draw();
+          vw->show();
+          viewman->add(vw);
+          state = 4;
+        }
+        else
+        {
+          state = 0;
+        }
+      }
+
+      if (state == 0) continue;
+      // state can't be 1
+      // if state == 2 then drop to remote handling below
+      // state can't be 3
+      // if state == 4 then drop through to main system, job done
+    }
+
+
+    button = remote->getButtonPress(2);  // FIXME why is this set to 2 and not 0? so it can quit
+    if ((button == Remote::NONE) || (button == Remote::UNKNOWN)) continue;
+
+    if (button != Remote::SIGNAL) handleCommand(button);
+    processMessageQueue();
+  }
+}
+
+void Command::postMessage(Message* m)
+{
+  MessageQueue::postMessage(m);
+  kill(mainPid, SIGURG);
+}
+
+void Command::processMessage(Message* m)
+{
+  Log::getInstance()->log("Command", Log::DEBUG, "processing message %i", m->message);
+
+  switch(m->message)
+  {
+    case Message::STANDBY:
+    {
+      doStandby();
+      break;
+    }
+    case Message::STOP_PLAYBACK:
+    {
+      handleCommand(Remote::STOP); // an odd way of doing it, but so simple
+      break;
+    }
+  }
+}
+
+void Command::clearServerIPs()
+{
+  // Clear the serverIPs vector
+  for(UINT k = 0; k < serverIPs.size(); k++)
+  {
+    delete[] serverIPs[k];
+  }
+  serverIPs.clear();
+}
+
+void Command::handleCommand(int button)
+{
+  if (state == 5 && (button != Remote::POWER)) return;
+
+  if (viewman->handleCommand(button)) return;
+
+  // command was not handled
+
+  switch(button)
+  {
+    case Remote::LEFT:
+    case Remote::RIGHT:
+    {
+      VVolume* v = new VVolume();
+      v->handleCommand(button); // this will draw+show
+      viewman->add(v);
+      viewman->timedDelete(v, 2, 1);
+      return;
+    }
+    case Remote::MUTE:
+    {
+      VMute* v = new VMute();
+      v->draw();
+      v->show();
+      viewman->add(v);
+      viewman->timedDelete(v, 2, 1);
+      return;
+    }
+    case Remote::POWER:
+    {
+      doStandby();
+      return;
+    }
+    case Remote::RECORD:
+    {
+      Osd::getInstance()->screenShot("/out.jpg");
+      return;
+    }
+  }
+}
+
+void Command::broadcastForServers()
+{
+  VInfo* viewWait = new VInfo();
+  viewWait->setDimensions(200, 400);
+  viewWait->setScreenPos(170, 200);
+  viewWait->setMainText("\n                        Locating server");
+  viewWait->draw();
+  viewWait->show();
+  viewman->add(viewWait);
+
+
+  VDR* vdr = VDR::getInstance();
+  vdr->findServers(serverIPs);
+  if (!irun) return;
+  viewman->removeView(viewWait);
+}
+
+int Command::connectToServer(int vectorIndex)
+{
+  char a[60];
+  struct timespec ts;
+
+  VDR* vdr = VDR::getInstance();
+  vdr->setServerIP(serverIPs[vectorIndex]);
+
+  logger->log("Command", Log::NOTICE, "Connecting to server at %s", serverIPs[vectorIndex]);
+
+  VInfo* viewWait = new VInfo();
+  viewWait->setDimensions(200, 400);
+  viewWait->setScreenPos(170, 200);
+  viewWait->setMainText("\n                     Connecting to VDR");
+  viewWait->draw();
+  viewWait->show();
+  viewman->add(viewWait);
+
+  int success = vdr->connect();
+
+  if (success)
+  {
+    Log::getInstance()->log("Command", Log::DEBUG, "Connected ok, doing login");
+    success = vdr->doLogin();
+
+    if (success)
+    {
+      strcpy(a, "\n                            Connected");
+      ts.tv_sec = 0;
+      ts.tv_nsec = 500000000;
+    }
+    else
+    {
+      strcpy(a, "\n                           Login failed");
+      ts.tv_sec = 3;
+      ts.tv_nsec = 0;
+    }
+  }
+  else
+  {
+    strcpy(a, "\n                      Connection failed");
+    ts.tv_sec = 3;
+    ts.tv_nsec = 0;
+  }
+
+  viewWait->setMainText(a);
+  viewWait->draw();
+  viewWait->show();
+
+  if (irun) nanosleep(&ts, NULL); // only do the wait if we aren't shutting down
+
+/*
+  vdr->configSave("Section Name This Is blah blah blah 495834509725049375032end", "thekey with this space ", "1234value");
+  sleep(10);
+
+  char* conf = vdr->configLoad("fred", "bill");
+  if (conf)
+  {
+    //printf("And the config value returned is %s\n", conf);
+    delete[] conf;
+  }
+  else
+  {
+    //printf("Conf value return is NULL :(\n");
+  }
+*/
+
+  viewman->removeView(viewWait);
+
+  return success;
+}
+
+void Command::doStandby()
+{
+  if (state == 5)
+  {
+    Video::getInstance()->signalOn();
+    Led::getInstance()->on();
+    state = 0;
+  }
+  else
+  {
+    ViewMan* viewman = ViewMan::getInstance();
+
+    viewman->removeAll();
+    viewman->redrawAll();
+
+
+    VDR::getInstance()->disconnect();
+    Video::getInstance()->signalOff();
+    Led::getInstance()->off();
+    state = 5;
+  }
+}
+
+void Command::doReboot()
+{
+  VDR::getInstance()->disconnect();
+  // just kill it...
+  logger->log("Command", Log::NOTICE, "Reboot");
+  reboot(LINUX_REBOOT_CMD_RESTART);
+}
diff --git a/command.h b/command.h
new file mode 100644 (file)
index 0000000..6cef15a
--- /dev/null
+++ b/command.h
@@ -0,0 +1,88 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef COMMAND_H
+#define COMMAND_H
+
+#include <unistd.h> // for reboot
+#include <linux/reboot.h>
+#include <sys/reboot.h>
+
+#include <time.h>
+#include <vector>
+
+#include <signal.h>
+
+#include "defines.h"
+#include "log.h"
+#include "viewman.h"
+#include "led.h"
+#include "video.h"
+#include "remote.h"
+#include "vdr.h"
+#include "list.h"
+#include "message.h"
+#include "messagequeue.h"
+#include "box.h"
+#include "view.h"
+#include "vinfo.h"
+#include "vwallpaper.h"
+#include "vvolume.h"
+#include "vserverselect.h"
+#include "vwelcome.h"
+#include "vmute.h"
+
+class Command : public MessageQueue
+{
+  public:
+    Command();
+    ~Command();
+    static Command* getInstance();
+
+    int init();
+    int shutdown();
+    void run();
+    void stop();
+    void doReboot();
+    void postMessage(Message* m); // override of MessageQueue::postMessage
+
+  private:
+    void handleCommand(int);
+    void broadcastForServers();
+    int connectToServer(int vectorIndex);
+    void doStandby();
+    void clearServerIPs();
+
+    static Command* instance;
+    pid_t mainPid;
+    UCHAR initted;
+    UCHAR irun;
+    UCHAR state;
+
+    std::vector<char*> serverIPs;
+
+    Log* logger;
+    ViewMan* viewman;
+    Remote* remote;
+
+    void processMessage(Message* m);
+};
+
+#endif
diff --git a/defines.h b/defines.h
new file mode 100644 (file)
index 0000000..8b3a337
--- /dev/null
+++ b/defines.h
@@ -0,0 +1,36 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef DEFINES_H
+#define DEFINES_H
+
+typedef unsigned char UCHAR;
+typedef unsigned short USHORT;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+typedef unsigned long long ULLONG;
+
+#define SCREENWIDTH 720
+#define SCREENHEIGHT 576
+
+ULLONG htonll(ULLONG a);
+ULLONG ntohll(ULLONG a);
+
+#endif
diff --git a/demuxer.cc b/demuxer.cc
new file mode 100644 (file)
index 0000000..b166173
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+    Copyright 2005 Mark Calderbank
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "demuxer.h"
+
+const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 };
+
+Demuxer* Demuxer::instance = NULL;
+
+Demuxer::Demuxer()
+{
+  if (instance) return;
+  instance = this;
+  initted = 0;
+}
+
+Demuxer::~Demuxer()
+{
+  shutdown();
+  instance = NULL;
+}
+
+Demuxer* Demuxer::getInstance()
+{
+  return instance;
+}
+
+int Demuxer::init()
+{
+  if (!initted)
+  {
+    if ( videostream.init(demuxMemory) ||
+         audiostream.init(demuxMemory) ||
+         !(local_frame = (UCHAR *) malloc(0x10000)))
+    {
+      printf("failed to initialize demuxer\n");
+      shutdown();
+      return 1;
+    }
+  }
+
+  reset();
+  initted = 1;
+  return 0;
+}
+
+void Demuxer::reset()
+{
+  flush();
+  video_current = audio_current = -1;
+  horizontal_size = vertical_size = 0;
+  aspect_ratio = (enum AspectRatio) 0;
+  frame_rate = bit_rate = 0;
+}
+
+int Demuxer::shutdown()
+{
+  videostream.shutdown();
+  audiostream.shutdown();
+  free(local_frame);
+  initted = 0;
+  return 1;
+}
+
+void Demuxer::flush()
+{
+  videostream.flush();
+  audiostream.flush();
+  state_frametype = state_framepos = 0;
+  seek();
+}
+
+void Demuxer::flushAudio()
+{
+  audiostream.flush();
+}
+
+void Demuxer::seek()
+{
+  seeking = 1;
+}
+
+void Demuxer::setAudioStream(int id)
+{
+  audio_current = id;
+}
+
+void Demuxer::setVideoStream(int id)
+{
+  video_current = id;
+}
+
+int Demuxer::scan(UCHAR *buf, int len)
+{
+  // Temporarily, just look for the lowest audio stream and return it
+  int ret = 0;
+  UCHAR byte;
+  int zeros = 0;
+  while (len > 1)
+  {
+    // We are searching for a string of bytes (0,0,1).
+    byte = *(buf++); --len;
+
+    if (byte == 0)
+    {
+      ++zeros; continue;
+    }
+    if (zeros < 2 || byte != 1)
+    {
+      zeros = 0; continue;
+    }
+    zeros = 0;
+    // We have found the pattern (0,0,1).
+    // Check the next byte for the sub-frame type.
+    byte = *(buf++); --len;
+    if (byte >= 0xc0 && byte <= 0xdf) // Audio
+      if (ret == 0 || ret > byte) ret = byte;
+  }
+  return ret;
+}
+
+int Demuxer::put(UCHAR* buf, int len)
+{
+  int ret = 0;    // return number of bytes consumed
+  int parsed = 0; // number of bytes parsed by sub-function
+  int full;       // sub-function sets this to tell us to exit early
+  inbuf = buf;    // Initialize buffer pointer
+
+  while (len)
+  {
+    full = 0;
+    switch (state_frametype)
+    {
+      case 0: // Search for frame
+        parsed = parse_find_frame(len);
+        break;
+      case FRAMETYPE_VID0 ... FRAMETYPE_VIDMAX:
+        parsed = parse_video_frame(len, &full);
+        break;
+      case FRAMETYPE_AUD0 ... FRAMETYPE_AUDMAX:
+        parsed = parse_audio_frame(len, &full);
+        break;
+    }
+    ret += parsed; len -= parsed;
+    if (full) // We have to exit early.
+      break; // out of while loop
+  }
+  Log::getInstance()->log(
+      "Demuxer", Log::DEBUG, "Put %d; took %d", ret + len, ret);
+  return ret;
+}
+
+int Demuxer::parse_find_frame(int len)
+{
+  int ret = 0; // return number of bytes parsed
+  UCHAR byte;
+
+  // In this function, state_framepos represents
+  // the number of fixed header bytes found so far.
+  if (state_framepos > 3 || state_framepos < 0)
+  {
+    // ERROR!
+    state_framepos = 0;
+  }
+
+  while (len)
+  {
+    byte = *inbuf++;
+    ++ret; --len;
+    switch (state_framepos)
+    {
+      case 0:
+      case 1:
+        if (byte == 0)
+          ++state_framepos;
+        else
+          state_framepos = 0;
+        break;
+      case 2:
+        if (byte == 1)
+          ++state_framepos;
+        else if (byte != 0)
+          state_framepos = 0;
+        break;
+      default:
+        state_framepos = 0; // Set initial state for the new frame
+        switch (byte)
+        {
+          case 0:
+            state_framepos = 1; // Count this as a first header byte!
+            break;
+          case FRAMETYPE_VID0 ... FRAMETYPE_VIDMAX:
+          case FRAMETYPE_AUD0 ... FRAMETYPE_AUDMAX:
+            state_frametype = byte;
+            return ret;
+        }
+        // Not a recognised frame type. Go back to Old Kent Road.
+        break;
+    }
+  }
+  return ret;
+}
+
+int Demuxer::parse_video_frame(int len, int* full)
+{
+  int ret = 0; // return number of bytes consumed
+  int stream_sent, bytes_remaining;
+
+  switch(state_framepos)
+  {
+    case 0: // Brand new video frame. Set initial states.
+      state_stream_fill = 0; state_vid_parsed = 0;
+      // Create a local copy of the frame header
+      local_frame[0] = local_frame[1] = 0; local_frame[2] = 1;
+      local_frame[3] = state_frametype;
+      // If no video stream has been set, use this one.
+      if (video_current == -1) video_current = state_frametype;
+      // Get MSB of frame length and copy to local frame.
+      frame_length = *inbuf << 8;
+      local_frame[4] = *inbuf;
+      ++inbuf; ++state_framepos; ++ret; --len;
+      if (len == 0) return ret;
+      // FALL THROUGH TO NEXT BYTE IN STREAM
+    case 1: // Get LSB of frame length and copy to local frame.
+      frame_length += *inbuf;
+      local_frame[5] = *inbuf;
+      ++inbuf; ++state_framepos; ++ret; --len;
+      if (len == 0) return ret;
+      // FALL THROUGH TO NEXT BYTE IN STREAM
+    case 2: // First data byte
+      if (len >= frame_length     // If we have the entire frame
+          && !state_vid_parsed)   // and haven't parsed it yet
+      {
+        if (video_current == state_frametype) // and we're interested
+          parse_video_details(inbuf, frame_length); // then parse it
+        state_vid_parsed = 1;
+      }
+  }
+  // We are in the frame data
+  bytes_remaining = 2 + frame_length - state_framepos;
+  if (video_current != state_frametype)
+  {
+    // We don't want this frame. Throw it away.
+    if (len >= bytes_remaining)
+    {
+      inbuf += bytes_remaining;
+      ret += bytes_remaining;
+      state_frametype = state_framepos = 0;
+      return ret;
+    }
+    else
+    {
+      inbuf += len; ret += len;
+      state_framepos += len;
+      return ret;
+    }
+  } // No fall through here
+
+  if (state_vid_parsed)
+  {
+    // We have already parsed the whole frame
+    if (seeking)   // Still not found a sync point. Throw this frame away.
+    {
+      if (len >= bytes_remaining)
+      {
+        inbuf += bytes_remaining;
+        ret += bytes_remaining;
+        state_frametype = state_framepos = 0;
+        return ret;
+      }
+      else
+      {
+        inbuf += len; ret += len; return ret;
+      }
+    } // No fall through is allowed here
+    // Send frame header to stream
+    if (state_stream_fill < 6)
+    {
+      state_stream_fill += videostream.put(local_frame,
+                                   6 - state_stream_fill);
+      if (state_stream_fill < 6)   // stream is full!
+      {
+        *full = 1; return ret;
+      }
+    }
+    // Send all frame data we have to stream
+    if (len >= bytes_remaining) len = bytes_remaining;
+    stream_sent = videostream.put(inbuf, len);
+    inbuf += stream_sent; ret += stream_sent;
+    state_framepos += stream_sent;
+    state_stream_fill += stream_sent;
+    if (stream_sent != len)   // stream is full!
+    {
+      *full = 1; return ret;
+    }
+    if (state_framepos == frame_length + 2)   // frame done
+    {
+      state_frametype = state_framepos = 0;
+    }
+    return ret;
+  } // No fall through is allowed here
+
+  // We haven't parsed the frame yet. It's arriving in pieces.
+  if (bytes_remaining)   // There is data yet to copy to local_frame
+  {
+    if (len >= bytes_remaining) len = bytes_remaining;
+    memcpy(local_frame + state_framepos + 4, inbuf, len);
+    inbuf += len; ret += len; state_framepos += len;
+    if (len < bytes_remaining)   // Not all arrived yet
+      return ret;
+    parse_video_details(local_frame+6, frame_length);
+    if (seeking) // Still not found a sync point. Ignore this frame.
+      return ret;
+  }
+  // We have the whole frame in local_frame. Send it to the stream.
+  state_stream_fill += videostream.put(local_frame,
+                  6 + frame_length - state_stream_fill);
+  if (state_stream_fill < frame_length + 6)   // stream is full!
+  {
+    *full = 1; return ret;
+  }
+  state_frametype = state_framepos = 0;
+  return ret;
+}
+
+int Demuxer::parse_audio_frame(int len, int* full)
+{
+  int ret = 0; // return number of bytes consumed
+  int stream_sent, bytes_remaining;
+
+  switch(state_framepos)
+  {
+    case 0: // Brand new audio frame. Set initial states.
+      state_stream_fill = 0;
+      // Create a local copy of the frame header
+      local_frame[0] = local_frame[1] = 0; local_frame[2] = 1;
+      local_frame[3] = state_frametype;
+      // If no audio stream has been set, use this one.
+      if (audio_current == -1) audio_current = state_frametype;
+      // Get MSB of frame length and copy to local frame.
+      frame_length = *inbuf << 8;
+      local_frame[4] = *inbuf;
+      ++inbuf; ++state_framepos; ++ret; --len;
+      if (len == 0) return ret;
+      // FALL THROUGH TO NEXT BYTE IN STREAM
+    case 1: // Get LSB of frame length and copy to local frame.
+      frame_length += *inbuf;
+      local_frame[5] = *inbuf;
+      ++inbuf; ++state_framepos; ++ret; --len;
+      if (len == 0) return ret;
+  }
+  // We are in the frame data
+  bytes_remaining = 2 + frame_length - state_framepos;
+  if (audio_current != state_frametype)
+  {
+    // We don't want this frame. Throw it away.
+    if (len >= bytes_remaining)
+    {
+      inbuf += bytes_remaining;
+      ret += bytes_remaining;
+      state_frametype = state_framepos = 0;
+      return ret;
+    }
+    else
+    {
+      inbuf += len; ret += len;
+      state_framepos += len;
+      return ret;
+    }
+  } // No fall through is allowed here
+
+  // Send frame header to stream
+  if (state_stream_fill < 6)
+  {
+    state_stream_fill += audiostream.put(local_frame,
+                                 6 - state_stream_fill);
+    if (state_stream_fill < 6) // stream is full!
+    {
+      *full = 1; return ret;
+    }
+  }
+  // Send all frame data we have to stream
+  if (len >= bytes_remaining) len = bytes_remaining;
+  stream_sent = audiostream.put(inbuf, len);
+  inbuf += stream_sent; ret += stream_sent;
+  state_framepos += stream_sent;
+  state_stream_fill += stream_sent;
+  if (stream_sent != len) // stream is full!
+  {
+    *full = 1; return ret;
+  }
+  if (state_framepos == frame_length + 2) // frame done
+  {
+    state_frametype = state_framepos = 0;
+  }
+  return ret;
+}
+
+void Demuxer::parse_video_details(UCHAR* buf, int len)
+{
+  UCHAR byte;
+  int zeros = 0;
+  while (len >= 8) // 8 is length of a GOP header
+  {
+    // We are searching for a string of bytes (0,0,1).
+    byte = *(buf++); --len;
+
+    if (byte == 0)
+    {
+      ++zeros; continue;
+    }
+    if (zeros < 2 || byte != 1)
+    {
+      zeros = 0; continue;
+    }
+    zeros = 0;
+    // We have found the pattern (0,0,1).
+    // Check the next byte for the sub-frame type.
+    byte = *(buf++); --len;
+    switch (byte)
+    {
+      case 0x00: // Picture header
+                 // 10 bits: temporal reference
+                 //  3 bits: coding type (I/P/B)
+                 //  ...
+        if (len < 2) return;
+        if ( (buf[1] & 0x38) == 0x08 ) // I-frame
+          seeking = 0;
+        buf += 4; // Minimum length of picture header
+        len -= 4;
+        break;
+      case 0xb3: // Sequence header
+                 // 12 bits: Horizontal size
+                 // 12 bits: Vertical size
+                 //  4 bits: Aspect ratio
+                 //  4 bits: Frame rate code
+                 // 18 bits: Bit rate value
+                 // ...
+        if (len < 7) return;
+        horizontal_size = ((int)buf[0] << 4) | ((int)buf[1] >> 4);
+        vertical_size = (((int)buf[1] & 0xf) << 8) | (int)buf[2];
+        aspect_ratio = (enum AspectRatio)(buf[3] >> 4);
+        frame_rate = buf[3] & 0x0f;
+        if (frame_rate >= 1 && frame_rate <= 8)
+          frame_rate = FrameRates[frame_rate];
+        else
+          frame_rate = 0;
+        bit_rate = ((int)buf[4] << 10) |
+                   ((int)buf[5] << 2) |
+                   ((int)buf[6] >> 6);
+        seeking = 0;
+        buf += 8; // Minimum length of sequence header
+        len -= 8;
+        break;
+      case 0xb8: // Group header
+                 // We're not going to bother parsing anything.
+        seeking = 0;
+        buf += 4; // Minimum length of group header
+        len -= 4;
+        break;
+    }
+  }
+}
diff --git a/demuxer.h b/demuxer.h
new file mode 100644 (file)
index 0000000..2193c8e
--- /dev/null
+++ b/demuxer.h
@@ -0,0 +1,147 @@
+/*
+    Copyright 2005 Mark Calderbank
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/*
+
+Thanks goes to Jon Gettler of the MVPMC project and Stephen Rice for
+the demuxer in mvpmc. It was used in the creation of this Demuxer,
+however, no code was copied verbatim.
+
+*/
+
+
+#ifndef DEMUXER_H
+#define DEMUXER_H
+
+#include <stdio.h>
+#include <memory.h>
+#include "stream.h"
+#include "log.h"
+#include "defines.h"
+
+class Demuxer
+{
+  public:
+    Demuxer();
+    ~Demuxer();
+    static Demuxer* getInstance();
+    int init();
+    void reset();
+    void flush();
+    void flushAudio();
+    void seek();
+    void setVideoStream(int id);
+    void setAudioStream(int id);
+    int writeAudio(int fd) { return audiostream.drain(fd); }
+    int writeVideo(int fd) { return videostream.drain(fd); }
+    int scan(UCHAR* buf, int len);
+    int put(UCHAR* buf, int len);
+
+  private:
+    static Demuxer* instance;
+    Stream videostream;
+    Stream audiostream;
+    int shutdown();
+    int initted;
+    int seeking;
+    UCHAR* inbuf;
+
+    int video_current, audio_current;
+    int state_frametype, state_framepos;
+    int state_stream_fill, state_vid_parsed;
+    int frame_length;
+    int parse_find_frame(int len);
+    int parse_video_frame(int len, int* full);
+    int parse_audio_frame(int len, int* full);
+    void parse_video_details(UCHAR* buf, int len);
+
+    UCHAR* local_frame;
+    static const int demuxMemory = 2097152;
+    static const int Demuxer::FrameRates[9];
+
+    enum FRAMETYPE
+    {
+      FRAMETYPE_AUD0 = 0xc0,
+      FRAMETYPE_AUD1,
+      FRAMETYPE_AUD2,
+      FRAMETYPE_AUD3,
+      FRAMETYPE_AUD4,
+      FRAMETYPE_AUD5,
+      FRAMETYPE_AUD6,
+      FRAMETYPE_AUD7,
+      FRAMETYPE_AUD8,
+      FRAMETYPE_AUD9,
+      FRAMETYPE_AUD10,
+      FRAMETYPE_AUD11,
+      FRAMETYPE_AUD12,
+      FRAMETYPE_AUD13,
+      FRAMETYPE_AUD14,
+      FRAMETYPE_AUD15,
+      FRAMETYPE_AUD16,
+      FRAMETYPE_AUD17,
+      FRAMETYPE_AUD18,
+      FRAMETYPE_AUD19,
+      FRAMETYPE_AUD20,
+      FRAMETYPE_AUD21,
+      FRAMETYPE_AUD22,
+      FRAMETYPE_AUD23,
+      FRAMETYPE_AUD24,
+      FRAMETYPE_AUD25,
+      FRAMETYPE_AUD26,
+      FRAMETYPE_AUD27,
+      FRAMETYPE_AUD28,
+      FRAMETYPE_AUD29,
+      FRAMETYPE_AUD30,
+      FRAMETYPE_AUD31,
+      FRAMETYPE_AUDMAX = FRAMETYPE_AUD31,
+
+      FRAMETYPE_VID0 = 0xe0,
+      FRAMETYPE_VID1,
+      FRAMETYPE_VID2,
+      FRAMETYPE_VID3,
+      FRAMETYPE_VID4,
+      FRAMETYPE_VID5,
+      FRAMETYPE_VID6,
+      FRAMETYPE_VID7,
+      FRAMETYPE_VID8,
+      FRAMETYPE_VID9,
+      FRAMETYPE_VID10,
+      FRAMETYPE_VID11,
+      FRAMETYPE_VID12,
+      FRAMETYPE_VID13,
+      FRAMETYPE_VID14,
+      FRAMETYPE_VID15,
+      FRAMETYPE_VIDMAX = FRAMETYPE_VID15
+    };
+
+    enum AspectRatio
+    {
+      ASPECT_4_3  = 2,
+      ASPECT_16_9 = 3
+    };
+
+    int horizontal_size;
+    int vertical_size;
+    enum AspectRatio aspect_ratio;
+    int frame_rate;
+    int bit_rate;
+};
+
+#endif
diff --git a/directory.cc b/directory.cc
new file mode 100644 (file)
index 0000000..b73b982
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "directory.h"
+
+ULONG Directory::totalSpace = 0;
+ULONG Directory::freeSpace = 0;
+ULONG Directory::usedPercent = 0;
+
+Directory::Directory()
+{
+  name = NULL;
+  dirList = new List();
+  recList = new List();
+
+  isRoot = 0;
+  index = -1;
+}
+
+Directory::~Directory()
+{
+  if (name) delete[] name;
+  index = -1; // just in case
+
+  if (dirList)
+  {
+    while (!dirList->isEmpty())
+    {
+      dirList->reset();
+      delete (Directory*)dirList->remove();
+    }
+
+    delete dirList;
+  }
+
+  if (recList)
+  {
+    while (!recList->isEmpty())
+    {
+      recList->reset();
+      delete (Recording*)recList->remove();
+    }
+
+    delete recList;
+  }
+}
+
+void Directory::setName(char* newName)
+{
+  name = new char[strlen(newName) + 1];
+  strcpy(name, newName);
+}
+
+Directory* Directory::getDirByName(char* dirName)
+{
+  Directory* currentDir;
+  for(dirList->reset(); (currentDir = (Directory*)dirList->getCurrent()); dirList->next())
+  {
+    if (!strcmp(dirName, currentDir->name)) return currentDir;
+  }
+  return NULL;
+}
+
+ULONG Directory::getNumRecordings()
+{
+  return recList->getNumElements();
+}
+
+// FIXME make an add function in here that adds recs to the end of the list
diff --git a/directory.h b/directory.h
new file mode 100644 (file)
index 0000000..f9d0d3c
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef DIRECTORY_H
+#define DIRECTORY_H
+
+#include <stdio.h>
+
+#include "defines.h"
+#include "list.h"
+#include "recording.h"
+
+class Directory
+{
+  public:
+    Directory();
+    ~Directory();
+
+    void setName(char* newName);
+    Directory* getDirByName(char* dirName);
+    void setFreeSpace(ULLONG);
+    ULONG getNumRecordings();
+
+    UCHAR isRoot;
+    char* name;
+
+    int index;
+
+    List* dirList;
+    List* recList;
+
+    static ULONG totalSpace;
+    static ULONG freeSpace;
+    static ULONG usedPercent;
+
+};
+
+#endif
diff --git a/dsock.cc b/dsock.cc
new file mode 100644 (file)
index 0000000..4acc89f
--- /dev/null
+++ b/dsock.cc
@@ -0,0 +1,190 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "dsock.h"
+
+DatagramSocket::DatagramSocket(short port)
+{
+  theInstance = this;
+  myPort = port;
+  addrlen = sizeof(struct sockaddr);
+
+  if ((socketnum = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+  { perror("socket"); exit(1); }
+
+  myAddr.sin_family = AF_INET;         // host byte order
+  myAddr.sin_port = htons(myPort);     // short, network byte order
+  myAddr.sin_addr.s_addr = INADDR_ANY; // auto-fill with my IP
+  memset(&(myAddr.sin_zero), 0, 8);    // zero the rest of the struct
+
+  if (bind(socketnum, (struct sockaddr *)&myAddr, addrlen) == -1)
+  { perror("bind"); exit(1); }
+
+  FD_ZERO(&readfds);
+  FD_SET(socketnum, &readfds);
+  tv.tv_sec = 0;
+  tv.tv_usec = 0;
+
+  int allowed = 1;
+  setsockopt(socketnum, SOL_SOCKET, SO_BROADCAST, &allowed, sizeof(allowed));
+}
+
+DatagramSocket::~DatagramSocket()
+{
+  close(socketnum);
+}
+
+DatagramSocket* DatagramSocket::theInstance = 0;
+DatagramSocket* DatagramSocket::getInstance(void)
+{
+  return theInstance;
+}
+
+unsigned char DatagramSocket::waitforMessage(unsigned char how)
+{
+  /* how = 0 - block
+     how = 1 - start new wait
+     how = 2 - continue wait
+  */
+
+  struct timeval* passToSelect = NULL;
+
+
+  if (how == 0)
+  {
+    passToSelect = NULL;
+  }
+  else if (how == 1)
+  {
+    tv.tv_sec = 1;
+    tv.tv_usec = 500000;
+    passToSelect = &tv;
+  }
+  else if (how == 2)
+  {
+    if ((tv.tv_sec == 0) && (tv.tv_usec == 0))  // protection in case timer = 0
+    {
+      tv.tv_sec = 1;
+      tv.tv_usec = 500000;
+    }
+    passToSelect = &tv;
+  }
+  FD_ZERO(&readfds);
+  FD_SET(socketnum, &readfds);
+
+  if (select(socketnum + 1, &readfds, NULL, NULL, passToSelect) <= 0)
+  {  return 1;  }
+
+  if ((mlength = recvfrom(socketnum, buf, MAXBUFLEN, 0,
+      (struct sockaddr *)&theirAddr, &addrlen)) == -1)
+  { perror("recvfrom"); return 0; }
+  else
+  {
+    memset(&buf[mlength], 0, MAXBUFLEN - mlength);
+    strcpy(fromIPA, inet_ntoa(theirAddr.sin_addr));
+    fromPort = ntohs(theirAddr.sin_port);
+
+    if (DSOCKDEBUG)
+    {
+      //printf("%s:%i\tIN  %i\t", fromIPA, fromPort, mlength);
+      int k;
+      for(k = 0; k < mlength; k++)
+        printf("%u ", (unsigned char)buf[k]);
+      printf("\n");
+    }
+    return 2;
+  }
+
+  /* Return 0, failure
+     Return 1, nothing happened, timer expired
+     Return 2, packet arrived (timer not expired)
+  */
+}
+
+int DatagramSocket::getDataLength(void) const
+{
+  return mlength;
+}
+
+char *DatagramSocket::getData(void)             {  return buf;  }
+char *DatagramSocket::getFromIPA(void)          {  return fromIPA;  }
+short DatagramSocket::getFromPort(void) const   {  return fromPort; }
+
+void DatagramSocket::send(char *ipa, short port, char *message, int length)
+{
+  if (DSOCKDEBUG)
+  {
+    printf("%s:%i\tOUT %i\t", ipa, port, length);
+    int k;
+    uchar l;
+    for (k = 0; k < length; k++)
+      { l = (uchar)message[k]; printf("%u ", l); }
+  }
+
+  int sentLength = 0;
+
+  theirAddr.sin_family = AF_INET;      // host byte order
+  theirAddr.sin_port = htons(port);    // short, network byte order
+  struct in_addr tad;                  // temp struct tad needed to pass to theirAddr.sin_addr
+  tad.s_addr = inet_addr(ipa);
+  theirAddr.sin_addr = tad;            // address
+  memset(&(theirAddr.sin_zero), 0, 8); // zero the rest of the struct
+
+  errno = 0;
+
+  sentLength = sendto(socketnum, message, length, 0, (struct sockaddr *)&theirAddr, addrlen);
+  if (sentLength == length)
+  {
+    if (DSOCKDEBUG) printf(" GOOD\n");
+  }
+  else
+  {
+    if (DSOCKDEBUG)
+    {
+      printf(" --BAD--");  fflush(stdout);
+    }
+    sentLength = sendto(socketnum, message, length, 0, (struct sockaddr *)&theirAddr, addrlen);
+    if (sentLength == length)
+    {
+      if (DSOCKDEBUG) printf(" GOOD\n");
+    }
+    else
+    {
+      if (DSOCKDEBUG && (sentLength != length))
+      {
+
+        printf(" -#-FAILED-#-\n");
+        printf("--------------\n");
+        printf("Sendto failure\n");
+        printf("--------------\n");
+        printf("%s:%i\tOUT %i %i ...\n", ipa, port, length, sentLength);
+        perror("Perror reports");
+        printf("errno value: %d\n", errno);
+        printf("errno translated: %s\n", strerror(errno));
+      //  printf("h_errno value: %d\n", h_errno);
+      //  printf("\nActual address: %s\n", inet_ntoa(tad));
+      //  printf("Actual port: %i\n", ntohs(theirAddr.sin_port));
+        printf("continuing...\n\n");
+
+      }
+    }
+  }
+}
+
diff --git a/dsock.h b/dsock.h
new file mode 100644 (file)
index 0000000..110c31a
--- /dev/null
+++ b/dsock.h
@@ -0,0 +1,67 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef DSOCK_H
+#define DSOCK_H
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define MAXBUFLEN 2000
+typedef unsigned char uchar;
+
+class DatagramSocket
+{
+  public:
+    DatagramSocket(short);             // port
+    ~DatagramSocket();
+    static DatagramSocket* getInstance(void);
+    unsigned char waitforMessage(unsigned char); // int =0-block =1-new wait =2-continue wait
+    int getDataLength(void) const;
+    char *getData(void);               // returns a pointer to the data
+    char *getFromIPA(void);            // returns a pointer to from IP address
+    short getFromPort(void) const;
+    void send(char *, short, char *, int); // send wants: IP Address ddn style, port,
+                                           // data, length of data
+  private:
+    const static char DSOCKDEBUG = 0;
+    static DatagramSocket* theInstance;
+    int socketnum;                  // Socket descriptor
+    short myPort;                   // My port number
+    struct sockaddr_in myAddr;      // My address
+    struct sockaddr_in theirAddr;   // User address
+    socklen_t addrlen;              // length of sockaddr struct
+    char buf[MAXBUFLEN];            // main data buffer
+    char fromIPA[20];               // from string (ip address)
+    short fromPort;                 // which port user sent on
+    int mlength;                    // length of message
+    struct timeval tv;
+    fd_set readfds;
+};
+
+#endif
diff --git a/fonts/helvB18-ISO8859-1.pcf b/fonts/helvB18-ISO8859-1.pcf
new file mode 100644 (file)
index 0000000..ad032c3
Binary files /dev/null and b/fonts/helvB18-ISO8859-1.pcf differ
diff --git a/fonts/helvB18.bdf b/fonts/helvB18.bdf
new file mode 100644 (file)
index 0000000..9df3e60
--- /dev/null
@@ -0,0 +1,4034 @@
+STARTFONT 2.1
+FONT -Adobe-Helvetica-Bold-R-Normal--18-180-75-75-P-103-ISO8859-1
+SIZE 18 75 75
+FONTBOUNDINGBOX 18 23 -1 -5
+
+STARTPROPERTIES 28
+FOUNDRY "Adobe"
+FAMILY_NAME "Helvetica"
+WEIGHT_NAME "Bold"
+SLANT "R"
+SETWIDTH_NAME "Normal"
+ADD_STYLE_NAME ""
+PIXEL_SIZE 18
+POINT_SIZE 180
+RESOLUTION_X 75
+RESOLUTION_Y 75
+SPACING "P"
+AVERAGE_WIDTH 103
+CHARSET_REGISTRY "ISO8859"
+CHARSET_ENCODING "1"
+CAP_HEIGHT 14
+X_HEIGHT 10
+FACE_NAME "Helvetica Bold"
+COPYRIGHT "Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved."
+NOTICE "Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.  "
+_DEC_DEVICE_FONTNAMES "PS=Helvetica-Bold"
+RELATIVE_SETWIDTH 50
+RELATIVE_WEIGHT 70
+FULL_NAME "Helvetica Bold"
+WEIGHT 10
+QUAD_WIDTH 11
+DEFAULT_CHAR 0
+FONT_DESCENT 5
+FONT_ASCENT 16
+ENDPROPERTIES
+
+CHARS 192
+
+STARTCHAR defaultchar
+ENCODING 0
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 13 1 0
+BITMAP
+AAA0
+0000
+8020
+0000
+8020
+0000
+8020
+0000
+8020
+0000
+8020
+0000
+AAA0
+ENDCHAR
+
+STARTCHAR space
+ENCODING 32
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+
+STARTCHAR exclam
+ENCODING 33
+SWIDTH 333 0
+DWIDTH 5 0
+BBX 3 14 1 0
+BITMAP
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+C0
+C0
+00
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR quotedbl
+ENCODING 34
+SWIDTH 474 0
+DWIDTH 8 0
+BBX 5 5 2 9
+BITMAP
+D8
+D8
+D8
+D8
+90
+ENDCHAR
+
+STARTCHAR numbersign
+ENCODING 35
+SWIDTH 556 0
+DWIDTH 11 0
+BBX 11 13 0 0
+BITMAP
+0D80
+0D80
+0D80
+7FE0
+7FE0
+1B00
+1B00
+1B00
+FFC0
+FFC0
+3600
+3600
+3600
+ENDCHAR
+
+STARTCHAR dollar
+ENCODING 36
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 16 0 -2
+BITMAP
+0800
+3E00
+7F00
+EB80
+EB80
+E800
+7800
+3E00
+0F00
+0B80
+EB80
+EB80
+7F00
+3E00
+0800
+0800
+ENDCHAR
+
+STARTCHAR percent
+ENCODING 37
+SWIDTH 889 0
+DWIDTH 16 0
+BBX 13 13 1 0
+BITMAP
+7860
+FC60
+CCC0
+CC80
+FD80
+7B00
+0200
+06F0
+0DF8
+0998
+1998
+31F8
+30F0
+ENDCHAR
+
+STARTCHAR ampersand
+ENCODING 38
+SWIDTH 722 0
+DWIDTH 14 0
+BBX 13 13 1 0
+BITMAP
+3E00
+7F00
+6300
+7300
+3E00
+7C60
+EE60
+C7E0
+C3C0
+C1C0
+E3E0
+7F70
+3E78
+ENDCHAR
+
+STARTCHAR quotesingle
+ENCODING 39
+SWIDTH 238 0
+DWIDTH 4 0
+BBX 2 5 1 9
+BITMAP
+C0
+C0
+C0
+C0
+80
+ENDCHAR
+
+STARTCHAR parenleft
+ENCODING 40
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 6 18 0 -4
+BITMAP
+1C
+38
+30
+70
+60
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+60
+70
+30
+38
+1C
+ENDCHAR
+
+STARTCHAR parenright
+ENCODING 41
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 6 18 1 -4
+BITMAP
+E0
+70
+30
+38
+18
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+18
+38
+30
+70
+E0
+ENDCHAR
+
+STARTCHAR asterisk
+ENCODING 42
+SWIDTH 389 0
+DWIDTH 9 0
+BBX 7 6 1 8
+BITMAP
+10
+D6
+7C
+38
+6C
+44
+ENDCHAR
+
+STARTCHAR plus
+ENCODING 43
+SWIDTH 584 0
+DWIDTH 11 0
+BBX 9 8 1 1
+BITMAP
+1C00
+1C00
+1C00
+FF80
+FF80
+1C00
+1C00
+1C00
+ENDCHAR
+
+STARTCHAR comma
+ENCODING 44
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 3 5 1 -2
+BITMAP
+E0
+E0
+E0
+60
+C0
+ENDCHAR
+
+STARTCHAR hyphen
+ENCODING 45
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 3 1 4
+BITMAP
+F8
+F8
+F8
+ENDCHAR
+
+STARTCHAR period
+ENCODING 46
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 3 3 1 0
+BITMAP
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR slash
+ENCODING 47
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 5 14 0 0
+BITMAP
+18
+18
+18
+10
+30
+30
+30
+20
+60
+60
+40
+C0
+C0
+C0
+ENDCHAR
+
+STARTCHAR zero
+ENCODING 48
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 13 0 0
+BITMAP
+1C00
+7F00
+7700
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+7700
+7F00
+1C00
+ENDCHAR
+
+STARTCHAR one
+ENCODING 49
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 6 13 1 0
+BITMAP
+1C
+3C
+FC
+FC
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+ENDCHAR
+
+STARTCHAR two
+ENCODING 50
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 13 0 0
+BITMAP
+3E00
+7F00
+E380
+E380
+0380
+0700
+1F00
+3E00
+7800
+7000
+E000
+FF80
+FF80
+ENDCHAR
+
+STARTCHAR three
+ENCODING 51
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 13 0 0
+BITMAP
+3E00
+7F00
+E700
+E300
+0700
+1E00
+1F00
+0780
+0380
+E380
+E780
+7F00
+3E00
+ENDCHAR
+
+STARTCHAR four
+ENCODING 52
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 13 0 0
+BITMAP
+0700
+0F00
+1F00
+3F00
+3700
+7700
+6700
+E700
+FF80
+FF80
+0700
+0700
+0700
+ENDCHAR
+
+STARTCHAR five
+ENCODING 53
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 13 0 0
+BITMAP
+FF00
+FF00
+E000
+E000
+FE00
+FF00
+E780
+0380
+0380
+E380
+E780
+FF00
+7E00
+ENDCHAR
+
+STARTCHAR six
+ENCODING 54
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 13 0 0
+BITMAP
+3E00
+7F00
+7300
+E000
+E000
+EE00
+FF00
+F380
+E380
+E380
+F380
+7F00
+3E00
+ENDCHAR
+
+STARTCHAR seven
+ENCODING 55
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 13 0 0
+BITMAP
+FF80
+FF80
+0380
+0700
+0E00
+0E00
+1C00
+1C00
+3800
+3800
+7000
+7000
+7000
+ENDCHAR
+
+STARTCHAR eight
+ENCODING 56
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 13 0 0
+BITMAP
+3E00
+7F00
+E380
+E380
+E380
+7F00
+3E00
+7700
+E380
+E380
+E380
+7F00
+3E00
+ENDCHAR
+
+STARTCHAR nine
+ENCODING 57
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 13 0 0
+BITMAP
+3E00
+7F00
+E700
+E380
+C380
+C380
+E780
+7F80
+3D80
+0380
+E700
+FF00
+7C00
+ENDCHAR
+
+STARTCHAR colon
+ENCODING 58
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 3 10 2 0
+BITMAP
+E0
+E0
+E0
+00
+00
+00
+00
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR semicolon
+ENCODING 59
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 3 12 2 -2
+BITMAP
+E0
+E0
+E0
+00
+00
+00
+00
+E0
+E0
+E0
+40
+80
+ENDCHAR
+
+STARTCHAR less
+ENCODING 60
+SWIDTH 584 0
+DWIDTH 11 0
+BBX 9 9 1 0
+BITMAP
+0380
+0F80
+3E00
+7800
+E000
+7800
+3E00
+0F80
+0380
+ENDCHAR
+
+STARTCHAR equal
+ENCODING 61
+SWIDTH 584 0
+DWIDTH 10 0
+BBX 8 6 1 2
+BITMAP
+FF
+FF
+00
+00
+FF
+FF
+ENDCHAR
+
+STARTCHAR greater
+ENCODING 62
+SWIDTH 584 0
+DWIDTH 11 0
+BBX 9 9 1 0
+BITMAP
+E000
+F800
+3E00
+0F00
+0380
+0F00
+3E00
+F800
+E000
+ENDCHAR
+
+STARTCHAR question
+ENCODING 63
+SWIDTH 611 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+7E
+FF
+E7
+E7
+0E
+1E
+1C
+38
+38
+38
+00
+38
+38
+38
+ENDCHAR
+
+STARTCHAR at
+ENCODING 64
+SWIDTH 975 0
+DWIDTH 18 0
+BBX 16 17 1 -3
+BITMAP
+07F0
+1FFC
+3C1E
+7006
+63B7
+E7F3
+C663
+CC63
+CCC3
+CCC6
+CCC6
+EFFC
+E7B8
+7000
+3C00
+1FF0
+07F0
+ENDCHAR
+
+STARTCHAR A
+ENCODING 65
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+0E00
+0E00
+1F00
+1F00
+1B00
+3B80
+3180
+3180
+71C0
+7FC0
+7FC0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR B
+ENCODING 66
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FE00
+FF80
+E3C0
+E1C0
+E1C0
+E380
+FF80
+FFC0
+E1E0
+E0E0
+E0E0
+E1E0
+FFC0
+FF00
+ENDCHAR
+
+STARTCHAR C
+ENCODING 67
+SWIDTH 722 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+0F80
+3FE0
+78E0
+7070
+F070
+E000
+E000
+E000
+E000
+F070
+7070
+78E0
+3FE0
+0F80
+ENDCHAR
+
+STARTCHAR D
+ENCODING 68
+SWIDTH 722 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+FF00
+FFC0
+E1E0
+E0E0
+E070
+E070
+E070
+E070
+E070
+E070
+E0E0
+E1E0
+FFC0
+FF00
+ENDCHAR
+
+STARTCHAR E
+ENCODING 69
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+FFC0
+FFC0
+E000
+E000
+E000
+E000
+FF80
+FF80
+E000
+E000
+E000
+E000
+FFC0
+FFC0
+ENDCHAR
+
+STARTCHAR F
+ENCODING 70
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+FFC0
+FFC0
+E000
+E000
+E000
+E000
+FF80
+FF80
+E000
+E000
+E000
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR G
+ENCODING 71
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+0F80
+3FE0
+78E0
+7070
+E070
+E000
+E000
+E3F0
+E3F0
+E070
+7070
+78F0
+3FF0
+1FB0
+ENDCHAR
+
+STARTCHAR H
+ENCODING 72
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+FFE0
+FFE0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR I
+ENCODING 73
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 3 14 1 0
+BITMAP
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR J
+ENCODING 74
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 14 0 0
+BITMAP
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+E380
+E380
+F780
+7F00
+3E00
+ENDCHAR
+
+STARTCHAR K
+ENCODING 75
+SWIDTH 722 0
+DWIDTH 14 0
+BBX 13 14 1 0
+BITMAP
+E0F0
+E1E0
+E3C0
+E780
+EF00
+FE00
+FC00
+FE00
+EF00
+E780
+E3C0
+E1E0
+E0F0
+E078
+ENDCHAR
+
+STARTCHAR L
+ENCODING 76
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+FF80
+FF80
+ENDCHAR
+
+STARTCHAR M
+ENCODING 77
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 14 1 0
+BITMAP
+E01C
+E01C
+F03C
+F03C
+F87C
+F87C
+F87C
+ECDC
+ECDC
+ECDC
+E79C
+E79C
+E31C
+E31C
+ENDCHAR
+
+STARTCHAR N
+ENCODING 78
+SWIDTH 722 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+E070
+F070
+F070
+F870
+FC70
+EC70
+EE70
+E670
+E770
+E370
+E1F0
+E1F0
+E0F0
+E070
+ENDCHAR
+
+STARTCHAR O
+ENCODING 79
+SWIDTH 778 0
+DWIDTH 16 0
+BBX 14 14 1 0
+BITMAP
+0FC0
+3FF0
+7878
+7038
+F03C
+E01C
+E01C
+E01C
+E01C
+F03C
+7038
+7878
+3FF0
+0FC0
+ENDCHAR
+
+STARTCHAR P
+ENCODING 80
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+FE00
+FF80
+E3C0
+E1C0
+E1C0
+E3C0
+FF80
+FE00
+E000
+E000
+E000
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR Q
+ENCODING 81
+SWIDTH 778 0
+DWIDTH 16 0
+BBX 14 15 1 -1
+BITMAP
+0FC0
+3FF0
+7878
+7038
+F03C
+E01C
+E01C
+E01C
+E01C
+F19C
+71D8
+78F8
+3FF0
+0FF8
+0018
+ENDCHAR
+
+STARTCHAR R
+ENCODING 82
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FF00
+FFC0
+E1E0
+E0E0
+E0E0
+E1E0
+FFC0
+FF80
+E1C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR S
+ENCODING 83
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+3F00
+7F80
+E3C0
+E1C0
+F000
+7C00
+3F00
+0F80
+03C0
+E1C0
+E1C0
+F3C0
+7F80
+3F00
+ENDCHAR
+
+STARTCHAR T
+ENCODING 84
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 11 14 0 0
+BITMAP
+FFE0
+FFE0
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+ENDCHAR
+
+STARTCHAR U
+ENCODING 85
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+7FC0
+1F00
+ENDCHAR
+
+STARTCHAR V
+ENCODING 86
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+E0E0
+E0E0
+E0E0
+71C0
+71C0
+71C0
+3180
+3B80
+3B80
+1B00
+1F00
+1F00
+0E00
+0E00
+ENDCHAR
+
+STARTCHAR W
+ENCODING 87
+SWIDTH 944 0
+DWIDTH 17 0
+BBX 15 14 1 0
+BITMAP
+E38E
+E38E
+E38E
+E38E
+739C
+739C
+739C
+76DC
+36D8
+36D8
+3EF8
+1C70
+1C70
+1C70
+ENDCHAR
+
+STARTCHAR X
+ENCODING 88
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 12 14 0 0
+BITMAP
+E070
+E070
+70E0
+79E0
+1980
+1F80
+0F00
+1F80
+1980
+39C0
+70E0
+70E0
+E070
+E070
+ENDCHAR
+
+STARTCHAR Y
+ENCODING 89
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+E0E0
+E0E0
+E0E0
+71C0
+71C0
+3B80
+3B80
+1F00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+ENDCHAR
+
+STARTCHAR Z
+ENCODING 90
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 14 1 0
+BITMAP
+FFC0
+FFC0
+01C0
+0380
+0700
+0700
+0E00
+1C00
+3800
+3800
+7000
+E000
+FFC0
+FFC0
+ENDCHAR
+
+STARTCHAR bracketleft
+ENCODING 91
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 5 18 1 -4
+BITMAP
+F8
+F8
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+F8
+F8
+ENDCHAR
+
+STARTCHAR backslash
+ENCODING 92
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 5 14 0 0
+BITMAP
+C0
+C0
+C0
+40
+60
+60
+60
+20
+30
+30
+10
+18
+18
+18
+ENDCHAR
+
+STARTCHAR bracketright
+ENCODING 93
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 5 18 0 -4
+BITMAP
+F8
+F8
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+F8
+F8
+ENDCHAR
+
+STARTCHAR asciicircum
+ENCODING 94
+SWIDTH 584 0
+DWIDTH 10 0
+BBX 10 6 0 7
+BITMAP
+0C00
+1E00
+3F00
+7380
+E1C0
+C0C0
+ENDCHAR
+
+STARTCHAR underscore
+ENCODING 95
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 10 2 0 -4
+BITMAP
+FFC0
+FFC0
+ENDCHAR
+
+STARTCHAR grave
+ENCODING 96
+SWIDTH 333 0
+DWIDTH 5 0
+BBX 5 3 0 11
+BITMAP
+E0
+70
+38
+ENDCHAR
+
+STARTCHAR a
+ENCODING 97
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+7C
+FE
+E7
+0F
+3F
+77
+E7
+E7
+FF
+77
+ENDCHAR
+
+STARTCHAR b
+ENCODING 98
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+E000
+E000
+E000
+E000
+EF00
+FF80
+F380
+E1C0
+E1C0
+E1C0
+E1C0
+F380
+FF80
+EF00
+ENDCHAR
+
+STARTCHAR c
+ENCODING 99
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 10 1 0
+BITMAP
+1E00
+7F80
+7380
+E000
+E000
+E000
+E000
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR d
+ENCODING 100
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+01C0
+01C0
+01C0
+01C0
+3DC0
+7FC0
+73C0
+E1C0
+E1C0
+E1C0
+E1C0
+73C0
+7FC0
+3DC0
+ENDCHAR
+
+STARTCHAR e
+ENCODING 101
+SWIDTH 556 0
+DWIDTH 11 0
+BBX 9 10 1 0
+BITMAP
+1E00
+7F00
+7380
+E180
+FF80
+FF80
+E000
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR f
+ENCODING 102
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 7 14 0 0
+BITMAP
+1E
+3E
+38
+38
+FE
+FE
+38
+38
+38
+38
+38
+38
+38
+38
+ENDCHAR
+
+STARTCHAR g
+ENCODING 103
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 14 1 -4
+BITMAP
+3DC0
+7FC0
+73C0
+E1C0
+E1C0
+E1C0
+E1C0
+73C0
+7FC0
+3DC0
+01C0
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR h
+ENCODING 104
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+E000
+E000
+E000
+E000
+EF00
+FF80
+F380
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+ENDCHAR
+
+STARTCHAR i
+ENCODING 105
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 3 14 1 0
+BITMAP
+E0
+E0
+00
+00
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR j
+ENCODING 106
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 5 18 -1 -4
+BITMAP
+38
+38
+00
+00
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+F8
+F0
+ENDCHAR
+
+STARTCHAR k
+ENCODING 107
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 14 1 0
+BITMAP
+E000
+E000
+E000
+E000
+E700
+EE00
+FC00
+F800
+F800
+FC00
+EE00
+E700
+E780
+E380
+ENDCHAR
+
+STARTCHAR l
+ENCODING 108
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 3 14 1 0
+BITMAP
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR m
+ENCODING 109
+SWIDTH 889 0
+DWIDTH 15 0
+BBX 13 10 1 0
+BITMAP
+EE70
+FFF8
+F7B8
+E738
+E738
+E738
+E738
+E738
+E738
+E738
+ENDCHAR
+
+STARTCHAR n
+ENCODING 110
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 9 10 1 0
+BITMAP
+EF00
+FF80
+F380
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+ENDCHAR
+
+STARTCHAR o
+ENCODING 111
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 10 1 0
+BITMAP
+1E00
+7F80
+7380
+E1C0
+E1C0
+E1C0
+E1C0
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR p
+ENCODING 112
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 14 1 -4
+BITMAP
+EF00
+FF80
+F380
+E1C0
+E1C0
+E1C0
+E1C0
+F380
+FF80
+EF00
+E000
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR q
+ENCODING 113
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 14 1 -4
+BITMAP
+3DC0
+7FC0
+73C0
+E1C0
+E1C0
+E1C0
+E1C0
+73C0
+7FC0
+3DC0
+01C0
+01C0
+01C0
+01C0
+ENDCHAR
+
+STARTCHAR r
+ENCODING 114
+SWIDTH 389 0
+DWIDTH 7 0
+BBX 6 10 1 0
+BITMAP
+EC
+FC
+FC
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR s
+ENCODING 115
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+1E
+7F
+E7
+E0
+FE
+3F
+07
+E7
+FE
+78
+ENDCHAR
+
+STARTCHAR t
+ENCODING 116
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 6 13 0 0
+BITMAP
+70
+70
+70
+FC
+FC
+70
+70
+70
+70
+70
+70
+7C
+3C
+ENDCHAR
+
+STARTCHAR u
+ENCODING 117
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 9 10 1 0
+BITMAP
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+E780
+FF80
+7B80
+ENDCHAR
+
+STARTCHAR v
+ENCODING 118
+SWIDTH 556 0
+DWIDTH 9 0
+BBX 9 10 0 0
+BITMAP
+E380
+E380
+E380
+7700
+7700
+7700
+3E00
+3E00
+1C00
+1C00
+ENDCHAR
+
+STARTCHAR w
+ENCODING 119
+SWIDTH 778 0
+DWIDTH 13 0
+BBX 13 10 0 0
+BITMAP
+E738
+E738
+E738
+6730
+7770
+7570
+3DE0
+3DE0
+18C0
+18C0
+ENDCHAR
+
+STARTCHAR x
+ENCODING 120
+SWIDTH 556 0
+DWIDTH 9 0
+BBX 9 10 0 0
+BITMAP
+E380
+E380
+7700
+3E00
+1C00
+3E00
+7700
+7700
+E380
+E380
+ENDCHAR
+
+STARTCHAR y
+ENCODING 121
+SWIDTH 556 0
+DWIDTH 9 0
+BBX 9 14 0 -4
+BITMAP
+E380
+E380
+E380
+7700
+7700
+7700
+3E00
+3E00
+1C00
+1C00
+1C00
+1800
+7800
+7000
+ENDCHAR
+
+STARTCHAR z
+ENCODING 122
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+FF
+FF
+07
+0E
+1C
+38
+70
+E0
+FF
+FF
+ENDCHAR
+
+STARTCHAR braceleft
+ENCODING 123
+SWIDTH 389 0
+DWIDTH 8 0
+BBX 7 18 1 -4
+BITMAP
+0E
+1C
+38
+38
+38
+38
+38
+70
+E0
+70
+38
+38
+38
+38
+38
+38
+1C
+0E
+ENDCHAR
+
+STARTCHAR bar
+ENCODING 124
+SWIDTH 280 0
+DWIDTH 5 0
+BBX 2 18 1 -4
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+
+STARTCHAR braceright
+ENCODING 125
+SWIDTH 389 0
+DWIDTH 8 0
+BBX 7 18 0 -4
+BITMAP
+E0
+70
+38
+38
+38
+38
+38
+1C
+0E
+1C
+38
+38
+38
+38
+38
+38
+70
+E0
+ENDCHAR
+
+STARTCHAR asciitilde
+ENCODING 126
+SWIDTH 584 0
+DWIDTH 11 0
+BBX 9 3 1 4
+BITMAP
+7980
+FF80
+CF00
+ENDCHAR
+
+STARTCHAR space
+ENCODING 160
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+
+STARTCHAR exclamdown
+ENCODING 161
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 3 14 2 -4
+BITMAP
+E0
+E0
+00
+00
+60
+60
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR cent
+ENCODING 162
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 8 14 1 -2
+BITMAP
+02
+02
+3E
+7F
+E7
+C8
+C8
+D0
+D0
+E3
+7F
+7E
+40
+40
+ENDCHAR
+
+STARTCHAR sterling
+ENCODING 163
+SWIDTH 556 0
+DWIDTH 11 0
+BBX 10 13 0 0
+BITMAP
+1F00
+3FC0
+71C0
+7000
+7000
+3800
+7F00
+1C00
+1C00
+3800
+70C0
+FFC0
+EF80
+ENDCHAR
+
+STARTCHAR currency
+ENCODING 164
+SWIDTH 556 0
+DWIDTH 11 0
+BBX 9 8 1 2
+BITMAP
+C180
+FF80
+7700
+6300
+6300
+7700
+FF80
+C180
+ENDCHAR
+
+STARTCHAR yen
+ENCODING 165
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 13 0 0
+BITMAP
+E380
+E380
+E380
+7700
+7700
+3E00
+FF80
+1C00
+FF80
+1C00
+1C00
+1C00
+1C00
+ENDCHAR
+
+STARTCHAR brokenbar
+ENCODING 166
+SWIDTH 280 0
+DWIDTH 5 0
+BBX 2 17 1 -3
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+00
+00
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+
+STARTCHAR section
+ENCODING 167
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 8 18 1 -4
+BITMAP
+3C
+7E
+C7
+C7
+E0
+78
+FC
+C6
+C7
+E3
+73
+3F
+0E
+07
+E3
+E3
+7E
+3C
+ENDCHAR
+
+STARTCHAR dieresis
+ENCODING 168
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 2 1 11
+BITMAP
+D8
+D8
+ENDCHAR
+
+STARTCHAR copyright
+ENCODING 169
+SWIDTH 737 0
+DWIDTH 15 0
+BBX 13 13 1 0
+BITMAP
+0F80
+38E0
+6030
+6730
+CD98
+D818
+9808
+D818
+CD98
+6730
+6030
+38E0
+0F80
+ENDCHAR
+
+STARTCHAR ordfeminine
+ENCODING 170
+SWIDTH 370 0
+DWIDTH 8 0
+BBX 6 9 1 5
+BITMAP
+78
+8C
+7C
+CC
+CC
+74
+00
+FC
+FC
+ENDCHAR
+
+STARTCHAR guillemotleft
+ENCODING 171
+SWIDTH 556 0
+DWIDTH 11 0
+BBX 10 8 0 1
+BITMAP
+1DC0
+3B80
+7700
+EE00
+EE00
+7700
+3B80
+1DC0
+ENDCHAR
+
+STARTCHAR logicalnot
+ENCODING 172
+SWIDTH 584 0
+DWIDTH 11 0
+BBX 9 5 1 2
+BITMAP
+FF80
+FF80
+0180
+0180
+0180
+ENDCHAR
+
+STARTCHAR hyphen
+ENCODING 173
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 3 1 4
+BITMAP
+F8
+F8
+F8
+ENDCHAR
+
+STARTCHAR registered
+ENCODING 174
+SWIDTH 737 0
+DWIDTH 15 0
+BBX 13 13 1 0
+BITMAP
+0F80
+38E0
+6030
+6F90
+CCD8
+CCD8
+8F08
+CD98
+CD98
+6CF0
+6030
+38E0
+0F80
+ENDCHAR
+
+STARTCHAR macron
+ENCODING 175
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 2 1 12
+BITMAP
+F8
+F8
+ENDCHAR
+
+STARTCHAR degree
+ENCODING 176
+SWIDTH 400 0
+DWIDTH 7 0
+BBX 6 6 0 7
+BITMAP
+78
+FC
+CC
+CC
+FC
+78
+ENDCHAR
+
+STARTCHAR plusminus
+ENCODING 177
+SWIDTH 584 0
+DWIDTH 11 0
+BBX 9 9 1 0
+BITMAP
+1C00
+1C00
+FF80
+FF80
+1C00
+1C00
+0000
+FF80
+FF80
+ENDCHAR
+
+STARTCHAR twosuperior
+ENCODING 178
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 6 8 0 5
+BITMAP
+78
+FC
+CC
+1C
+78
+E0
+FC
+FC
+ENDCHAR
+
+STARTCHAR threesuperior
+ENCODING 179
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 6 8 0 5
+BITMAP
+78
+FC
+CC
+38
+3C
+CC
+FC
+78
+ENDCHAR
+
+STARTCHAR acute
+ENCODING 180
+SWIDTH 333 0
+DWIDTH 5 0
+BBX 5 3 0 11
+BITMAP
+38
+70
+E0
+ENDCHAR
+
+STARTCHAR mu
+ENCODING 181
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 9 14 1 -4
+BITMAP
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+E780
+FF80
+FB80
+E000
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR paragraph
+ENCODING 182
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 18 0 -4
+BITMAP
+3F80
+7B00
+FB00
+FB00
+FB00
+FB00
+FB00
+7B00
+3B00
+1B00
+1B00
+1B00
+1B00
+1B00
+1B00
+1B00
+1B00
+1B00
+ENDCHAR
+
+STARTCHAR periodcentered
+ENCODING 183
+SWIDTH 278 0
+DWIDTH 4 0
+BBX 2 2 1 4
+BITMAP
+C0
+C0
+ENDCHAR
+
+STARTCHAR cedilla
+ENCODING 184
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 5 1 -5
+BITMAP
+60
+70
+18
+F8
+F0
+ENDCHAR
+
+STARTCHAR onesuperior
+ENCODING 185
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 4 8 0 5
+BITMAP
+30
+F0
+F0
+30
+30
+30
+30
+30
+ENDCHAR
+
+STARTCHAR ordmasculine
+ENCODING 186
+SWIDTH 365 0
+DWIDTH 8 0
+BBX 6 9 1 5
+BITMAP
+78
+CC
+CC
+CC
+CC
+78
+00
+FC
+FC
+ENDCHAR
+
+STARTCHAR guillemotright
+ENCODING 187
+SWIDTH 556 0
+DWIDTH 11 0
+BBX 10 8 0 1
+BITMAP
+EE00
+7700
+3B80
+1DC0
+1DC0
+3B80
+7700
+EE00
+ENDCHAR
+
+STARTCHAR onequarter
+ENCODING 188
+SWIDTH 834 0
+DWIDTH 15 0
+BBX 14 13 0 0
+BITMAP
+3060
+F060
+F0C0
+30C0
+3180
+3198
+3338
+3638
+0678
+0CD8
+0CFC
+1818
+1818
+ENDCHAR
+
+STARTCHAR onehalf
+ENCODING 189
+SWIDTH 834 0
+DWIDTH 15 0
+BBX 15 13 0 0
+BITMAP
+3060
+F060
+F0C0
+30C0
+3180
+31BC
+337E
+3666
+060E
+0C3C
+0C70
+187E
+187E
+ENDCHAR
+
+STARTCHAR threequarters
+ENCODING 190
+SWIDTH 834 0
+DWIDTH 15 0
+BBX 14 13 0 0
+BITMAP
+7830
+FC30
+CC60
+3860
+3CC0
+CCD8
+FDB8
+7B38
+0378
+06D8
+06FC
+0C18
+0C18
+ENDCHAR
+
+STARTCHAR questiondown
+ENCODING 191
+SWIDTH 611 0
+DWIDTH 10 0
+BBX 8 14 1 -4
+BITMAP
+1C
+1C
+00
+00
+1C
+1C
+1C
+38
+78
+70
+E7
+E7
+FF
+7E
+ENDCHAR
+
+STARTCHAR Agrave
+ENCODING 192
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+3800
+1C00
+0E00
+0000
+0E00
+0E00
+1F00
+1F00
+1B00
+3B80
+3180
+3180
+71C0
+7FC0
+7FC0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR Aacute
+ENCODING 193
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+0380
+0700
+0E00
+0000
+0E00
+0E00
+1F00
+1F00
+1B00
+3B80
+3180
+3180
+71C0
+7FC0
+7FC0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR Acircumflex
+ENCODING 194
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+0E00
+1F00
+3B80
+0000
+0E00
+0E00
+1F00
+1F00
+1B00
+3B80
+3180
+3180
+71C0
+7FC0
+7FC0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR Atilde
+ENCODING 195
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+1D80
+3F80
+3700
+0000
+0E00
+0E00
+1F00
+1F00
+1B00
+3B80
+3180
+3180
+71C0
+7FC0
+7FC0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR Adieresis
+ENCODING 196
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 17 1 0
+BITMAP
+1980
+1980
+0000
+0E00
+0E00
+1F00
+1F00
+1B00
+3B80
+3180
+3180
+71C0
+7FC0
+7FC0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR Aring
+ENCODING 197
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 17 1 0
+BITMAP
+0E00
+1B00
+1B00
+0E00
+0E00
+1F00
+1F00
+1B00
+3B80
+3180
+3180
+71C0
+7FC0
+7FC0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR AE
+ENCODING 198
+SWIDTH 1000 0
+DWIDTH 18 0
+BBX 16 14 1 0
+BITMAP
+0FFF
+0FFF
+1F80
+1B80
+3B80
+3B80
+33FE
+73FE
+7380
+7F80
+FF80
+E380
+E3FF
+E3FF
+ENDCHAR
+
+STARTCHAR Ccedilla
+ENCODING 199
+SWIDTH 722 0
+DWIDTH 14 0
+BBX 12 19 1 -5
+BITMAP
+0F80
+3FE0
+78E0
+7070
+F070
+E000
+E000
+E000
+E000
+F070
+7070
+78E0
+3FE0
+0F80
+0C00
+0E00
+0300
+1F00
+1E00
+ENDCHAR
+
+STARTCHAR Egrave
+ENCODING 200
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 10 18 1 0
+BITMAP
+3800
+1C00
+0E00
+0000
+FFC0
+FFC0
+E000
+E000
+E000
+E000
+FF80
+FF80
+E000
+E000
+E000
+E000
+FFC0
+FFC0
+ENDCHAR
+
+STARTCHAR Eacute
+ENCODING 201
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 10 18 1 0
+BITMAP
+0380
+0700
+0E00
+0000
+FFC0
+FFC0
+E000
+E000
+E000
+E000
+FF80
+FF80
+E000
+E000
+E000
+E000
+FFC0
+FFC0
+ENDCHAR
+
+STARTCHAR Ecircumflex
+ENCODING 202
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 10 18 1 0
+BITMAP
+0E00
+1F00
+3B80
+0000
+FFC0
+FFC0
+E000
+E000
+E000
+E000
+FF80
+FF80
+E000
+E000
+E000
+E000
+FFC0
+FFC0
+ENDCHAR
+
+STARTCHAR Edieresis
+ENCODING 203
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 10 17 1 0
+BITMAP
+3300
+3300
+0000
+FFC0
+FFC0
+E000
+E000
+E000
+E000
+FF80
+FF80
+E000
+E000
+E000
+E000
+FFC0
+FFC0
+ENDCHAR
+
+STARTCHAR Igrave
+ENCODING 204
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 5 18 -1 0
+BITMAP
+E0
+70
+38
+00
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+ENDCHAR
+
+STARTCHAR Iacute
+ENCODING 205
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 5 18 1 0
+BITMAP
+38
+70
+E0
+00
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR Icircumflex
+ENCODING 206
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 5 18 0 0
+BITMAP
+20
+70
+D8
+00
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+ENDCHAR
+
+STARTCHAR Idieresis
+ENCODING 207
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 5 17 0 0
+BITMAP
+D8
+D8
+00
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+ENDCHAR
+
+STARTCHAR Eth
+ENCODING 208
+SWIDTH 722 0
+DWIDTH 14 0
+BBX 13 14 0 0
+BITMAP
+7F80
+7FE0
+70F0
+7070
+7038
+7038
+FE38
+FE38
+7038
+7038
+7070
+70F0
+7FE0
+7F80
+ENDCHAR
+
+STARTCHAR Ntilde
+ENCODING 209
+SWIDTH 722 0
+DWIDTH 14 0
+BBX 12 18 1 0
+BITMAP
+0EC0
+1FC0
+1B80
+0000
+E070
+F070
+F070
+F870
+FC70
+EC70
+EE70
+E670
+E770
+E370
+E1F0
+E1F0
+E0F0
+E070
+ENDCHAR
+
+STARTCHAR Ograve
+ENCODING 210
+SWIDTH 778 0
+DWIDTH 16 0
+BBX 14 18 1 0
+BITMAP
+0E00
+0700
+0380
+0000
+0FC0
+3FF0
+7878
+7038
+F03C
+E01C
+E01C
+E01C
+E01C
+F03C
+7038
+7878
+3FF0
+0FC0
+ENDCHAR
+
+STARTCHAR Oacute
+ENCODING 211
+SWIDTH 778 0
+DWIDTH 16 0
+BBX 14 18 1 0
+BITMAP
+00E0
+01C0
+0380
+0000
+0FC0
+3FF0
+7878
+7038
+F03C
+E01C
+E01C
+E01C
+E01C
+F03C
+7038
+7878
+3FF0
+0FC0
+ENDCHAR
+
+STARTCHAR Ocircumflex
+ENCODING 212
+SWIDTH 778 0
+DWIDTH 16 0
+BBX 14 18 1 0
+BITMAP
+0380
+07C0
+0EE0
+0000
+0FC0
+3FF0
+7878
+7038
+F03C
+E01C
+E01C
+E01C
+E01C
+F03C
+7038
+7878
+3FF0
+0FC0
+ENDCHAR
+
+STARTCHAR Otilde
+ENCODING 213
+SWIDTH 778 0
+DWIDTH 16 0
+BBX 14 18 1 0
+BITMAP
+0760
+0FE0
+0DC0
+0000
+0FC0
+3FF0
+7878
+7038
+F03C
+E01C
+E01C
+E01C
+E01C
+F03C
+7038
+7878
+3FF0
+0FC0
+ENDCHAR
+
+STARTCHAR Odieresis
+ENCODING 214
+SWIDTH 778 0
+DWIDTH 16 0
+BBX 14 17 1 0
+BITMAP
+0CC0
+0CC0
+0000
+0FC0
+3FF0
+7878
+7038
+F03C
+E01C
+E01C
+E01C
+E01C
+F03C
+7038
+7878
+3FF0
+0FC0
+ENDCHAR
+
+STARTCHAR multiply
+ENCODING 215
+SWIDTH 584 0
+DWIDTH 11 0
+BBX 10 8 0 1
+BITMAP
+E1C0
+7380
+3F00
+1E00
+1E00
+3F00
+7380
+E1C0
+ENDCHAR
+
+STARTCHAR Oslash
+ENCODING 216
+SWIDTH 778 0
+DWIDTH 16 0
+BBX 15 14 0 0
+BITMAP
+07EE
+1FFC
+3C38
+387C
+78EE
+71CE
+738E
+770E
+7E0E
+7C1E
+381C
+7C3C
+EFF8
+C7E0
+ENDCHAR
+
+STARTCHAR Ugrave
+ENCODING 217
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+3800
+1C00
+0E00
+0000
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+7FC0
+1F00
+ENDCHAR
+
+STARTCHAR Uacute
+ENCODING 218
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+0380
+0700
+0E00
+0000
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+7FC0
+1F00
+ENDCHAR
+
+STARTCHAR Ucircumflex
+ENCODING 219
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+0E00
+1F00
+3B80
+0000
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+7FC0
+1F00
+ENDCHAR
+
+STARTCHAR Udieresis
+ENCODING 220
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 17 1 0
+BITMAP
+1980
+1980
+0000
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+7FC0
+1F00
+ENDCHAR
+
+STARTCHAR Yacute
+ENCODING 221
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+0380
+0700
+0E00
+0000
+E0E0
+E0E0
+E0E0
+71C0
+71C0
+3B80
+3B80
+1F00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+ENDCHAR
+
+STARTCHAR Thorn
+ENCODING 222
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+E000
+E000
+E000
+FE00
+FF80
+E3C0
+E1C0
+E1C0
+E3C0
+FF80
+FE00
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR germandbls
+ENCODING 223
+SWIDTH 611 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+3C
+7E
+E7
+E7
+E7
+E7
+EE
+EE
+E7
+E7
+E7
+E7
+EF
+EE
+ENDCHAR
+
+STARTCHAR agrave
+ENCODING 224
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+70
+38
+1C
+00
+7C
+FE
+E7
+0F
+3F
+77
+E7
+E7
+FF
+77
+ENDCHAR
+
+STARTCHAR aacute
+ENCODING 225
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+0E
+1C
+38
+00
+7C
+FE
+E7
+0F
+3F
+77
+E7
+E7
+FF
+77
+ENDCHAR
+
+STARTCHAR acircumflex
+ENCODING 226
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+1C
+3E
+77
+00
+7C
+FE
+E7
+0F
+3F
+77
+E7
+E7
+FF
+77
+ENDCHAR
+
+STARTCHAR atilde
+ENCODING 227
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+3B
+7F
+6E
+00
+7C
+FE
+E7
+0F
+3F
+77
+E7
+E7
+FF
+77
+ENDCHAR
+
+STARTCHAR adieresis
+ENCODING 228
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+36
+36
+00
+7C
+FE
+E7
+0F
+3F
+77
+E7
+E7
+FF
+77
+ENDCHAR
+
+STARTCHAR aring
+ENCODING 229
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+1C
+36
+36
+1C
+7C
+FE
+E7
+0F
+3F
+77
+E7
+E7
+FF
+77
+ENDCHAR
+
+STARTCHAR ae
+ENCODING 230
+SWIDTH 889 0
+DWIDTH 16 0
+BBX 14 10 1 0
+BITMAP
+7CF0
+FFF8
+E71C
+0F1C
+3FFC
+7700
+E700
+EF9C
+FFFC
+79F0
+ENDCHAR
+
+STARTCHAR ccedilla
+ENCODING 231
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 15 1 -5
+BITMAP
+1E00
+7F80
+7380
+E000
+E000
+E000
+E000
+7380
+7F80
+1E00
+1800
+1C00
+0600
+3E00
+3C00
+ENDCHAR
+
+STARTCHAR egrave
+ENCODING 232
+SWIDTH 556 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+3800
+1C00
+0E00
+0000
+1E00
+7F00
+7380
+E180
+FF80
+FF80
+E000
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR eacute
+ENCODING 233
+SWIDTH 556 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+0700
+0E00
+1C00
+0000
+1E00
+7F00
+7380
+E180
+FF80
+FF80
+E000
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR ecircumflex
+ENCODING 234
+SWIDTH 556 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+0E00
+1F00
+3B80
+0000
+1E00
+7F00
+7380
+E180
+FF80
+FF80
+E000
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR edieresis
+ENCODING 235
+SWIDTH 556 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+3300
+3300
+0000
+1E00
+7F00
+7380
+E180
+FF80
+FF80
+E000
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR igrave
+ENCODING 236
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 5 14 0 0
+BITMAP
+E0
+70
+38
+00
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+ENDCHAR
+
+STARTCHAR iacute
+ENCODING 237
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 5 14 0 0
+BITMAP
+38
+70
+E0
+00
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+ENDCHAR
+
+STARTCHAR icircumflex
+ENCODING 238
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 7 14 -1 0
+BITMAP
+38
+7C
+EE
+00
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+ENDCHAR
+
+STARTCHAR idieresis
+ENCODING 239
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 5 13 0 0
+BITMAP
+D8
+D8
+00
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+ENDCHAR
+
+STARTCHAR eth
+ENCODING 240
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+7000
+1F00
+7C00
+0600
+1F00
+7F80
+7380
+E1C0
+E1C0
+E1C0
+E1C0
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR ntilde
+ENCODING 241
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+3B00
+7F00
+6E00
+0000
+EF00
+FF80
+F380
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+ENDCHAR
+
+STARTCHAR ograve
+ENCODING 242
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+3800
+1C00
+0E00
+0000
+1E00
+7F80
+7380
+E1C0
+E1C0
+E1C0
+E1C0
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR oacute
+ENCODING 243
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+0700
+0E00
+1C00
+0000
+1E00
+7F80
+7380
+E1C0
+E1C0
+E1C0
+E1C0
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR ocircumflex
+ENCODING 244
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+0E00
+1F00
+3B80
+0000
+1E00
+7F80
+7380
+E1C0
+E1C0
+E1C0
+E1C0
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR otilde
+ENCODING 245
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 14 1 0
+BITMAP
+1D80
+3F80
+3700
+0000
+1E00
+7F80
+7380
+E1C0
+E1C0
+E1C0
+E1C0
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR odieresis
+ENCODING 246
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+3300
+3300
+0000
+1E00
+7F80
+7380
+E1C0
+E1C0
+E1C0
+E1C0
+7380
+7F80
+1E00
+ENDCHAR
+
+STARTCHAR divide
+ENCODING 247
+SWIDTH 584 0
+DWIDTH 11 0
+BBX 9 8 1 1
+BITMAP
+1C00
+1C00
+0000
+FF80
+FF80
+0000
+1C00
+1C00
+ENDCHAR
+
+STARTCHAR oslash
+ENCODING 248
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 12 10 0 0
+BITMAP
+0F30
+3FE0
+38C0
+71E0
+77E0
+7EE0
+78E0
+31C0
+7FC0
+CF00
+ENDCHAR
+
+STARTCHAR ugrave
+ENCODING 249
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+7000
+3800
+1C00
+0000
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+E780
+FF80
+7B80
+ENDCHAR
+
+STARTCHAR uacute
+ENCODING 250
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+0700
+0E00
+1C00
+0000
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+E780
+FF80
+7B80
+ENDCHAR
+
+STARTCHAR ucircumflex
+ENCODING 251
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+1C00
+3E00
+7700
+0000
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+E780
+FF80
+7B80
+ENDCHAR
+
+STARTCHAR udieresis
+ENCODING 252
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+3600
+3600
+0000
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+E780
+FF80
+7B80
+ENDCHAR
+
+STARTCHAR yacute
+ENCODING 253
+SWIDTH 556 0
+DWIDTH 9 0
+BBX 9 18 0 -4
+BITMAP
+0700
+0E00
+1C00
+0000
+E380
+E380
+E380
+7700
+7700
+7700
+3E00
+3E00
+1C00
+1C00
+1C00
+1800
+7800
+7000
+ENDCHAR
+
+STARTCHAR thorn
+ENCODING 254
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 10 18 1 -4
+BITMAP
+E000
+E000
+E000
+E000
+EF00
+FF80
+F380
+E1C0
+E1C0
+E1C0
+E1C0
+F380
+FF80
+EF00
+E000
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR ydieresis
+ENCODING 255
+SWIDTH 556 0
+DWIDTH 9 0
+BBX 9 17 0 -4
+BITMAP
+3600
+3600
+0000
+E380
+E380
+E380
+7700
+7700
+7700
+3E00
+3E00
+1C00
+1C00
+1C00
+1800
+7800
+7000
+ENDCHAR
+
+ENDFONT
diff --git a/fonts/helvB18.cc b/fonts/helvB18.cc
new file mode 100644 (file)
index 0000000..5da9b7f
Binary files /dev/null and b/fonts/helvB18.cc differ
diff --git a/fonts/helvB24-ISO8859-1.pcf b/fonts/helvB24-ISO8859-1.pcf
new file mode 100644 (file)
index 0000000..6309e1e
Binary files /dev/null and b/fonts/helvB24-ISO8859-1.pcf differ
diff --git a/fonts/helvB24.bdf b/fonts/helvB24.bdf
new file mode 100644 (file)
index 0000000..971b857
--- /dev/null
@@ -0,0 +1,4889 @@
+STARTFONT 2.1
+FONT -Adobe-Helvetica-Bold-R-Normal--24-240-75-75-P-138-ISO8859-1
+SIZE 24 75 75
+FONTBOUNDINGBOX 24 29 -1 -5
+
+STARTPROPERTIES 28
+FOUNDRY "Adobe"
+FAMILY_NAME "Helvetica"
+WEIGHT_NAME "Bold"
+SLANT "R"
+SETWIDTH_NAME "Normal"
+ADD_STYLE_NAME ""
+PIXEL_SIZE 24
+POINT_SIZE 240
+RESOLUTION_X 75
+RESOLUTION_Y 75
+SPACING "P"
+AVERAGE_WIDTH 138
+CHARSET_REGISTRY "ISO8859"
+CHARSET_ENCODING "1"
+CAP_HEIGHT 19
+X_HEIGHT 14
+FACE_NAME "Helvetica Bold"
+COPYRIGHT "Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved."
+NOTICE "Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.  "
+_DEC_DEVICE_FONTNAMES "PS=Helvetica-Bold"
+RELATIVE_SETWIDTH 50
+RELATIVE_WEIGHT 70
+FULL_NAME "Helvetica Bold"
+WEIGHT 10
+QUAD_WIDTH 15
+DEFAULT_CHAR 0
+FONT_DESCENT 5
+FONT_ASCENT 22
+ENDPROPERTIES
+
+CHARS 192
+
+STARTCHAR defaultchar
+ENCODING 0
+SWIDTH 722 0
+DWIDTH 19 0
+BBX 15 19 2 0
+BITMAP
+AAAA
+0000
+8002
+0000
+8002
+0000
+8002
+0000
+8002
+0000
+8002
+0000
+8002
+0000
+8002
+0000
+8002
+0000
+AAAA
+ENDCHAR
+
+STARTCHAR space
+ENCODING 32
+SWIDTH 278 0
+DWIDTH 6 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+
+STARTCHAR exclam
+ENCODING 33
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 3 19 2 0
+BITMAP
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+00
+00
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR quotedbl
+ENCODING 34
+SWIDTH 474 0
+DWIDTH 9 0
+BBX 5 6 2 13
+BITMAP
+D8
+D8
+D8
+D8
+D8
+90
+ENDCHAR
+
+STARTCHAR numbersign
+ENCODING 35
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 18 0 0
+BITMAP
+0CC0
+0CC0
+0CC0
+0CC0
+0CC0
+7FF0
+7FF0
+1980
+1980
+1980
+1980
+FFE0
+FFE0
+3300
+3300
+3300
+3300
+3300
+ENDCHAR
+
+STARTCHAR dollar
+ENCODING 36
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 12 21 0 -2
+BITMAP
+0600
+3F80
+7FC0
+F6E0
+E6E0
+E6E0
+F600
+7E00
+3E00
+0F00
+07C0
+07E0
+06F0
+E670
+E670
+E670
+F6F0
+7FE0
+1FC0
+0600
+0600
+ENDCHAR
+
+STARTCHAR percent
+ENCODING 37
+SWIDTH 889 0
+DWIDTH 22 0
+BBX 21 18 0 0
+BITMAP
+000700
+3E0700
+7F0E00
+E38E00
+C19C00
+C19C00
+E3B800
+7F3800
+3E7000
+007000
+00E3E0
+00E7F0
+01CE38
+01CC18
+038C18
+038E38
+0707F0
+0703E0
+ENDCHAR
+
+STARTCHAR ampersand
+ENCODING 38
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 16 18 1 0
+BITMAP
+0F80
+1FC0
+3DE0
+38E0
+38E0
+38E0
+1DC0
+0F80
+1F00
+3F9C
+7BDC
+71FC
+E0F8
+E070
+E0F8
+F1FC
+7FCE
+1F87
+ENDCHAR
+
+STARTCHAR quotesingle
+ENCODING 39
+SWIDTH 238 0
+DWIDTH 6 0
+BBX 2 6 2 13
+BITMAP
+C0
+C0
+C0
+C0
+C0
+80
+ENDCHAR
+
+STARTCHAR parenleft
+ENCODING 40
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 6 24 1 -5
+BITMAP
+0C
+1C
+38
+38
+70
+70
+60
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+60
+70
+70
+38
+38
+1C
+0C
+ENDCHAR
+
+STARTCHAR parenright
+ENCODING 41
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 6 24 1 -5
+BITMAP
+C0
+E0
+70
+70
+38
+38
+18
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+18
+38
+38
+70
+70
+E0
+C0
+ENDCHAR
+
+STARTCHAR asterisk
+ENCODING 42
+SWIDTH 389 0
+DWIDTH 10 0
+BBX 8 7 1 12
+BITMAP
+18
+18
+DB
+FF
+3C
+66
+66
+ENDCHAR
+
+STARTCHAR plus
+ENCODING 43
+SWIDTH 584 0
+DWIDTH 15 0
+BBX 11 12 2 1
+BITMAP
+0E00
+0E00
+0E00
+0E00
+0E00
+FFE0
+FFE0
+0E00
+0E00
+0E00
+0E00
+0E00
+ENDCHAR
+
+STARTCHAR comma
+ENCODING 44
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 3 6 2 -3
+BITMAP
+E0
+E0
+E0
+60
+60
+C0
+ENDCHAR
+
+STARTCHAR hyphen
+ENCODING 45
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 7 3 0 6
+BITMAP
+FE
+FE
+FE
+ENDCHAR
+
+STARTCHAR period
+ENCODING 46
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 3 3 2 0
+BITMAP
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR slash
+ENCODING 47
+SWIDTH 278 0
+DWIDTH 8 0
+BBX 8 19 0 0
+BITMAP
+07
+07
+06
+06
+0E
+0C
+0C
+1C
+1C
+18
+18
+38
+30
+30
+70
+60
+60
+E0
+E0
+ENDCHAR
+
+STARTCHAR zero
+ENCODING 48
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 12 18 0 0
+BITMAP
+1F80
+3FC0
+79E0
+70E0
+70E0
+E070
+E070
+E070
+E070
+E070
+E070
+E070
+E070
+70E0
+70E0
+79E0
+3FC0
+1F80
+ENDCHAR
+
+STARTCHAR one
+ENCODING 49
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 7 18 2 0
+BITMAP
+0E
+0E
+1E
+FE
+FE
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+ENDCHAR
+
+STARTCHAR two
+ENCODING 50
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 12 18 0 0
+BITMAP
+1F00
+7FC0
+71E0
+E0E0
+E070
+E070
+0070
+00E0
+01E0
+03C0
+0780
+1F00
+3C00
+7800
+F000
+E000
+FFF0
+FFF0
+ENDCHAR
+
+STARTCHAR three
+ENCODING 51
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 12 18 0 0
+BITMAP
+1F00
+7FC0
+71C0
+E0E0
+E0E0
+E0E0
+00E0
+01C0
+0F80
+0FE0
+00E0
+0070
+0070
+E070
+E0F0
+71E0
+7FE0
+1F80
+ENDCHAR
+
+STARTCHAR four
+ENCODING 52
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 12 18 0 0
+BITMAP
+01C0
+03C0
+03C0
+07C0
+07C0
+0DC0
+1DC0
+19C0
+31C0
+71C0
+61C0
+E1C0
+FFF0
+FFF0
+01C0
+01C0
+01C0
+01C0
+ENDCHAR
+
+STARTCHAR five
+ENCODING 53
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 12 18 0 0
+BITMAP
+7FE0
+7FE0
+7000
+7000
+7000
+7000
+7F80
+7FC0
+71E0
+00E0
+0070
+0070
+0070
+E070
+E0F0
+F1E0
+7FC0
+1F80
+ENDCHAR
+
+STARTCHAR six
+ENCODING 54
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 12 18 0 0
+BITMAP
+0F80
+3FE0
+78E0
+7070
+E070
+E000
+E000
+EF00
+FFC0
+F9E0
+F0E0
+E070
+E070
+E070
+70E0
+79E0
+3FC0
+1F80
+ENDCHAR
+
+STARTCHAR seven
+ENCODING 55
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 12 18 0 0
+BITMAP
+FFF0
+FFF0
+00F0
+00E0
+01C0
+01C0
+0380
+0380
+0700
+0700
+0E00
+0E00
+1E00
+1C00
+1C00
+3C00
+3800
+3800
+ENDCHAR
+
+STARTCHAR eight
+ENCODING 56
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 12 18 0 0
+BITMAP
+0F00
+3FC0
+39C0
+70E0
+70E0
+70E0
+70E0
+39C0
+1F80
+3FC0
+70E0
+E070
+E070
+E070
+E070
+70E0
+7FE0
+1F80
+ENDCHAR
+
+STARTCHAR nine
+ENCODING 57
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 12 18 0 0
+BITMAP
+1F80
+7FC0
+79E0
+F0E0
+E070
+E070
+E070
+E070
+F0F0
+79F0
+7FF0
+1F70
+0070
+0070
+E0E0
+F3E0
+7FC0
+1F00
+ENDCHAR
+
+STARTCHAR colon
+ENCODING 58
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 3 14 2 0
+BITMAP
+E0
+E0
+E0
+00
+00
+00
+00
+00
+00
+00
+00
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR semicolon
+ENCODING 59
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 3 17 2 -3
+BITMAP
+E0
+E0
+E0
+00
+00
+00
+00
+00
+00
+00
+00
+E0
+E0
+E0
+60
+60
+C0
+ENDCHAR
+
+STARTCHAR less
+ENCODING 60
+SWIDTH 584 0
+DWIDTH 15 0
+BBX 13 12 0 1
+BITMAP
+0038
+00F8
+03E0
+0F80
+3E00
+F000
+F000
+3E00
+0F80
+03E0
+00F8
+0038
+ENDCHAR
+
+STARTCHAR equal
+ENCODING 61
+SWIDTH 584 0
+DWIDTH 14 0
+BBX 10 6 2 4
+BITMAP
+FFC0
+FFC0
+0000
+0000
+FFC0
+FFC0
+ENDCHAR
+
+STARTCHAR greater
+ENCODING 62
+SWIDTH 584 0
+DWIDTH 14 0
+BBX 13 12 0 1
+BITMAP
+E000
+F800
+3E00
+0F80
+03E0
+0078
+0078
+03E0
+0F80
+3E00
+F800
+E000
+ENDCHAR
+
+STARTCHAR question
+ENCODING 63
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 11 19 2 0
+BITMAP
+1F80
+7FC0
+79E0
+F0E0
+E0E0
+E1E0
+01C0
+03C0
+0780
+0700
+0E00
+0E00
+0E00
+0E00
+0000
+0000
+0E00
+0E00
+0E00
+ENDCHAR
+
+STARTCHAR at
+ENCODING 64
+SWIDTH 975 0
+DWIDTH 24 0
+BBX 22 22 1 -4
+BITMAP
+01FF00
+07FFC0
+0F81F0
+1E0078
+3C0038
+787D9C
+70FF9C
+F1C71C
+E3871C
+E30E1C
+E70E38
+E70C38
+E71C70
+E71C70
+E39DE0
+F3FFC0
+71F700
+780000
+3C0000
+1F0700
+0FFF00
+03FC00
+ENDCHAR
+
+STARTCHAR A
+ENCODING 65
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 16 19 1 0
+BITMAP
+03C0
+03C0
+07E0
+07E0
+0E60
+0E70
+0E70
+1C38
+1C38
+1C38
+381C
+381C
+3FFC
+7FFE
+700E
+700E
+E007
+E007
+E007
+ENDCHAR
+
+STARTCHAR B
+ENCODING 66
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 15 19 2 0
+BITMAP
+FFE0
+FFF8
+E078
+E01C
+E01C
+E01C
+E01C
+E038
+FFF0
+FFF8
+E01C
+E00E
+E00E
+E00E
+E00E
+E01E
+E07C
+FFF8
+FFE0
+ENDCHAR
+
+STARTCHAR C
+ENCODING 67
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 16 19 1 0
+BITMAP
+07F0
+1FFC
+3E3E
+780F
+7007
+F000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+F007
+7007
+780F
+3E3E
+1FFC
+07F0
+ENDCHAR
+
+STARTCHAR D
+ENCODING 68
+SWIDTH 722 0
+DWIDTH 19 0
+BBX 16 19 2 0
+BITMAP
+FFE0
+FFF8
+E07C
+E01E
+E00E
+E00F
+E007
+E007
+E007
+E007
+E007
+E007
+E007
+E00F
+E00E
+E01E
+E07C
+FFF8
+FFE0
+ENDCHAR
+
+STARTCHAR E
+ENCODING 69
+SWIDTH 667 0
+DWIDTH 16 0
+BBX 13 19 2 0
+BITMAP
+FFF0
+FFF0
+E000
+E000
+E000
+E000
+E000
+E000
+FFE0
+FFE0
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+FFF8
+FFF8
+ENDCHAR
+
+STARTCHAR F
+ENCODING 70
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 12 19 2 0
+BITMAP
+FFF0
+FFF0
+E000
+E000
+E000
+E000
+E000
+E000
+FFE0
+FFE0
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR G
+ENCODING 71
+SWIDTH 778 0
+DWIDTH 19 0
+BBX 17 19 1 0
+BITMAP
+07F000
+1FFC00
+3E3E00
+780F00
+700700
+F00000
+E00000
+E00000
+E00000
+E07F80
+E07F80
+E00380
+E00380
+F00380
+700780
+780F80
+3E3F80
+1FFB80
+07F180
+ENDCHAR
+
+STARTCHAR H
+ENCODING 72
+SWIDTH 722 0
+DWIDTH 19 0
+BBX 15 19 2 0
+BITMAP
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+FFFE
+FFFE
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+ENDCHAR
+
+STARTCHAR I
+ENCODING 73
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 3 19 2 0
+BITMAP
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR J
+ENCODING 74
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 11 19 1 0
+BITMAP
+00E0
+00E0
+00E0
+00E0
+00E0
+00E0
+00E0
+00E0
+00E0
+00E0
+00E0
+00E0
+E0E0
+E0E0
+E0E0
+E0E0
+71E0
+7FC0
+3F80
+ENDCHAR
+
+STARTCHAR K
+ENCODING 75
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 16 19 2 0
+BITMAP
+E03C
+E078
+E0F0
+E1E0
+E3C0
+E780
+EF00
+FE00
+FE00
+FF00
+F780
+E3C0
+E1E0
+E0F0
+E078
+E03C
+E01E
+E00F
+E007
+ENDCHAR
+
+STARTCHAR L
+ENCODING 76
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 12 19 2 0
+BITMAP
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+FFF0
+FFF0
+ENDCHAR
+
+STARTCHAR M
+ENCODING 77
+SWIDTH 833 0
+DWIDTH 23 0
+BBX 19 19 2 0
+BITMAP
+E000E0
+F001E0
+F001E0
+F803E0
+F803E0
+FC07E0
+EC06E0
+EE0EE0
+E60CE0
+E71CE0
+E71CE0
+E318E0
+E3B8E0
+E3B8E0
+E1F0E0
+E1F0E0
+E0E0E0
+E0E0E0
+E0E0E0
+ENDCHAR
+
+STARTCHAR N
+ENCODING 78
+SWIDTH 722 0
+DWIDTH 19 0
+BBX 15 19 2 0
+BITMAP
+E00E
+F00E
+F00E
+F80E
+F80E
+FC0E
+EE0E
+EE0E
+E70E
+E38E
+E38E
+E1CE
+E0CE
+E0EE
+E07E
+E03E
+E03E
+E01E
+E00E
+ENDCHAR
+
+STARTCHAR O
+ENCODING 79
+SWIDTH 778 0
+DWIDTH 19 0
+BBX 17 19 1 0
+BITMAP
+07F000
+1FFC00
+3E3E00
+780F00
+700700
+F00780
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+F00780
+700700
+780F00
+3E3E00
+1FFC00
+07F000
+ENDCHAR
+
+STARTCHAR P
+ENCODING 80
+SWIDTH 667 0
+DWIDTH 17 0
+BBX 14 19 2 0
+BITMAP
+FFE0
+FFF8
+E038
+E01C
+E01C
+E01C
+E01C
+E038
+FFF8
+FFF0
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR Q
+ENCODING 81
+SWIDTH 778 0
+DWIDTH 19 0
+BBX 17 19 1 0
+BITMAP
+07F000
+1FFC00
+3E3E00
+780F00
+700700
+F00780
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+F00780
+70F700
+787F00
+3E1E00
+1FFF00
+07F780
+ENDCHAR
+
+STARTCHAR R
+ENCODING 82
+SWIDTH 722 0
+DWIDTH 17 0
+BBX 14 19 2 0
+BITMAP
+FFE0
+FFF8
+E038
+E01C
+E01C
+E01C
+E01C
+E038
+FFF8
+FFF0
+E078
+E038
+E01C
+E01C
+E01C
+E01C
+E01C
+E01C
+E01C
+ENDCHAR
+
+STARTCHAR S
+ENCODING 83
+SWIDTH 667 0
+DWIDTH 17 0
+BBX 15 19 1 0
+BITMAP
+07E0
+1FF8
+3C7C
+781C
+701C
+7000
+7800
+3E00
+1FE0
+03F8
+007C
+001E
+000E
+E00E
+E00E
+F01E
+7C7C
+3FF8
+0FE0
+ENDCHAR
+
+STARTCHAR T
+ENCODING 84
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 15 19 0 0
+BITMAP
+FFFE
+FFFE
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+ENDCHAR
+
+STARTCHAR U
+ENCODING 85
+SWIDTH 722 0
+DWIDTH 19 0
+BBX 15 19 2 0
+BITMAP
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+7C7C
+3FF8
+0FE0
+ENDCHAR
+
+STARTCHAR V
+ENCODING 86
+SWIDTH 667 0
+DWIDTH 18 0
+BBX 16 19 1 0
+BITMAP
+E007
+E007
+F00F
+700E
+781E
+381C
+381C
+3C3C
+1C38
+1C38
+1E78
+0E70
+0E70
+0E70
+07E0
+07E0
+03C0
+03C0
+03C0
+ENDCHAR
+
+STARTCHAR W
+ENCODING 87
+SWIDTH 944 0
+DWIDTH 23 0
+BBX 21 19 1 0
+BITMAP
+E07038
+E07038
+E07038
+E07038
+70F870
+70F870
+70D870
+71DC70
+31DC60
+39DCE0
+398CE0
+3B8EE0
+1B8EC0
+1B8EC0
+1F07C0
+1F07C0
+0E0380
+0E0380
+0E0380
+ENDCHAR
+
+STARTCHAR X
+ENCODING 88
+SWIDTH 667 0
+DWIDTH 18 0
+BBX 16 19 1 0
+BITMAP
+E007
+F00F
+781E
+381C
+1C38
+0E70
+0FF0
+07E0
+03C0
+03C0
+07E0
+0FF0
+0E70
+1C38
+3C3C
+381C
+700E
+F00F
+E007
+ENDCHAR
+
+STARTCHAR Y
+ENCODING 89
+SWIDTH 667 0
+DWIDTH 17 0
+BBX 15 19 1 0
+BITMAP
+E00E
+F01E
+701C
+783C
+3838
+3C78
+1C70
+1EF0
+0EE0
+0FE0
+07C0
+07C0
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+ENDCHAR
+
+STARTCHAR Z
+ENCODING 90
+SWIDTH 611 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+FFFC
+FFFC
+003C
+0078
+00F0
+01E0
+01E0
+03C0
+0780
+0780
+0F00
+1E00
+1E00
+3C00
+3800
+7800
+F000
+FFFC
+FFFC
+ENDCHAR
+
+STARTCHAR bracketleft
+ENCODING 91
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 5 24 1 -5
+BITMAP
+F8
+F8
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+F8
+F8
+ENDCHAR
+
+STARTCHAR backslash
+ENCODING 92
+SWIDTH 278 0
+DWIDTH 8 0
+BBX 8 19 0 0
+BITMAP
+E0
+E0
+60
+60
+70
+30
+30
+38
+38
+18
+18
+1C
+0C
+0C
+0E
+06
+06
+07
+07
+ENDCHAR
+
+STARTCHAR bracketright
+ENCODING 93
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 5 24 2 -5
+BITMAP
+F8
+F8
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+F8
+F8
+ENDCHAR
+
+STARTCHAR asciicircum
+ENCODING 94
+SWIDTH 584 0
+DWIDTH 14 0
+BBX 11 9 1 10
+BITMAP
+0E00
+0E00
+1F00
+1B00
+3B80
+71C0
+71C0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR underscore
+ENCODING 95
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 14 2 0 -5
+BITMAP
+FFFC
+FFFC
+ENDCHAR
+
+STARTCHAR grave
+ENCODING 96
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 6 4 1 15
+BITMAP
+E0
+70
+38
+1C
+ENDCHAR
+
+STARTCHAR a
+ENCODING 97
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+1F80
+3FC0
+71E0
+70E0
+00E0
+07E0
+3FE0
+7CE0
+F0E0
+E0E0
+E1E0
+F3E0
+7FF0
+3E70
+ENDCHAR
+
+STARTCHAR b
+ENCODING 98
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 12 19 2 0
+BITMAP
+E000
+E000
+E000
+E000
+E000
+EF80
+FFC0
+F9E0
+F0E0
+E070
+E070
+E070
+E070
+E070
+E070
+F0E0
+F9E0
+FFC0
+EF80
+ENDCHAR
+
+STARTCHAR c
+ENCODING 99
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+1F80
+3FC0
+79E0
+70E0
+E000
+E000
+E000
+E000
+E000
+E000
+70E0
+79E0
+3FC0
+1F80
+ENDCHAR
+
+STARTCHAR d
+ENCODING 100
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 12 19 1 0
+BITMAP
+0070
+0070
+0070
+0070
+0070
+1F70
+3FF0
+79F0
+70F0
+E070
+E070
+E070
+E070
+E070
+E070
+70F0
+79F0
+3FF0
+1F70
+ENDCHAR
+
+STARTCHAR e
+ENCODING 101
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+0F00
+3FC0
+79E0
+70E0
+E070
+E070
+FFF0
+FFF0
+E000
+E000
+7070
+78F0
+3FE0
+0F80
+ENDCHAR
+
+STARTCHAR f
+ENCODING 102
+SWIDTH 333 0
+DWIDTH 9 0
+BBX 7 19 1 0
+BITMAP
+1E
+3E
+38
+38
+38
+FE
+FE
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+ENDCHAR
+
+STARTCHAR g
+ENCODING 103
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 12 19 1 -5
+BITMAP
+1F70
+3FF0
+79F0
+70F0
+E070
+E070
+E070
+E070
+E070
+E070
+70F0
+79F0
+3FF0
+1F70
+0070
+E070
+F0E0
+7FE0
+1F80
+ENDCHAR
+
+STARTCHAR h
+ENCODING 104
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 11 19 2 0
+BITMAP
+E000
+E000
+E000
+E000
+E000
+EF00
+FFC0
+F1C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR i
+ENCODING 105
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 3 19 2 0
+BITMAP
+E0
+E0
+E0
+00
+00
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR j
+ENCODING 106
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 5 24 0 -5
+BITMAP
+38
+38
+38
+00
+00
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+F8
+F0
+ENDCHAR
+
+STARTCHAR k
+ENCODING 107
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 19 2 0
+BITMAP
+E000
+E000
+E000
+E000
+E000
+E1E0
+E3C0
+E780
+EF00
+FE00
+FC00
+FE00
+EF00
+E700
+E780
+E3C0
+E1C0
+E1E0
+E0F0
+ENDCHAR
+
+STARTCHAR l
+ENCODING 108
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 3 19 2 0
+BITMAP
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR m
+ENCODING 109
+SWIDTH 889 0
+DWIDTH 21 0
+BBX 17 14 2 0
+BITMAP
+EF3E00
+FFFF00
+F3E780
+E1C380
+E1C380
+E1C380
+E1C380
+E1C380
+E1C380
+E1C380
+E1C380
+E1C380
+E1C380
+E1C380
+ENDCHAR
+
+STARTCHAR n
+ENCODING 110
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 11 14 2 0
+BITMAP
+EF80
+FFC0
+F1C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR o
+ENCODING 111
+SWIDTH 611 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+0F00
+3FC0
+79E0
+70E0
+E070
+E070
+E070
+E070
+E070
+E070
+70E0
+79E0
+3FC0
+0F00
+ENDCHAR
+
+STARTCHAR p
+ENCODING 112
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 12 19 2 -5
+BITMAP
+EF80
+FFC0
+F9E0
+F0E0
+E070
+E070
+E070
+E070
+E070
+E070
+F0E0
+F9E0
+FFC0
+EF80
+E000
+E000
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR q
+ENCODING 113
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 12 19 1 -5
+BITMAP
+1F70
+3FF0
+79F0
+70F0
+E070
+E070
+E070
+E070
+E070
+E070
+70F0
+79F0
+3FF0
+1F70
+0070
+0070
+0070
+0070
+0070
+ENDCHAR
+
+STARTCHAR r
+ENCODING 114
+SWIDTH 389 0
+DWIDTH 10 0
+BBX 7 14 2 0
+BITMAP
+E6
+EE
+FE
+F0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR s
+ENCODING 115
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+3F00
+7F80
+F3C0
+E1C0
+E000
+FC00
+7F80
+0FC0
+01E0
+E0E0
+E0E0
+F1E0
+7FC0
+3F80
+ENDCHAR
+
+STARTCHAR t
+ENCODING 116
+SWIDTH 333 0
+DWIDTH 9 0
+BBX 7 18 1 0
+BITMAP
+38
+38
+38
+38
+FE
+FE
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+3E
+1E
+ENDCHAR
+
+STARTCHAR u
+ENCODING 117
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 11 14 2 0
+BITMAP
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E1E0
+73E0
+7EE0
+1CE0
+ENDCHAR
+
+STARTCHAR v
+ENCODING 118
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+E070
+E070
+E070
+70E0
+70E0
+70E0
+39C0
+39C0
+39C0
+1F80
+1F80
+0F00
+0F00
+0F00
+ENDCHAR
+
+STARTCHAR w
+ENCODING 119
+SWIDTH 778 0
+DWIDTH 19 0
+BBX 19 14 0 0
+BITMAP
+E0E0E0
+E0E0E0
+60E0C0
+71F1C0
+71F1C0
+31B180
+33B980
+3BBB80
+1B1B00
+1F1F00
+1F1F00
+0E0E00
+0E0E00
+0E0E00
+ENDCHAR
+
+STARTCHAR x
+ENCODING 120
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+E0E0
+F1E0
+71C0
+3B80
+3F80
+1F00
+0E00
+1F00
+1F00
+3B80
+7BC0
+71C0
+F1E0
+E0E0
+ENDCHAR
+
+STARTCHAR y
+ENCODING 121
+SWIDTH 556 0
+DWIDTH 15 0
+BBX 13 19 1 -5
+BITMAP
+E038
+E038
+7038
+7870
+3870
+3CF0
+1CE0
+1CE0
+0FC0
+0FC0
+07C0
+0780
+0380
+0380
+0700
+0700
+0E00
+3E00
+3C00
+ENDCHAR
+
+STARTCHAR z
+ENCODING 122
+SWIDTH 500 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FFE0
+FFE0
+01C0
+0380
+0780
+0F00
+0E00
+1E00
+3C00
+3800
+7000
+F000
+FFE0
+FFE0
+ENDCHAR
+
+STARTCHAR braceleft
+ENCODING 123
+SWIDTH 389 0
+DWIDTH 10 0
+BBX 7 24 1 -5
+BITMAP
+0E
+1C
+38
+38
+38
+38
+38
+38
+38
+38
+70
+E0
+E0
+70
+38
+38
+38
+38
+38
+38
+38
+38
+1C
+0E
+ENDCHAR
+
+STARTCHAR bar
+ENCODING 124
+SWIDTH 280 0
+DWIDTH 7 0
+BBX 3 24 2 -5
+BITMAP
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR braceright
+ENCODING 125
+SWIDTH 389 0
+DWIDTH 10 0
+BBX 7 24 2 -5
+BITMAP
+E0
+70
+38
+38
+38
+38
+38
+38
+38
+38
+1C
+0E
+0E
+1C
+38
+38
+38
+38
+38
+38
+38
+38
+70
+E0
+ENDCHAR
+
+STARTCHAR asciitilde
+ENCODING 126
+SWIDTH 584 0
+DWIDTH 14 0
+BBX 11 4 1 5
+BITMAP
+78E0
+FEE0
+EFE0
+E3C0
+ENDCHAR
+
+STARTCHAR space
+ENCODING 160
+SWIDTH 278 0
+DWIDTH 6 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+
+STARTCHAR exclamdown
+ENCODING 161
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 3 19 2 -5
+BITMAP
+E0
+E0
+E0
+00
+00
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR cent
+ENCODING 162
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 11 18 1 -2
+BITMAP
+0180
+0180
+1F80
+3FC0
+7BE0
+7360
+E300
+E600
+E600
+E600
+E600
+EC00
+ECE0
+7DE0
+7FC0
+3F80
+1800
+1800
+ENDCHAR
+
+STARTCHAR sterling
+ENCODING 163
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 13 18 0 0
+BITMAP
+1F80
+3FC0
+70E0
+70E0
+7000
+7800
+3800
+1C00
+FFC0
+FFC0
+1C00
+1C00
+1C00
+3800
+3800
+7738
+FFF8
+F9F0
+ENDCHAR
+
+STARTCHAR currency
+ENCODING 164
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 12 1 3
+BITMAP
+C030
+EF70
+7FE0
+39C0
+70E0
+70E0
+70E0
+70E0
+39C0
+7FE0
+EF70
+C030
+ENDCHAR
+
+STARTCHAR yen
+ENCODING 165
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 13 18 0 0
+BITMAP
+E038
+E038
+7070
+7070
+38E0
+38E0
+1DC0
+1DC0
+7FF0
+7FF0
+0700
+7FF0
+7FF0
+0700
+0700
+0700
+0700
+0700
+ENDCHAR
+
+STARTCHAR brokenbar
+ENCODING 166
+SWIDTH 280 0
+DWIDTH 7 0
+BBX 3 23 2 -4
+BITMAP
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+00
+00
+00
+00
+00
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR section
+ENCODING 167
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 24 1 -5
+BITMAP
+1F80
+3FC0
+79E0
+70E0
+78E0
+3C00
+1E00
+7F00
+F780
+E3C0
+E1E0
+E0E0
+7070
+7870
+3C70
+1EE0
+0FC0
+0780
+03C0
+71E0
+70E0
+79E0
+3FC0
+1F80
+ENDCHAR
+
+STARTCHAR dieresis
+ENCODING 168
+SWIDTH 333 0
+DWIDTH 9 0
+BBX 7 2 1 16
+BITMAP
+EE
+EE
+ENDCHAR
+
+STARTCHAR copyright
+ENCODING 169
+SWIDTH 737 0
+DWIDTH 19 0
+BBX 17 17 1 0
+BITMAP
+07F000
+1E3C00
+380E00
+700700
+63E300
+E73380
+CE3180
+CE0180
+CE0180
+CE0180
+CE3180
+E73180
+63E300
+700700
+380E00
+1E3C00
+07F000
+ENDCHAR
+
+STARTCHAR ordfeminine
+ENCODING 170
+SWIDTH 370 0
+DWIDTH 10 0
+BBX 8 12 1 7
+BITMAP
+7C
+FE
+C6
+1E
+7E
+E6
+C6
+FF
+7B
+00
+FF
+FF
+ENDCHAR
+
+STARTCHAR guillemotleft
+ENCODING 171
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 10 8 1 3
+BITMAP
+1DC0
+3B80
+7700
+EE00
+EE00
+7700
+3B80
+1DC0
+ENDCHAR
+
+STARTCHAR logicalnot
+ENCODING 172
+SWIDTH 584 0
+DWIDTH 15 0
+BBX 12 7 1 4
+BITMAP
+FFF0
+FFF0
+0030
+0030
+0030
+0030
+0030
+ENDCHAR
+
+STARTCHAR hyphen
+ENCODING 173
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 7 3 0 6
+BITMAP
+FE
+FE
+FE
+ENDCHAR
+
+STARTCHAR registered
+ENCODING 174
+SWIDTH 737 0
+DWIDTH 19 0
+BBX 17 17 1 0
+BITMAP
+07F000
+1E3C00
+380E00
+700700
+67E300
+E63380
+C63180
+C63180
+C7E180
+C6C180
+C66180
+E63180
+661B00
+700700
+380E00
+1E3C00
+07F000
+ENDCHAR
+
+STARTCHAR macron
+ENCODING 175
+SWIDTH 333 0
+DWIDTH 9 0
+BBX 7 2 1 17
+BITMAP
+FE
+FE
+ENDCHAR
+
+STARTCHAR degree
+ENCODING 176
+SWIDTH 400 0
+DWIDTH 9 0
+BBX 8 7 0 11
+BITMAP
+3C
+66
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+
+STARTCHAR plusminus
+ENCODING 177
+SWIDTH 584 0
+DWIDTH 15 0
+BBX 11 13 2 0
+BITMAP
+0E00
+0E00
+0E00
+0E00
+FFE0
+FFE0
+0E00
+0E00
+0E00
+0E00
+0000
+FFE0
+FFE0
+ENDCHAR
+
+STARTCHAR twosuperior
+ENCODING 178
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 6 10 0 8
+BITMAP
+78
+FC
+CC
+0C
+1C
+78
+E0
+C0
+FC
+FC
+ENDCHAR
+
+STARTCHAR threesuperior
+ENCODING 179
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 6 10 0 8
+BITMAP
+78
+FC
+CC
+0C
+38
+38
+0C
+CC
+FC
+78
+ENDCHAR
+
+STARTCHAR acute
+ENCODING 180
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 6 4 1 15
+BITMAP
+1C
+38
+70
+E0
+ENDCHAR
+
+STARTCHAR mu
+ENCODING 181
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 11 19 2 -5
+BITMAP
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E1E0
+F3E0
+FEE0
+ECE0
+E000
+E000
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR paragraph
+ENCODING 182
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 11 24 1 -5
+BITMAP
+0FE0
+3FE0
+7CC0
+7CC0
+FCC0
+FCC0
+FCC0
+FCC0
+FCC0
+7CC0
+7CC0
+3CC0
+1CC0
+0CC0
+0CC0
+0CC0
+0CC0
+0CC0
+0CC0
+0CC0
+0CC0
+0CC0
+0CC0
+0CC0
+ENDCHAR
+
+STARTCHAR periodcentered
+ENCODING 183
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 3 3 2 6
+BITMAP
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR cedilla
+ENCODING 184
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 6 6 1 -5
+BITMAP
+70
+78
+1C
+1C
+FC
+78
+ENDCHAR
+
+STARTCHAR onesuperior
+ENCODING 185
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 4 10 0 8
+BITMAP
+30
+30
+F0
+F0
+30
+30
+30
+30
+30
+30
+ENDCHAR
+
+STARTCHAR ordmasculine
+ENCODING 186
+SWIDTH 365 0
+DWIDTH 10 0
+BBX 8 12 1 7
+BITMAP
+3C
+7E
+E7
+C3
+C3
+C3
+E7
+7E
+3C
+00
+FF
+FF
+ENDCHAR
+
+STARTCHAR guillemotright
+ENCODING 187
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 10 8 1 3
+BITMAP
+EE00
+7700
+3B80
+1DC0
+1DC0
+3B80
+7700
+EE00
+ENDCHAR
+
+STARTCHAR onequarter
+ENCODING 188
+SWIDTH 834 0
+DWIDTH 19 0
+BBX 17 18 1 0
+BITMAP
+301800
+301800
+F03000
+F03000
+306000
+306000
+30C000
+30C000
+318600
+318E00
+031E00
+031E00
+063600
+066600
+0C7F80
+0C7F80
+180600
+180600
+ENDCHAR
+
+STARTCHAR onehalf
+ENCODING 189
+SWIDTH 834 0
+DWIDTH 19 0
+BBX 16 18 1 0
+BITMAP
+3018
+3018
+F030
+F030
+3060
+3060
+30C0
+30C0
+319E
+31BF
+0333
+0303
+0607
+061E
+0C38
+0C30
+183F
+183F
+ENDCHAR
+
+STARTCHAR threequarters
+ENCODING 190
+SWIDTH 834 0
+DWIDTH 19 0
+BBX 17 18 1 0
+BITMAP
+781800
+FC1800
+CC3000
+0C3000
+386000
+386000
+0CC000
+CCC000
+FD8600
+798E00
+031E00
+031E00
+063600
+066600
+0C7F80
+0C7F80
+180600
+180600
+ENDCHAR
+
+STARTCHAR questiondown
+ENCODING 191
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 11 19 2 -5
+BITMAP
+0E00
+0E00
+0E00
+0000
+0000
+0E00
+0E00
+0E00
+0E00
+1C00
+3C00
+7800
+7000
+F0E0
+E0E0
+E1E0
+F3C0
+7FC0
+3F00
+ENDCHAR
+
+STARTCHAR Agrave
+ENCODING 192
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 16 24 1 0
+BITMAP
+0E00
+0700
+0380
+01C0
+0000
+03C0
+03C0
+07E0
+07E0
+0E60
+0E70
+0E70
+1C38
+1C38
+1C38
+381C
+381C
+3FFC
+7FFE
+700E
+700E
+E007
+E007
+E007
+ENDCHAR
+
+STARTCHAR Aacute
+ENCODING 193
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 16 24 1 0
+BITMAP
+0038
+0070
+00E0
+01C0
+0000
+03C0
+03C0
+07E0
+07E0
+0E60
+0E70
+0E70
+1C38
+1C38
+1C38
+381C
+381C
+3FFC
+7FFE
+700E
+700E
+E007
+E007
+E007
+ENDCHAR
+
+STARTCHAR Acircumflex
+ENCODING 194
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 16 24 1 0
+BITMAP
+01C0
+03E0
+0770
+0E38
+0000
+03C0
+03C0
+07E0
+07E0
+0E60
+0E70
+0E70
+1C38
+1C38
+1C38
+381C
+381C
+3FFC
+7FFE
+700E
+700E
+E007
+E007
+E007
+ENDCHAR
+
+STARTCHAR Atilde
+ENCODING 195
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 16 23 1 0
+BITMAP
+0798
+0FF8
+0CF0
+0000
+03C0
+03C0
+07E0
+07E0
+0E60
+0E70
+0E70
+1C38
+1C38
+1C38
+381C
+381C
+3FFC
+7FFE
+700E
+700E
+E007
+E007
+E007
+ENDCHAR
+
+STARTCHAR Adieresis
+ENCODING 196
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 16 23 1 0
+BITMAP
+0E70
+0E70
+0000
+0000
+03C0
+03C0
+07E0
+07E0
+0E60
+0E70
+0E70
+1C38
+1C38
+1C38
+381C
+381C
+3FFC
+7FFE
+700E
+700E
+E007
+E007
+E007
+ENDCHAR
+
+STARTCHAR Aring
+ENCODING 197
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 16 23 1 0
+BITMAP
+03C0
+0660
+0660
+0660
+03C0
+03C0
+07E0
+07E0
+0E60
+0E70
+0E70
+1C38
+1C38
+1C38
+381C
+381C
+3FFC
+7FFE
+700E
+700E
+E007
+E007
+E007
+ENDCHAR
+
+STARTCHAR AE
+ENCODING 198
+SWIDTH 1000 0
+DWIDTH 24 0
+BBX 22 19 1 0
+BITMAP
+03FFF8
+03FFF8
+07F000
+067000
+0E7000
+0E7000
+0E7000
+1C7000
+1C7FF0
+1C7FF0
+387000
+387000
+3FF000
+7FF000
+707000
+707000
+E07000
+E07FFC
+E07FFC
+ENDCHAR
+
+STARTCHAR Ccedilla
+ENCODING 199
+SWIDTH 722 0
+DWIDTH 18 0
+BBX 16 24 1 -5
+BITMAP
+07F0
+1FFC
+3E3E
+780F
+7007
+F000
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+F007
+7007
+780F
+3E3E
+1FFC
+07F0
+03C0
+00E0
+00E0
+07E0
+03C0
+ENDCHAR
+
+STARTCHAR Egrave
+ENCODING 200
+SWIDTH 667 0
+DWIDTH 16 0
+BBX 13 24 2 0
+BITMAP
+7000
+3800
+1C00
+0E00
+0000
+FFF0
+FFF0
+E000
+E000
+E000
+E000
+E000
+E000
+FFE0
+FFE0
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+FFF8
+FFF8
+ENDCHAR
+
+STARTCHAR Eacute
+ENCODING 201
+SWIDTH 667 0
+DWIDTH 16 0
+BBX 13 24 2 0
+BITMAP
+00E0
+01C0
+0380
+0700
+0000
+FFF0
+FFF0
+E000
+E000
+E000
+E000
+E000
+E000
+FFE0
+FFE0
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+FFF8
+FFF8
+ENDCHAR
+
+STARTCHAR Ecircumflex
+ENCODING 202
+SWIDTH 667 0
+DWIDTH 16 0
+BBX 13 24 2 0
+BITMAP
+0700
+0F80
+1DC0
+38E0
+0000
+FFF0
+FFF0
+E000
+E000
+E000
+E000
+E000
+E000
+FFE0
+FFE0
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+FFF8
+FFF8
+ENDCHAR
+
+STARTCHAR Edieresis
+ENCODING 203
+SWIDTH 667 0
+DWIDTH 16 0
+BBX 13 23 2 0
+BITMAP
+39C0
+39C0
+0000
+0000
+FFF0
+FFF0
+E000
+E000
+E000
+E000
+E000
+E000
+FFE0
+FFE0
+E000
+E000
+E000
+E000
+E000
+E000
+E000
+FFF8
+FFF8
+ENDCHAR
+
+STARTCHAR Igrave
+ENCODING 204
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 6 24 0 0
+BITMAP
+E0
+70
+38
+1C
+00
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+ENDCHAR
+
+STARTCHAR Iacute
+ENCODING 205
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 6 24 2 0
+BITMAP
+1C
+38
+70
+E0
+00
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+E0
+ENDCHAR
+
+STARTCHAR Icircumflex
+ENCODING 206
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 9 24 -1 0
+BITMAP
+1C00
+3E00
+7700
+E380
+0000
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+ENDCHAR
+
+STARTCHAR Idieresis
+ENCODING 207
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 7 23 0 0
+BITMAP
+EE
+EE
+00
+00
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+ENDCHAR
+
+STARTCHAR Eth
+ENCODING 208
+SWIDTH 722 0
+DWIDTH 19 0
+BBX 19 19 -1 0
+BITMAP
+1FFC00
+1FFF00
+1C0F80
+1C03C0
+1C01C0
+1C01E0
+1C00E0
+1C00E0
+FFC0E0
+FFC0E0
+1C00E0
+1C00E0
+1C00E0
+1C01E0
+1C01C0
+1C03C0
+1C0F80
+1FFF00
+1FFC00
+ENDCHAR
+
+STARTCHAR Ntilde
+ENCODING 209
+SWIDTH 722 0
+DWIDTH 19 0
+BBX 15 23 2 0
+BITMAP
+0E30
+1FF0
+19E0
+0000
+E00E
+F00E
+F00E
+F80E
+F80E
+FC0E
+EE0E
+EE0E
+E70E
+E38E
+E38E
+E1CE
+E0CE
+E0EE
+E07E
+E03E
+E03E
+E01E
+E00E
+ENDCHAR
+
+STARTCHAR Ograve
+ENCODING 210
+SWIDTH 778 0
+DWIDTH 19 0
+BBX 17 24 1 0
+BITMAP
+070000
+038000
+01C000
+00E000
+000000
+07F000
+1FFC00
+3E3E00
+780F00
+700700
+F00780
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+F00780
+700700
+780F00
+3E3E00
+1FFC00
+07F000
+ENDCHAR
+
+STARTCHAR Oacute
+ENCODING 211
+SWIDTH 778 0
+DWIDTH 19 0
+BBX 17 24 1 0
+BITMAP
+003800
+007000
+00E000
+01C000
+000000
+07F000
+1FFC00
+3E3E00
+780F00
+700700
+F00780
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+F00780
+700700
+780F00
+3E3E00
+1FFC00
+07F000
+ENDCHAR
+
+STARTCHAR Ocircumflex
+ENCODING 212
+SWIDTH 778 0
+DWIDTH 19 0
+BBX 17 24 1 0
+BITMAP
+01C000
+03E000
+077000
+0E3800
+000000
+07F000
+1FFC00
+3E3E00
+780F00
+700700
+F00780
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+F00780
+700700
+780F00
+3E3E00
+1FFC00
+07F000
+ENDCHAR
+
+STARTCHAR Otilde
+ENCODING 213
+SWIDTH 778 0
+DWIDTH 19 0
+BBX 17 24 1 0
+BITMAP
+079800
+0FF800
+0CF000
+000000
+000000
+07F000
+1FFC00
+3E3E00
+780F00
+700700
+F00780
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+F00780
+700700
+780F00
+3E3E00
+1FFC00
+07F000
+ENDCHAR
+
+STARTCHAR Odieresis
+ENCODING 214
+SWIDTH 778 0
+DWIDTH 19 0
+BBX 17 23 1 0
+BITMAP
+0E3800
+0E3800
+000000
+000000
+07F000
+1FFC00
+3E3E00
+780F00
+700700
+F00780
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+E00380
+F00780
+700700
+780F00
+3E3E00
+1FFC00
+07F000
+ENDCHAR
+
+STARTCHAR multiply
+ENCODING 215
+SWIDTH 584 0
+DWIDTH 15 0
+BBX 12 12 1 1
+BITMAP
+4020
+E070
+70E0
+39C0
+1F80
+0F00
+0F00
+1F80
+39C0
+70E0
+E070
+4020
+ENDCHAR
+
+STARTCHAR Oslash
+ENCODING 216
+SWIDTH 778 0
+DWIDTH 19 0
+BBX 19 19 0 0
+BITMAP
+03F860
+0FFEE0
+1F1FC0
+3C0380
+380780
+780FC0
+701DC0
+7039C0
+7071C0
+70E1C0
+71C1C0
+7381C0
+7701C0
+7E03C0
+3C0380
+3C0780
+7F1F00
+EFFE00
+C3F800
+ENDCHAR
+
+STARTCHAR Ugrave
+ENCODING 217
+SWIDTH 722 0
+DWIDTH 19 0
+BBX 15 24 2 0
+BITMAP
+0E00
+0700
+0380
+01C0
+0000
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+F01E
+F01E
+701C
+7C7C
+3FF8
+0FE0
+ENDCHAR
+
+STARTCHAR Uacute
+ENCODING 218
+SWIDTH 722 0
+DWIDTH 19 0
+BBX 15 24 2 0
+BITMAP
+0070
+00E0
+01C0
+0380
+0000
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+F01E
+F01E
+701C
+7C7C
+3FF8
+0FE0
+ENDCHAR
+
+STARTCHAR Ucircumflex
+ENCODING 219
+SWIDTH 722 0
+DWIDTH 19 0
+BBX 15 24 2 0
+BITMAP
+0780
+0FC0
+1CE0
+3870
+0000
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+F01E
+F01E
+701C
+7C7C
+3FF8
+0FE0
+ENDCHAR
+
+STARTCHAR Udieresis
+ENCODING 220
+SWIDTH 722 0
+DWIDTH 19 0
+BBX 15 23 2 0
+BITMAP
+1C70
+1C70
+0000
+0000
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+E00E
+F01E
+F01E
+701C
+7C7C
+3FF8
+0FE0
+ENDCHAR
+
+STARTCHAR Yacute
+ENCODING 221
+SWIDTH 667 0
+DWIDTH 17 0
+BBX 15 24 1 0
+BITMAP
+0070
+00E0
+01C0
+0380
+0000
+F01E
+701C
+783C
+3838
+3C78
+1C70
+1EF0
+0EE0
+0FE0
+07C0
+07C0
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+0380
+ENDCHAR
+
+STARTCHAR Thorn
+ENCODING 222
+SWIDTH 667 0
+DWIDTH 17 0
+BBX 14 19 2 0
+BITMAP
+E000
+E000
+E000
+E000
+FFE0
+FFF8
+E038
+E01C
+E01C
+E01C
+E01C
+E038
+FFF8
+FFF0
+E000
+E000
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR germandbls
+ENCODING 223
+SWIDTH 611 0
+DWIDTH 14 0
+BBX 11 19 2 0
+BITMAP
+1E00
+7F80
+F380
+E1C0
+E1C0
+E1C0
+E1C0
+E380
+EF00
+EF80
+E3C0
+E1C0
+E0E0
+E0E0
+E0E0
+E0E0
+E1C0
+EFC0
+EF80
+ENDCHAR
+
+STARTCHAR agrave
+ENCODING 224
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+1C00
+0E00
+0700
+0380
+0000
+1F80
+3FC0
+71E0
+70E0
+00E0
+07E0
+3FE0
+7CE0
+F0E0
+E0E0
+E1E0
+F3E0
+7FF0
+3E70
+ENDCHAR
+
+STARTCHAR aacute
+ENCODING 225
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+01C0
+0380
+0700
+0E00
+0000
+1F80
+3FC0
+71E0
+70E0
+00E0
+07E0
+3FE0
+7CE0
+F0E0
+E0E0
+E1E0
+F3E0
+7FF0
+3E70
+ENDCHAR
+
+STARTCHAR acircumflex
+ENCODING 226
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+0700
+0F80
+1DC0
+38E0
+0000
+1F80
+3FC0
+71E0
+70E0
+00E0
+07E0
+3FE0
+7CE0
+F0E0
+E0E0
+E1E0
+F3E0
+7FF0
+3E70
+ENDCHAR
+
+STARTCHAR atilde
+ENCODING 227
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+1E60
+3FE0
+33C0
+0000
+0000
+1F80
+3FC0
+71E0
+70E0
+00E0
+07E0
+3FE0
+7CE0
+F0E0
+E0E0
+E1E0
+F3E0
+7FF0
+3E70
+ENDCHAR
+
+STARTCHAR adieresis
+ENCODING 228
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 18 1 0
+BITMAP
+1DC0
+1DC0
+0000
+0000
+1F80
+3FC0
+71E0
+70E0
+00E0
+07E0
+3FE0
+7CE0
+F0E0
+E0E0
+E1E0
+F3E0
+7FF0
+3E70
+ENDCHAR
+
+STARTCHAR aring
+ENCODING 229
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+0F00
+1980
+1980
+1980
+0F00
+1F80
+3FC0
+71E0
+70E0
+00E0
+07E0
+3FE0
+7CE0
+F0E0
+E0E0
+E1E0
+F3E0
+7FF0
+3E70
+ENDCHAR
+
+STARTCHAR ae
+ENCODING 230
+SWIDTH 889 0
+DWIDTH 22 0
+BBX 20 14 1 0
+BITMAP
+1F8F00
+3FFFC0
+71F9E0
+70F0E0
+00E070
+07E070
+3FFFF0
+7CFFF0
+F0E000
+E0E000
+E1F070
+F3F8F0
+7F3FE0
+3E0F80
+ENDCHAR
+
+STARTCHAR ccedilla
+ENCODING 231
+SWIDTH 556 0
+DWIDTH 13 0
+BBX 11 19 1 -5
+BITMAP
+1F80
+3FC0
+79E0
+70E0
+E000
+E000
+E000
+E000
+E000
+E000
+70E0
+79E0
+3FC0
+1F80
+1E00
+0700
+0700
+3F00
+1E00
+ENDCHAR
+
+STARTCHAR egrave
+ENCODING 232
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+1C00
+0E00
+0700
+0380
+0000
+0F00
+3FC0
+79E0
+70E0
+E070
+E070
+FFF0
+FFF0
+E000
+E000
+7070
+78F0
+3FE0
+0F80
+ENDCHAR
+
+STARTCHAR eacute
+ENCODING 233
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+01C0
+0380
+0700
+0E00
+0000
+0F00
+3FC0
+79E0
+70E0
+E070
+E070
+FFF0
+FFF0
+E000
+E000
+7070
+78F0
+3FE0
+0F80
+ENDCHAR
+
+STARTCHAR ecircumflex
+ENCODING 234
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+0700
+0F80
+1DC0
+38E0
+0000
+0F00
+3FC0
+79E0
+70E0
+E070
+E070
+FFF0
+FFF0
+E000
+E000
+7070
+78F0
+3FE0
+0F80
+ENDCHAR
+
+STARTCHAR edieresis
+ENCODING 235
+SWIDTH 556 0
+DWIDTH 14 0
+BBX 12 18 1 0
+BITMAP
+39C0
+39C0
+0000
+0000
+0F00
+3FC0
+79E0
+70E0
+E070
+E070
+FFF0
+FFF0
+E000
+E000
+7070
+78F0
+3FE0
+0F80
+ENDCHAR
+
+STARTCHAR igrave
+ENCODING 236
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 6 19 1 0
+BITMAP
+E0
+70
+38
+1C
+00
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+ENDCHAR
+
+STARTCHAR iacute
+ENCODING 237
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 6 19 1 0
+BITMAP
+1C
+38
+70
+E0
+00
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+ENDCHAR
+
+STARTCHAR icircumflex
+ENCODING 238
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 9 19 -1 0
+BITMAP
+1C00
+3E00
+7700
+E380
+0000
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+1C00
+ENDCHAR
+
+STARTCHAR idieresis
+ENCODING 239
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 7 18 0 0
+BITMAP
+EE
+EE
+00
+00
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+ENDCHAR
+
+STARTCHAR eth
+ENCODING 240
+SWIDTH 611 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+E000
+39C0
+1F00
+3E00
+C300
+0F80
+3FC0
+79E0
+70E0
+E070
+E070
+E070
+E070
+E070
+E070
+70E0
+79E0
+3FC0
+0F00
+ENDCHAR
+
+STARTCHAR ntilde
+ENCODING 241
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 11 19 2 0
+BITMAP
+3CC0
+7FC0
+6780
+0000
+0000
+EF80
+FFC0
+F1C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+ENDCHAR
+
+STARTCHAR ograve
+ENCODING 242
+SWIDTH 611 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+1C00
+0E00
+0700
+0380
+0000
+0F00
+3FC0
+79E0
+70E0
+E070
+E070
+E070
+E070
+E070
+E070
+70E0
+79E0
+3FC0
+0F00
+ENDCHAR
+
+STARTCHAR oacute
+ENCODING 243
+SWIDTH 611 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+01C0
+0380
+0700
+0E00
+0000
+0F00
+3FC0
+79E0
+70E0
+E070
+E070
+E070
+E070
+E070
+E070
+70E0
+79E0
+3FC0
+0F00
+ENDCHAR
+
+STARTCHAR ocircumflex
+ENCODING 244
+SWIDTH 611 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+0700
+0F80
+1DC0
+38E0
+0000
+0F00
+3FC0
+79E0
+70E0
+E070
+E070
+E070
+E070
+E070
+E070
+70E0
+79E0
+3FC0
+0F00
+ENDCHAR
+
+STARTCHAR otilde
+ENCODING 245
+SWIDTH 611 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+1E60
+3FE0
+33C0
+0000
+0000
+0F00
+3FC0
+79E0
+70E0
+E070
+E070
+E070
+E070
+E070
+E070
+70E0
+79E0
+3FC0
+0F00
+ENDCHAR
+
+STARTCHAR odieresis
+ENCODING 246
+SWIDTH 611 0
+DWIDTH 14 0
+BBX 12 18 1 0
+BITMAP
+1DC0
+1DC0
+0000
+0000
+0F00
+3FC0
+79E0
+70E0
+E070
+E070
+E070
+E070
+E070
+E070
+70E0
+79E0
+3FC0
+0F00
+ENDCHAR
+
+STARTCHAR divide
+ENCODING 247
+SWIDTH 584 0
+DWIDTH 15 0
+BBX 11 12 2 1
+BITMAP
+0E00
+0E00
+0E00
+0000
+0000
+FFE0
+FFE0
+0000
+0000
+0E00
+0E00
+0E00
+ENDCHAR
+
+STARTCHAR oslash
+ENCODING 248
+SWIDTH 611 0
+DWIDTH 14 0
+BBX 14 14 0 0
+BITMAP
+078C
+1FF8
+3CF0
+3870
+70F8
+71F8
+73B8
+7738
+7E38
+7C38
+3870
+7CF0
+DFE0
+8780
+ENDCHAR
+
+STARTCHAR ugrave
+ENCODING 249
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 11 19 2 0
+BITMAP
+3800
+1C00
+0E00
+0700
+0000
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E1E0
+73E0
+7EE0
+1CE0
+ENDCHAR
+
+STARTCHAR uacute
+ENCODING 250
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 11 19 2 0
+BITMAP
+0380
+0700
+0E00
+1C00
+0000
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E1E0
+73E0
+7EE0
+1CE0
+ENDCHAR
+
+STARTCHAR ucircumflex
+ENCODING 251
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 11 19 2 0
+BITMAP
+0E00
+1F00
+3B80
+71C0
+0000
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E1E0
+73E0
+7EE0
+1CE0
+ENDCHAR
+
+STARTCHAR udieresis
+ENCODING 252
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 11 18 2 0
+BITMAP
+3B80
+3B80
+0000
+0000
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+E1E0
+73E0
+7EE0
+1CE0
+ENDCHAR
+
+STARTCHAR yacute
+ENCODING 253
+SWIDTH 556 0
+DWIDTH 15 0
+BBX 13 24 1 -5
+BITMAP
+00E0
+01C0
+0380
+0700
+0000
+E038
+E038
+7038
+7870
+3870
+3CF0
+1CE0
+1CE0
+0FC0
+0FC0
+07C0
+0780
+0380
+0380
+0700
+0700
+0E00
+3E00
+3C00
+ENDCHAR
+
+STARTCHAR thorn
+ENCODING 254
+SWIDTH 611 0
+DWIDTH 15 0
+BBX 12 24 2 -5
+BITMAP
+E000
+E000
+E000
+E000
+E000
+EF80
+FFC0
+F9E0
+F0E0
+E070
+E070
+E070
+E070
+E070
+E070
+F0E0
+F9E0
+FFC0
+EF80
+E000
+E000
+E000
+E000
+E000
+ENDCHAR
+
+STARTCHAR ydieresis
+ENCODING 255
+SWIDTH 556 0
+DWIDTH 15 0
+BBX 13 23 1 -5
+BITMAP
+1CE0
+1CE0
+0000
+0000
+E038
+E038
+7038
+7870
+3870
+3CF0
+1CE0
+1CE0
+0FC0
+0FC0
+07C0
+0780
+0380
+0380
+0700
+0700
+0E00
+3E00
+3C00
+ENDCHAR
+
+ENDFONT
diff --git a/fonts/helvB24.cc b/fonts/helvB24.cc
new file mode 100644 (file)
index 0000000..8ed2c3b
Binary files /dev/null and b/fonts/helvB24.cc differ
diff --git a/fonts/licence.txt b/fonts/licence.txt
new file mode 100644 (file)
index 0000000..0c39824
--- /dev/null
@@ -0,0 +1,876 @@
+The fonts were obtained from the debian package xfree86.
+The copyright file from this package is included here.
+
+
+Package: xfree86
+Obtained from: XFree86 CVS repository (anoncvs@anoncvs.xfree86.org:/cvs)
+Upstream author(s): The XFree86 Project, Inc., et al.
+Debian package author(s): Stephen Early, Mark Eichin, Branden Robinson
+
+Debian modifications to upstream sources:
+
+  The following files were removed from the source package due to
+  non-DFSG-compliant licensing:
+    xc/fonts/scaled/Type1/COPYRIGHT.BH
+    xc/fonts/scaled/Type1/COPYRIGHT.IBM
+    xc/fonts/scaled/Type1/UTBI____.afm
+    xc/fonts/scaled/Type1/UTBI____.pfa
+    xc/fonts/scaled/Type1/UTB_____.afm
+    xc/fonts/scaled/Type1/UTB_____.pfa
+    xc/fonts/scaled/Type1/UTI_____.afm
+    xc/fonts/scaled/Type1/UTI_____.pfa
+    xc/fonts/scaled/Type1/UTRG____.afm
+    xc/fonts/scaled/Type1/UTRG____.pfa
+    xc/fonts/scaled/Type1/cour.afm
+    xc/fonts/scaled/Type1/cour.pfa
+    xc/fonts/scaled/Type1/courb.afm
+    xc/fonts/scaled/Type1/courb.pfa
+    xc/fonts/scaled/Type1/courbi.afm
+    xc/fonts/scaled/Type1/courbi.pfa
+    xc/fonts/scaled/Type1/couri.afm
+    xc/fonts/scaled/Type1/couri.pfa
+    xc/fonts/scaled/Type1/lcdxmo.afm
+    xc/fonts/scaled/Type1/lcdxmo.pfa
+    xc/fonts/scaled/Type1/lcdxmr.afm
+    xc/fonts/scaled/Type1/lcdxmr.pfa
+    xc/fonts/scaled/Type1/lcdxro.afm
+    xc/fonts/scaled/Type1/lcdxro.pfa
+    xc/fonts/scaled/Type1/lcdxrr.afm
+    xc/fonts/scaled/Type1/lcdxrr.pfa
+    xc/fonts/scaled/Type1/lcdxso.afm
+    xc/fonts/scaled/Type1/lcdxso.pfa
+    xc/fonts/scaled/Type1/lcdxsr.afm
+    xc/fonts/scaled/Type1/lcdxsr.pfa
+
+  See the debian/patches directory for all other changes to upstream
+  source.
+
+Debian copyright(s)/license(s):
+
+Unless otherwise noted, all modifications and additions to XFree86 found in
+this Debian package bear the following copyright and license terms:
+
+Copyright 1996-2001 Software in the Public Interest, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+SOFTWARE IN THE PUBLIC INTEREST, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Software in the Public
+Interest, Inc. shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization from Software in the Public Interest, Inc.
+
+Upstream copyright(s)/license(s):
+
+********************************************************************************
+
+1.  XFree86 License
+
+XFree86 code without an explicit copyright is covered by the following copy-
+right/license:
+
+Copyright (C) 1994-2001 The XFree86 Project, Inc.  All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is fur-
+nished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the XFree86 Project shall not
+be used in advertising or otherwise to promote the sale, use or other deal-
+ings in this Software without prior written authorization from the XFree86
+Project.
+
+2.  Other Licenses
+
+Portions of code are covered by the following licenses/copyrights:
+
+2.1  X Consortium
+
+Copyright (C) 1996 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is fur-
+nished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE X
+CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+X Window System is a trademark of X Consortium, Inc.
+
+2.2  Berkeley-based copyrights:
+
+2.2.1  General
+
+Redistribution and use in source and binary forms, with or without modifica-
+tion, are permitted provided that the following conditions are met:
+
+  1.  Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+  2.  Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+  3.  The name of the author may not be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+2.2.2  UCB/LBL
+
+Copyright (c) 1993 The Regents of the University of California.  All rights
+reserved.
+
+This software was developed by the Computer Systems Engineering group at
+Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and contributed to
+Berkeley.
+
+All advertising materials mentioning features or use of this software must
+display the following acknowledgement: This product includes software devel-
+oped by the University of California, Lawrence Berkeley Laboratory.
+
+Redistribution and use in source and binary forms, with or without modifica-
+tion, are permitted provided that the following conditions are met:
+
+  1.  Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+  2.  Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+  3.  All advertising materials mentioning features or use of this software
+      must display the following acknowledgement: This product includes soft-
+      ware developed by the University of California, Berkeley and its con-
+      tributors.
+
+  4.  Neither the name of the University nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DIS-
+CLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+2.3  NVIDIA Corp
+
+Copyright (c) 1996 NVIDIA, Corp.  All rights reserved.
+
+NOTICE TO USER: The source code is copyrighted under U.S. and international
+laws.  NVIDIA, Corp. of Sunnyvale, California owns the copyright and as
+design patents pending on the design and interface of the NV chips.  Users
+and possessors of this source code are hereby granted a nonexclusive, roy-
+alty-free copyright and design patent license to use this code in individual
+and commercial software.
+
+Any use of this source code must include, in the user documentation and
+internal comments to the code, notices to the end user as follows:
+
+Copyright (c) 1996 NVIDIA, Corp.  NVIDIA design patents pending in the U.S.
+and foreign countries.
+
+NVIDIA, CORP.  MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
+CODE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WAR-
+RANTY OF ANY KIND.  NVIDIA, CORP. DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA, CORP.  BE LIABLE
+FOR ANY SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAM-
+AGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.
+
+2.4  GLX Public License
+
+GLX PUBLIC LICENSE (Version 1.0 (2/11/99)) ("License")
+
+Subject to any third party claims, Silicon Graphics, Inc. ("SGI") hereby
+grants permission to Recipient (defined below), under Recipient's copyrights
+in the Original Software (defined below), to use, copy, modify, merge, pub-
+lish, distribute, sublicense and/or sell copies of Subject Software (defined
+below), and to permit persons to whom the Subject Software is furnished in
+accordance with this License to do the same, subject to all of the following
+terms and conditions, which Recipient accepts by engaging in any such use,
+copying, modifying, merging, publishing, distributing, sublicensing or sell-
+ing:
+
+1. Definitions.
+
+     (a) "Original Software" means source code of computer software code
+     which is described in Exhibit A as Original Software.
+
+     (b) "Modifications" means any addition to or deletion from the sub-
+     stance or structure of either the Original Software or any previous
+     Modifications. When Subject Software is released as a series of
+     files, a Modification means (i) any addition to or deletion from
+     the contents of a file containing Original Software or previous
+     Modifications and (ii) any new file that contains any part of the
+     Original Code or previous Modifications.
+
+     (c) "Subject Software" means the Original Software or Modifications
+     or the combination of the Original Software and Modifications, or
+     portions of any of the foregoing.
+
+     (d) "Recipient" means an individual or a legal entity exercising
+     rights under, and complying with all of the terms of, this License.
+     For legal entities, "Recipient" includes any entity which controls,
+     is controlled by, or is under common control with Recipient. For
+     purposes of this definition, "control" of an entity means (a) the
+     power, direct or indirect, to direct or manage such entity, or (b)
+     ownership of fifty percent (50%) or more of the outstanding shares
+     or beneficial ownership of such entity.
+
+2. Redistribution of Source Code Subject to These Terms. Redistributions of
+Subject Software in source code form must retain the notice set forth in
+Exhibit A, below, in every file. A copy of this License must be included in
+any documentation for such Subject Software where the recipients' rights
+relating to Subject Software are described. Recipient may distribute the
+source code version of Subject Software under a license of Recipient's
+choice, which may contain terms different from this License, provided that
+(i) Recipient is in compliance with the terms of this License, and (ii) the
+license terms include this Section 2 and Sections 3, 4, 7, 8, 10, 12 and 13
+of this License, which terms may not be modified or superseded by any other
+terms of such license. If Recipient distributes the source code version under
+a different license Recipient must make it absolutely clear that any terms
+which differ from this License are offered by Recipient alone, not by SGI.
+Recipient hereby agrees to indemnify SGI for any liability incurred by SGI as
+a result of any such terms Recipient offers.
+
+3. Redistribution in Executable Form. The notice set forth in Exhibit A must
+be conspicuously included in any notice in an executable version of Subject
+Software, related documentation or collateral in which Recipient describes
+the user's rights relating to the Subject Software. Recipient may distribute
+the executable version of Subject Software under a license of Recipient's
+choice, which may contain terms different from this License, provided that
+(i) Recipient is in compliance with the terms of this License, and (ii) the
+license terms include this Section 3 and Sections 4, 7, 8, 10, 12 and 13 of
+this License, which terms may not be modified or superseded by any other
+terms of such license. If Recipient distributes the executable version under
+a different license Recipient must make it absolutely clear that any terms
+which differ from this License are offered by Recipient alone, not by SGI.
+Recipient hereby agrees to indemnify SGI for any liability incurred by SGI as
+a result of any such terms Recipient offers.
+
+4. Termination. This License and the rights granted hereunder will terminate
+automatically if Recipient fails to comply with terms herein and fails to
+cure such breach within 30 days of the breach. Any sublicense to the Subject
+Software which is properly granted shall survive any termination of this
+License absent termination by the terms of such sublicense. Provisions which,
+by their nature, must remain in effect beyond the termination of this License
+shall survive.
+
+5. No Trademark Rights. This License does not grant any rights to use any
+trade name, trademark or service mark whatsoever. No trade name, trademark or
+service mark of SGI may be used to endorse or promote products derived from
+the Subject Software without prior written permission of SGI.
+
+6. No Other Rights. This License does not grant any rights with respect to
+the OpenGL API or to any software or hardware implementation thereof or to
+any other software whatsoever, nor shall any other rights or licenses not
+expressly granted hereunder arise by implication, estoppel or otherwise with
+respect to the Subject Software. Title to and ownership of the Original Soft-
+ware at all times remains with SGI. All rights in the Original Software not
+expressly granted under this License are reserved.
+
+7. Compliance with Laws; Non-Infringement. Recipient shall comply with all
+applicable laws and regulations in connection with use and distribution of
+the Subject Software, including but not limited to, all export and import
+control laws and regulations of the U.S. government and other countries.
+Recipient may not distribute Subject Software that (i) in any way infringes
+(directly or contributorily) the rights (including patent, copyright, trade
+secret, trademark or other intellectual property rights of any kind) of any
+other person or entity or (ii) breaches any representation or warranty,
+express, implied or statutory, which under any applicable law it might be
+deemed to have been distributed.
+
+8. Claims of Infringement. If Recipient at any time has knowledge of any one
+or more third party claims that reproduction, modification, use, distribu-
+tion, import or sale of Subject Software (including particular functionality
+or code incorporated in Subject Software) infringes the third party's intel-
+lectual property rights, Recipient must place in a well-identified web page
+bearing the title "LEGAL" a description of each such claim and a description
+of the party making each such claim in sufficient detail that a user of the
+Subject Software will know whom to contact regarding the claim. Also, upon
+gaining such knowledge of any such claim, Recipient must conspicuously
+include the URL for such web page in the Exhibit A notice required under Sec-
+tions 2 and 3, above, and in the text of any related documentation, license
+agreement or collateral in which Recipient describes end user's rights relat-
+ing to the Subject Software. If Recipient obtains such knowledge after it
+makes Subject Software available to any other person or entity, Recipient
+shall take other steps (such as notifying appropriate mailing lists or news-
+groups) reasonably calculated to inform those who received the Subject Soft-
+ware that new knowledge has been obtained.
+
+9. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT
+LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS, MER-
+CHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON- INFRINGING. SGI ASSUMES NO
+RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE. SHOULD ANY SOFTWARE
+PROVE DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY SER-
+VICING, REPAIR OR CORRECTION.  THIS DISCLAIMER OF WARRANTY CONSTITUTES AN
+ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED
+HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+10. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THE-
+ORY, WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIA-
+BILITY), CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR BE LIABLE FOR
+ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK
+STOPPAGE, LOSS OF DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF
+THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY
+TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SGI's NEGLIGENCE TO
+THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO
+NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES,
+SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO RECIPIENT.
+
+11. Indemnity. Recipient shall be solely responsible for damages arising,
+directly or indirectly, out of its utilization of rights under this License.
+Recipient will defend, indemnify and hold harmless Silicon Graphics, Inc.
+from and against any loss, liability, damages, costs or expenses (including
+the payment of reasonable attorneys fees) arising out of Recipient's use,
+modification, reproduction and distribution of the Subject Software or out of
+any representation or warranty made by Recipient.
+
+12. U.S. Government End Users. The Subject Software is a "commercial item"
+consisting of "commercial computer software" as such terms are defined in
+title 48 of the Code of Federal Regulations and all U.S.  Government End
+Users acquire only the rights set forth in this License and are subject to
+the terms of this License.
+
+13. Miscellaneous. This License represents the complete agreement concerning
+subject matter hereof. If any provision of this License is held to be unen-
+forceable, such provision shall be reformed so as to achieve as nearly as
+possible the same economic effect as the original provision and the remainder
+of this License will remain in effect. This License shall be governed by and
+construed in accordance with the laws of the United States and the State of
+California as applied to agreements entered into and to be performed entirely
+within California between California residents. Any litigation relating to
+this License shall be subject to the exclusive jurisdiction of the Federal
+Courts of the Northern District of California (or, absent subject matter
+jurisdiction in such courts, the courts of the State of California), with
+venue lying exclusively in Santa Clara County, California, with the losing
+party responsible for costs, including without limitation, court costs and
+reasonable attorneys fees and expenses. The application of the United Nations
+Convention on Contracts for the International Sale of Goods is expressly
+excluded. Any law or regulation which provides that the language of a con-
+tract shall be construed against the drafter shall not apply to this License.
+
+Exhibit A
+
+The contents of this file are subject to Sections 2, 3, 4, 7, 8, 10, 12 and
+13 of the GLX Public License Version 1.0 (the "License"). You may not use
+this file except in compliance with those sections of the License. You may
+obtain a copy of the License at Silicon Graphics, Inc., attn: Legal Services,
+2011 N. Shoreline Blvd., Mountain View, CA 94043 or at
+http://www.sgi.com/software/opensource/glx/license.html.
+
+Software distributed under the License is distributed on an "AS IS" basis.
+ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED
+WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF NON-
+INFRINGEMENT. See the License for the specific language governing rights and
+limitations under the License.
+
+The Original Software is GLX version 1.2 source code, released February,
+1999. The developer of the Original Software is Silicon Graphics, Inc.  Those
+portions of the Subject Software created by Silicon Graphics, Inc.  are Copy-
+right (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+
+2.5  CID Font Code Public License
+
+CID FONT CODE PUBLIC LICENSE (Version 1.0 (3/31/99))("License")
+
+Subject to any applicable third party claims, Silicon Graphics, Inc. ("SGI")
+hereby grants permission to Recipient (defined below), under SGI's copyrights
+in the Original Software (defined below), to use, copy, modify, merge, pub-
+lish, distribute, sublicense and/or sell copies of Subject Software (defined
+below) in both source code and executable form, and to permit persons to whom
+the Subject Software is furnished in accordance with this License to do the
+same, subject to all of the following terms and conditions, which Recipient
+accepts by engaging in any such use, copying, modifying, merging, publica-
+tion, distributing, sublicensing or selling:
+
+1. Definitions.
+
+     a. "Original Software" means source code of computer software code
+     that is described in Exhibit A as Original Software.
+
+     b. "Modifications" means any addition to or deletion from the sub-
+     stance or structure of either the Original Software or any previous
+     Modifications. When Subject Software is released as a series of
+     files, a Modification means (i) any addition to or deletion from
+     the contents of a file containing Original Software or previous
+     Modifications and (ii) any new file that contains any part of the
+     Original Code or previous Modifications.
+
+     c. "Subject Software" means the Original Software or Modifications
+     or the combination of the Original Software and Modifications, or
+     portions of any of the foregoing.
+
+     d. "Recipient" means an individual or a legal entity exercising
+     rights under the terms of this License. For legal entities, "Recip-
+     ient" includes any entity that controls, is controlled by, or is
+     under common control with Recipient. For purposes of this defini-
+     tion, "control" of an entity means (i) the power, direct or indi-
+     rect, to direct or manage such entity, or (ii) ownership of fifty
+     percent (50%) or more of the outstanding shares or beneficial own-
+     ership of such entity.
+
+     e. "Required Notice" means the notice set forth in Exhibit A to
+     this License.
+
+     f. "Accompanying Technology" means any software or other technology
+     that is not a Modification and that is distributed or made publicly
+     available by Recipient with the Subject Software.  Separate soft-
+     ware files that do not contain any Original Software or any previ-
+     ous Modification shall not be deemed a Modification, even if such
+     software files are aggregated as part of a product, or in any
+     medium of storage, with any file that does contain Original Soft-
+     ware or any previous Modification.
+
+2. License Terms. All distribution of the Subject Software must be made sub-
+ject to the terms of this License. A copy of this License and the Required
+Notice must be included in any documentation for Subject Software where
+Recipient's rights relating to Subject Software and/or any Accompanying Tech-
+nology are described. Distributions of Subject Software in source code form
+must also include the Required Notice in every file distributed. In addition,
+a ReadMe file entitled "Important Legal Notice" must be distributed with each
+distribution of one or more files that incorporate Subject Software. That
+file must be included with distributions made in both source code and exe-
+cutable form. A copy of the License and the Required Notice must be included
+in that file.  Recipient may distribute Accompanying Technology under a
+license of Recipient's choice, which may contain terms different from this
+License, provided that (i) Recipient is in compliance with the terms of this
+License, (ii) such other license terms do not modify or supersede the terms
+of this License as applicable to the Subject Software, (iii) Recipient hereby
+indemnifies SGI for any liability incurred by SGI as a result of the distri-
+bution of Accompanying Technology or the use of other license terms.
+
+3. Termination. This License and the rights granted hereunder will terminate
+automatically if Recipient fails to comply with terms herein and fails to
+cure such breach within 30 days of the breach. Any sublicense to the Subject
+Software that is properly granted shall survive any termination of this
+License absent termination by the terms of such sublicense. Provisions which,
+by their nature, must remain in effect beyond the termination of this License
+shall survive.
+
+4. Trademark Rights. This License does not grant any rights to use any trade
+name, trademark or service mark whatsoever. No trade name, trademark or ser-
+vice mark of SGI may be used to endorse or promote products derived from or
+incorporating any Subject Software without prior written permission of SGI.
+
+5. No Other Rights. No rights or licenses not expressly granted hereunder
+shall arise by implication, estoppel or otherwise. Title to and ownership of
+the Original Software at all times remains with SGI. All rights in the Origi-
+nal Software not expressly granted under this License are reserved.
+
+6. Compliance with Laws; Non-Infringement. Recipient shall comply with all
+applicable laws and regulations in connection with use and distribution of
+the Subject Software, including but not limited to, all export and import
+control laws and regulations of the U.S. government and other countries.
+Recipient may not distribute Subject Software that (i) in any way infringes
+(directly or contributorily) the rights (including patent, copyright, trade
+secret, trademark or other intellectual property rights of any kind) of any
+other person or entity, or (ii) breaches any representation or warranty,
+express, implied or statutory, which under any applicable law it might be
+deemed to have been distributed.
+
+7. Claims of Infringement. If Recipient at any time has knowledge of any one
+or more third party claims that reproduction, modification, use, distribu-
+tion, import or sale of Subject Software (including particular functionality
+or code incorporated in Subject Software) infringes the third party's intel-
+lectual property rights, Recipient must place in a well-identified web page
+bearing the title "LEGAL" a description of each such claim and a description
+of the party making each such claim in sufficient detail that a user of the
+Subject Software will know whom to contact regarding the claim. Also, upon
+gaining such knowledge of any such claim, Recipient must conspicuously
+include the URL for such web page in the Required Notice, and in the text of
+any related documentation, license agreement or collateral in which Recipient
+describes end user's rights relating to the Subject Software. If Recipient
+obtains such knowledge after it makes Subject Software available to any other
+person or entity, Recipient shall take other steps (such as notifying appro-
+priate mailing lists or newsgroups) reasonably calculated to provide such
+knowledge to those who received the Subject Software.
+
+8. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT
+LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS, MER-
+CHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. SGI ASSUMES NO
+RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE. SHOULD ANY SOFTWARE
+PROVE DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY SER-
+VICING, REPAIR OR CORRECTION.  THIS DISCLAIMER OF WARRANTY CONSTITUTES AN
+ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED
+HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY,
+WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIABILITY),
+CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SUBJECT SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SUBJECT SOFTWARE. SOME JURISDICTIONS DO NOT
+ALLOW THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES, SO THIS EXCLUSION AND
+LIMITATION MAY NOT APPLY TO RECIPIENT TO THE EXTENT SO DISALLOWED.
+
+10. Indemnity. Recipient shall be solely responsible for damages arising,
+directly or indirectly, out of its utilization of rights under this License.
+Recipient will defend, indemnify and hold SGI and its successors and assigns
+harmless from and against any loss, liability, damages, costs or expenses
+(including the payment of reasonable attorneys fees) arising out of (Recipi-
+ent's use, modification, reproduction and distribution of the Subject Soft-
+ware or out of any representation or warranty made by Recipient.
+
+11. U.S. Government End Users. The Subject Software is a "commercial item"
+consisting of "commercial computer software" as such terms are defined in
+title 48 of the Code of Federal Regulations and all U.S. Government End Users
+acquire only the rights set forth in this License and are subject to the
+terms of this License.
+
+12. Miscellaneous. This License represents the complete agreement concerning
+subject matter hereof. If any provision of this License is held to be unen-
+forceable by any judicial or administrative authority having proper jurisdic-
+tion with respect thereto, such provision shall be reformed so as to achieve
+as nearly as possible the same economic effect as the original provision and
+the remainder of this License will remain in effect. This License shall be
+governed by and construed in accordance with the laws of the United States
+and the State of California as applied to agreements entered into and to be
+performed entirely within California between California residents. Any liti-
+gation relating to this License shall be subject to the exclusive jurisdic-
+tion of the Federal Courts of the Northern District of California (or, absent
+subject matter jurisdiction in such courts, the courts of the State of Cali-
+fornia), with venue lying exclusively in Santa Clara County, California, with
+the losing party responsible for costs, including without limitation, court
+costs and reasonable attorneys fees and expenses. The application of the
+United Nations Convention on Contracts for the International Sale of Goods is
+expressly excluded. Any law or regulation that provides that the language of
+a contract shall be construed against the drafter shall not apply to this
+License.
+
+Exhibit A
+
+Copyright (c) 1994-1999 Silicon Graphics, Inc.
+
+The contents of this file are subject to the CID Font Code Public License
+Version 1.0 (the "License"). You may not use this file except in compliance
+with the License. You may obtain a copy of the License at Silicon Graphics,
+Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+or at http://www.sgi.com/software/opensource/cid/license.html
+
+Software distributed under the License is distributed on an "AS IS" basis.
+ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED
+WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF NON-
+INFRINGEMENT. See the License for the specific language governing rights and
+limitations under the License.
+
+The Original Software (as defined in the License) is CID font code that was
+developed by Silicon Graphics, Inc. Those portions of the Subject Software
+(as defined in the License) that were created by Silicon Graphics, Inc. are
+Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved.
+
+[NOTE: When using this text in connection with Subject Software delivered
+solely in object code form, Recipient may replace the words "this file" with
+"this software" in both the first and second sentences.]
+
+Additional copyright(s)/license(s):
+
+********************************************************************************
+
+SGI FREE SOFTWARE LICENSE B (Version 1.1 [02/22/2000])
+
+1. Definitions.
+
+1.1. "Additional Notice Provisions" means such additional provisions as
+appear in the Notice in Original Code under the heading "Additional Notice
+Provisions."
+1.2. "Covered Code" means the Original Code or Modifications, or any
+combination thereof.
+1.3. "Hardware" means any physical device that accepts input, processes
+input, stores the results of processing, and/or provides output.
+1.4. "Larger Work" means a work that combines Covered Code or portions
+thereof with code not governed by the terms of this License.
+1.5. "Licensable" means having the right to grant, to the maximum extent
+possible, whether at the time of the initial grant or subsequently
+acquired, any and all of the rights conveyed herein.
+1.6. "License" means this document.
+1.7. "Licensed Patents" means patent claims Licensable by SGI that are
+infringed by the use or sale of Original Code or any Modifications provided
+by SGI, or any combination thereof.
+1.8. "Modifications" means any addition to or deletion from the substance
+or structure of the Original Code or any previous Modifications. When
+Covered Code is released as a series of files, a Modification is:
+  A. Any addition to the contents of a file containing Original Code and/or
+  addition to or deletion from the contents of a file containing previous
+  Modifications.
+  B. Any new file that contains any part of the Original Code or previous
+  Modifications.
+1.9. "Notice" means any notice in Original Code or Covered Code, as
+required by and in compliance with this License.
+1.10. "Original Code" means source code of computer software code that is
+described in the source code Notice required by Exhibit A as Original Code,
+and updates and error corrections specifically thereto.
+1.11. "Recipient" means an individual or a legal entity exercising rights
+under, and complying with all of the terms of, this License or a future
+version of this License issued under Section 8.  For legal entities,
+"Recipient" includes any entity that controls, is controlled by, or is
+under common control with Recipient. For purposes of this definition,
+"control" of an entity means (a) the power, direct or indirect, to direct
+or manage such entity, or (b) ownership of fifty percent (50%) or more of
+the outstanding shares or beneficial ownership of such entity.
+1.12. "Recipient Patents" means patent claims Licensable by a Recipient
+that are infringed by the use or sale of Original Code or any Modifications
+provided by SGI, or any combination thereof.
+1.13. "SGI" means Silicon Graphics, Inc.
+1.14. "SGI Patents" means patent claims Licensable by SGI other than the
+Licensed Patents.
+
+2. License Grant and Restrictions.
+
+2.1. SGI License Grant. Subject to the terms of this License and any third
+party intellectual property claims, for the duration of intellectual
+property protections inherent in the Original Code, SGI hereby grants
+Recipient a worldwide, royalty­free, non­exclusive license, to do the
+following: (i) under copyrights Licensable by SGI, to reproduce,
+distribute, create derivative works from, and, to the extent applicable,
+display and perform the Original Code and/or any Modifications provided by
+SGI alone and/or as part of a Larger Work; and (ii) under any Licensable
+Patents, to make, have made, use, sell, offer for sale, import and/or
+otherwise transfer the Original Code and/or any Modifications provided by
+SGI. Recipient accepts the terms and conditions of this License by
+undertaking any of the aforementioned actions.  The patent license shall
+apply to the Covered Code if, at the time any related Modification is
+added, such addition of the Modification causes such combination to be
+covered by the Licensed Patents. The patent license in Section 2.1(ii)
+shall not apply to any other combinations that include the Modification.
+No patent license is provided under SGI Patents for infringements of SGI
+Patents by Modifications not provided by SGI or combinations of Original
+Code and Modifications not provided by SGI.
+
+2.2. Recipient License Grant. Subject to the terms of this License and any
+third party intellectual property claims, Recipient hereby grants SGI and
+any other Recipients a worldwide, royalty­free, non­exclusive license,
+under any Recipient Patents, to make, have made, use, sell, offer for sale,
+import and/or otherwise transfer the Original Code and/or any Modifications
+provided by SGI.
+
+2.3. No License For Hardware Implementations. The licenses granted in
+Section 2.1 and 2.2 are not applicable to implementation in Hardware of the
+algorithms embodied in the Original Code or any Modifications provided by
+SGI .
+
+3. Redistributions.
+
+3.1. Retention of Notice/Copy of License. The Notice set forth in Exhibit
+A, below, must be conspicuously retained or included in any and all
+redistributions of Covered Code. For distributions of the Covered Code in
+source code form, the Notice must appear in every file that can include a
+text comments field; in executable form, the Notice and a copy of this
+License must appear in related documentation or collateral where the
+Recipient's rights relating to Covered Code are described. Any Additional
+Notice Provisions which actually appears in the Original Code must also be
+retained or included in any and all redistributions of Covered Code.
+
+3.2. Alternative License. Provided that Recipient is in compliance with the
+terms of this License, Recipient may, so long as without derogation of any
+of SGI's rights in and to the Original Code, distribute the source code
+and/or executable version(s) of Covered Code under (1) this License; (2) a
+license identical to this License but for only such changes as are
+necessary in order to clarify Recipient's role as licensor of
+Modifications; and/or (3) a license of Recipient's choosing, containing
+terms different from this License, provided that the license terms include
+this Section 3 and Sections 4, 6, 7, 10, 12, and 13, which terms may not be
+modified or superseded by any other terms of such license. If Recipient
+elects to use any license other than this License, Recipient must make it
+absolutely clear that any of its terms which differ from this License are
+offered by Recipient alone, and not by SGI. It is emphasized that this
+License is a limited license, and, regardless of the license form employed
+by Recipient in accordance with this Section 3.2, Recipient may relicense
+only such rights, in Original Code and Modifications by SGI, as it has
+actually been granted by SGI in this License.
+
+3.3. Indemnity. Recipient hereby agrees to indemnify SGI for any liability
+incurred by SGI as a result of any such alternative license terms Recipient
+offers.
+
+4. Termination. This License and the rights granted hereunder will
+terminate automatically if Recipient breaches any term herein and fails to
+cure such breach within 30 days thereof. Any sublicense to the Covered Code
+that is properly granted shall survive any termination of this License,
+absent termination by the terms of such sublicense. Provisions that, by
+their nature, must remain in effect beyond the termination of this License,
+shall survive.
+
+5. No Trademark Or Other Rights. This License does not grant any rights to:
+(i) any software apart from the Covered Code, nor shall any other rights or
+licenses not expressly granted hereunder arise by implication, estoppel or
+otherwise with respect to the Covered Code; (ii) any trade name, trademark
+or service mark whatsoever, including without limitation any related right
+for purposes of endorsement or promotion of products derived from the
+Covered Code, without prior written permission of SGI; or (iii) any title
+to or ownership of the Original Code, which shall at all times remains with
+SGI. All rights in the Original Code not expressly granted under this
+License are reserved.
+
+6. Compliance with Laws; Non­Infringement. There are various worldwide
+laws, regulations, and executive orders applicable to dispositions of
+Covered Code, including without limitation export, re­export, and import
+control laws, regulations, and executive orders, of the U.S. government and
+other countries, and Recipient is reminded it is obliged to obey such laws,
+regulations, and executive orders. Recipient may not distribute Covered
+Code that (i) in any way infringes (directly or contributorily) any
+intellectual property rights of any kind of any other person or entity or
+(ii) breaches any representation or warranty, express, implied or
+statutory, to which, under any applicable law, it might be deemed to have
+been subject.
+
+7. Claims of Infringement. If Recipient learns of any third party claim
+that any disposition of Covered Code and/or functionality wholly or
+partially infringes the third party's intellectual property rights,
+Recipient will promptly notify SGI of such claim.
+
+8. Versions of the License. SGI may publish revised and/or new versions of
+the License from time to time, each with a distinguishing version number.
+Once Covered Code has been published under a particular version of the
+License, Recipient may, for the duration of the license, continue to use it
+under the terms of that version, or choose to use such Covered Code under
+the terms of any subsequent version published by SGI. Subject to the
+provisions of Sections 3 and 4 of this License, only SGI may modify the
+terms applicable to Covered Code created under this License.
+
+9. DISCLAIMER OF WARRANTY. COVERED CODE IS PROVIDED "AS IS." ALL EXPRESS
+AND IMPLIED WARRANTIES AND CONDITIONS ARE DISCLAIMED, INCLUDING, WITHOUT
+LIMITATION, ANY IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY,
+SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+NON­INFRINGEMENT. SGI ASSUMES NO RISK AS TO THE QUALITY AND PERFORMANCE OF
+THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, SGI
+ASSUMES NO COST OR LIABILITY FOR SERVICING, REPAIR OR CORRECTION. THIS
+DISCLAIMER OF WARRANTY IS AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY
+COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT SUBJECT TO THIS DISCLAIMER.
+
+10. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES NOR LEGAL THEORY,
+WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT
+LIABILITY), CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR BE LIABLE
+FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF
+ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+WORK STOPPAGE, LOSS OF DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND
+ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY
+SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM
+SGI's NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION.
+SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL
+OR CONSEQUENTIAL DAMAGES, SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO
+RECIPIENT.
+
+11. Indemnity. Recipient shall be solely responsible for damages arising,
+directly or indirectly, out of its utilization of rights under this
+License. Recipient will defend, indemnify and hold harmless Silicon
+Graphics, Inc. from and against any loss, liability, damages, costs or
+expenses (including the payment of reasonable attorneys fees) arising out
+of Recipient's use, modification, reproduction and distribution of the
+Covered Code or out of any representation or warranty made by Recipient.
+
+12. U.S. Government End Users. The Covered Code is a "commercial item"
+consisting of "commercial computer software" as such terms are defined in
+title 48 of the Code of Federal Regulations and all U.S. Government End
+Users acquire only the rights set forth in this License and are subject to
+the terms of this License.
+
+13. Miscellaneous. This License represents the complete agreement
+concerning the its subject matter. If any provision of this License is held
+to be unenforceable, such provision shall be reformed so as to achieve as
+nearly as possible the same legal and economic effect as the original
+provision and the remainder of this License will remain in effect.  This
+License shall be governed by and construed in accordance with the laws of
+the United States and the State of California as applied to agreements
+entered into and to be performed entirely within California between
+California residents. Any litigation relating to this License shall be
+subject to the exclusive jurisdiction of the Federal Courts of the Northern
+District of California (or, absent subject matter jurisdiction in such
+courts, the courts of the State of California), with venue lying
+exclusively in Santa Clara County, California, with the losing party
+responsible for costs, including without limitation, court costs and
+reasonable attorneys fees and expenses. The application of the United
+Nations Convention on Contracts for the International Sale of Goods is
+expressly excluded. Any law or regulation that provides that the language
+of a contract shall be construed against the drafter shall not apply to
+this License.
+
+Exhibit A License Applicability.
+
+Except to the extent portions of this file are made subject to an
+alternative license as permitted in the SGI Free Software License B,
+Version 1.1 (the "License"), the contents of this file are subject only to
+the provisions of the License.  You may not use this file except in
+compliance with the License.  You may obtain a copy of the License at
+Silicon Graphics, Inc., attn: Legal Services, 1600 Amphitheatre Parkway,
+Mountain View, CA 94043­1351, or at: http://oss.sgi.com/projects/FreeB Note
+that, as provided in the License, the Software is distributed on an "AS IS"
+basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS DISCLAIMED,
+INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND CONDITIONS OF
+MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE,
+AND NON­INFRINGEMENT.  Original Code. The Original Code is: [name of
+software, version number, and release date], developed by Silicon Graphics,
+Inc. The Original Code is Copyright (c) [dates of first publication, as
+appearing in the Notice in the Original Code] Silicon Graphics, Inc.
+Copyright in any portions created by third parties is as indicated
+elsewhere herein. All Rights Reserved.
+
+Additional Notice Provisions:
+
+[such additional provisions, if any, as appear in the Notice in the
+Original Code under the heading "Additional Notice Provisions"]
diff --git a/led.cc b/led.cc
new file mode 100644 (file)
index 0000000..8f49364
--- /dev/null
+++ b/led.cc
@@ -0,0 +1,75 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "led.h"
+
+Led* Led::instance = NULL;
+
+Led::Led()
+{
+  if (instance) return;
+  instance = this;
+  initted = 0;
+  device = 0;
+}
+
+Led::~Led()
+{
+  instance = NULL;
+}
+
+Led* Led::getInstance()
+{
+  return instance;
+}
+
+int Led::init(int device)
+{
+  if (initted) return 0;
+  initted = 1;
+  this->device = device;
+  return 1;
+}
+
+int Led::shutdown()
+{
+  if (!initted) return 0;
+  initted = 0;
+  device = 0;
+  return 1;
+}
+
+int Led::on()
+{
+  if (!initted) return 0;
+
+  int result = ioctl(device, IR_SET_LED, 0);
+  if (result >= 0) return 1;
+  else return 0;
+}
+
+int Led::off()
+{
+  if (!initted) return 0;
+
+  int result = ioctl(device, IR_SET_LED, 1);
+  if (result >= 0) return 1;
+  else return 0;
+}
diff --git a/led.h b/led.h
new file mode 100644 (file)
index 0000000..4b67e0b
--- /dev/null
+++ b/led.h
@@ -0,0 +1,48 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef LED_H
+#define LED_H
+
+#include <stdio.h>
+#include <sys/ioctl.h>
+
+#include "stb.h"
+
+class Led
+{
+  public:
+    Led();
+    ~Led();
+    static Led* getInstance();
+
+    int init(int device);
+    int shutdown();
+
+    int on();
+    int off();
+
+  private:
+    static Led* instance;
+    int initted;
+    int device;
+};
+
+#endif
diff --git a/list.cc b/list.cc
new file mode 100644 (file)
index 0000000..39a049d
--- /dev/null
+++ b/list.cc
@@ -0,0 +1,170 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "list.h"
+
+// ------ Constructor add delete get methods -------------------------------------
+
+List::List(void)
+{
+  start = NULL;
+  current = NULL;
+  prev = NULL;
+  numElements = 0;
+}
+
+List::~List()
+{
+  while (!isEmpty())
+  {
+    reset();
+    remove();
+  }
+  numElements = 0;
+}
+
+void List::add(void *newData)
+{
+  Node *temp = new Node(newData, current);
+  current = temp;
+  if (prev == 0)
+    start = current;
+  else
+    prev->setPtr(current);
+  ++numElements;
+}
+
+void *List::getCurrent(void) const
+{
+  if (current == 0) return 0;
+  else return current->getData();
+}
+
+void *List::remove(void)
+{
+  if (current == 0) return 0;
+  Node *dN;
+
+  if (prev == 0)
+    start = current->getPtr();
+  else
+    prev->setPtr(current->getPtr());
+  dN = current;
+  current = current->getPtr();
+
+  // saved a reference to the Node in dN and current points to where it should
+  // that's dN out of the list but it still needs to be deleted, and what it
+  // points to
+
+  void *returnObject;
+  returnObject = dN->getData();
+  delete dN;
+  --numElements;
+  return returnObject;
+}
+
+void List::remove(void *removeThis)
+{
+  reset();
+  while((!eol()) && (current->getData() != removeThis)) next();
+  // Now use method above to actually remove the node and get the object
+  remove();
+}
+
+unsigned long int List::getNumElements()
+{
+  return numElements;
+}
+
+// ------ Pointer shift methods -----------------------------------------------
+
+void List::reset(void)
+{
+  current = start;
+  prev = 0;
+}
+
+void List::next(void)
+{
+  if (current == 0) return;
+  prev = current;
+  current = current->getPtr();
+}
+
+// ------ Boolean methods -----------------------------------------------------
+
+short List::isEmpty(void) const
+{
+  return (start == 0);
+}
+
+short List::eol(void) const
+{
+  return (current == 0);
+}
+
+// ------ Save / load methods method --------------------------------------------
+
+void List::save(char *fileName, long int objectLength)
+{
+  FILE *f = fopen(fileName, "w");
+  fwrite(&objectLength, sizeof(long int), 1, f);
+
+  void *v;
+  reset();
+  while(!eol())
+  {
+    v = getCurrent();
+    fwrite(v, objectLength, 1, f);
+    next();
+  }
+  fclose(f);
+}
+
+int List::load(char *fileName)
+{
+int temp1 = 0;
+
+  int readIn = 0;
+  long int objectLength = 0;
+  FILE *f = fopen(fileName, "r");
+  if (!f) return readIn;
+
+  if (fread(&objectLength, sizeof(long int), 1, f) != 1)
+  {
+    fclose(f);
+    return 0;
+  }
+
+  void *temp = 0;
+
+  while(1)
+  {
+    temp = malloc(objectLength);
+    if ((temp1=fread(temp, objectLength, 1, f)) < 1) break;
+    readIn++;
+    add(temp);
+  }
+
+  // We allocated temp but then fread failed
+  free(temp);
+  fclose(f);
+  return readIn;
+}
diff --git a/list.h b/list.h
new file mode 100644 (file)
index 0000000..e1a6451
--- /dev/null
+++ b/list.h
@@ -0,0 +1,66 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef LIST_H
+#define LIST_H
+
+#include <stdio.h>
+#include <malloc.h>
+#include "node.h"
+
+class List
+{
+  public:
+    List();
+    ~List();
+    void add(void *);
+    void *getCurrent(void) const;
+    void *remove(void);   // Removes node from current position from list
+                          // and passes it back to be deleted
+    void remove(void *); // Removes node passed in from list, does not delete it
+    void reset(void);
+    void next(void);
+    short isEmpty(void) const;
+    short eol(void) const;
+    void save(char *, long int);
+    int load(char *);
+    unsigned long int getNumElements();
+
+  private:
+    Node *start;
+    Node *current;
+    Node *prev;
+    unsigned long int numElements;
+};
+
+/* The list class can not delete the object stored in the node object because
+   it does not know the length of it. All the node has is a void *. This is why
+   List always passes back the actual stored object to the calling method.
+*/
+
+/* Fixed memory hole, when delete List, it deletes any remaining Nodes but not
+   stored objects. That's just tuff.
+*/
+
+/* The new saving code will work as long as the objects don't contain any
+   pointers to other areas of memory. Only for use with self-contained objects!
+*/
+
+#endif
diff --git a/log.cc b/log.cc
new file mode 100644 (file)
index 0000000..6823f75
--- /dev/null
+++ b/log.cc
@@ -0,0 +1,149 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+    Copyright 2003-2004 University Of Bradford
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "log.h"
+
+Log* Log::instance = NULL;
+
+Log::Log()
+{
+  if (instance) return;
+  instance = this;
+  logfile = NULL;
+  initted = 0;
+  logLevel = 0;
+}
+
+Log::~Log()
+{
+  instance = NULL;
+}
+
+Log* Log::getInstance()
+{
+  return instance;
+}
+
+void Log::upLogLevel()
+{
+  if (logLevel == Log::DEBUG)
+  {
+    log("Log", logLevel, "Log level is at its highest already");
+    return;
+  }
+
+  logLevel++;
+  log("Log", logLevel, "Log level is now %i", logLevel);
+}
+
+void Log::downLogLevel()
+{
+  if (logLevel == Log::CRAZY)
+  {
+    log("Log", logLevel, "Log level is at its lowest already");
+    return;
+  }
+
+  logLevel--;
+  log("Log", logLevel, "Log level is now %i", logLevel);
+}
+
+int Log::init(int startLogLevel, char* fileName, int tenabled)
+{
+  initted = 1;
+  logLevel = startLogLevel;
+  enabled = tenabled;
+//  logfile = fopen(fileName, "a");
+//  logfile = fopen(stdout, "a");
+  logfile = stdout;
+  if (logfile) return 1;
+  else return 0;
+}
+
+int Log::shutdown()
+{
+  if (!initted) return 1;
+  if (logfile) fclose(logfile);
+  return 1;
+}
+
+int Log::log(char *fromModule, int level, char* message, ...)
+{
+  if (!instance || !logfile) return 0;
+
+  if (!enabled) return 1;
+  if (level > logLevel) return 1;
+
+  char buffer[151];
+  int spaceLeft = 150;
+
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  struct tm* tm = gmtime(&tv.tv_sec);
+  spaceLeft -= strftime(buffer, spaceLeft, "%H:%M:%S.", tm);
+  spaceLeft -= snprintf(&buffer[150-spaceLeft], spaceLeft, "%06lu ", (unsigned long)tv.tv_usec);
+
+
+  char levelString[10];
+  if (level == CRAZY)   strcpy(levelString, "[CRAZY] ");
+  if (level == EMERG)   strcpy(levelString, "[EMERG] ");
+  if (level == ALERT)   strcpy(levelString, "[ALERT] ");
+  if (level == CRIT)    strcpy(levelString, "[CRIT]  ");
+  if (level == ERR)     strcpy(levelString, "[ERR]   ");
+  if (level == WARN)    strcpy(levelString, "[WARN]  ");
+  if (level == NOTICE)  strcpy(levelString, "[notice]");
+  if (level == INFO)    strcpy(levelString, "[info]  ");
+  if (level == DEBUG)   strcpy(levelString, "[debug] ");
+
+  spaceLeft -= snprintf(&buffer[150-spaceLeft], spaceLeft, "%s %s - ", levelString, fromModule);
+
+  va_list ap;
+  va_start(ap, message);
+  spaceLeft = vsnprintf(&buffer[150-spaceLeft], spaceLeft, message, ap);
+  va_end(ap);
+
+  int messageLength = strlen(buffer);
+  if (messageLength < 150)
+  {
+    buffer[messageLength] = '\n';
+    buffer[messageLength+1] = '\0';
+  }
+  else
+  {
+    buffer[149] = '\n';
+    buffer[150] = '\0';
+  }
+
+  int success = fputs(buffer, logfile);
+  fflush(NULL);
+
+  if (success != EOF)
+    return 1;
+  else
+    return 0;
+
+}
+
+int Log::status()
+{
+  if (instance && logfile) return 1;
+  else return 0;
+}
diff --git a/log.h b/log.h
new file mode 100644 (file)
index 0000000..bf45f42
--- /dev/null
+++ b/log.h
@@ -0,0 +1,89 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+    Copyright 2003-2004 University Of Bradford
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef LOG_H
+#define LOG_H
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include <string.h>
+#include <stdarg.h>
+
+class Log
+{
+  public:
+    Log();
+    ~Log();
+    static Log* getInstance();
+
+    int init(int defaultLevel, char* fileName, int enabled);
+    int shutdown();
+    int log(char *fromModule, int level, char *message, ...);
+    int status();
+    void upLogLevel();
+    void downLogLevel();
+
+    const static int CRAZY  = 0; // mad crazy things that should never happen
+    const static int EMERG  = 1; // human assist required NOW
+    const static int ALERT  = 2; // system unusable, but happy to sit there
+    const static int CRIT   = 3; // still working, but maybe about to die
+    const static int ERR    = 4; // that response is not even listed...
+    const static int WARN   = 5; // this could be a bad thing. still running tho
+    const static int NOTICE = 6; // significant good thing
+    const static int INFO   = 7; // verbose good thing
+    const static int DEBUG  = 8; // debug-level messages
+
+  private:
+    static Log* instance;
+    int initted;
+    int logLevel;
+    int enabled;
+
+    FILE *logfile;
+};
+
+#endif
+
+/*
+
+Documentation
+-------------
+
+This class is intended to be instatiated once by the core.
+For a one off use:
+
+Log::getInstance()->log("<module-name>", Log::<levelname>, "<message>");
+
+Or, a pointer can be stored and used:
+
+Log *myptr = Log::getInstance();
+
+myptr->log("<module-name>", Log::<levelname>, "<message>");
+myptr->log("<module-name>", Log::<levelname>, "<message>");
+
+Level usages are above.
+
+The message parameter in the log function can be used in the same way as printf, eg.
+
+myptr->log("<module-name>", Log::<levelname>, "Success: %s %i", stringpointer, integer);
+
+*/
diff --git a/main.cc b/main.cc
new file mode 100644 (file)
index 0000000..92e53d1
--- /dev/null
+++ b/main.cc
@@ -0,0 +1,399 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <endian.h>
+
+#include "defines.h"
+#include "log.h"
+#include "remote.h"
+#include "led.h"
+#include "mtd.h"
+#include "video.h"
+#include "audio.h"
+#include "vdr.h"
+#include "osd.h"
+#include "viewman.h"
+#include "command.h"
+
+void sighandler(int signal);
+void shutdown(int code);
+
+// Global variables --------------------------------------------------------------------------------------------------
+int debugEnabled = 0;
+Log* logger;
+Remote* remote;
+Mtd* mtd;
+Led* led;
+Osd* osd;
+ViewMan* viewman;
+Command* command;
+VDR* vdr;
+Video* video;
+Audio* audio;
+
+int main(int argc, char** argv)
+{
+  if ((argc > 1) && (!strcmp(argv[1], "-d"))) debugEnabled = 1;
+
+
+  // Init global vars ------------------------------------------------------------------------------------------------
+
+  logger     = new Log();
+  remote     = new Remote();
+  mtd        = new Mtd();
+  led        = new Led();
+  osd        = new Osd();
+  vdr        = new VDR();
+  video      = new Video();
+  audio      = new Audio();
+  viewman    = new ViewMan();
+  command    = new Command();
+
+  if (!logger || !remote || !mtd || !led || !osd || !video || !audio || !viewman || !command)
+  {
+    printf("Could not create objects. Memory problems?\n");
+    shutdown(1);
+  }
+
+  // Get logging module started --------------------------------------------------------------------------------------
+
+  if (!logger->init(Log::DEBUG, "dummy", debugEnabled))
+  {
+    printf("Could not initialise log object. Aborting.\n");
+    shutdown(1);
+  }
+
+  logger->log("Core", Log::INFO, "Starting up...");
+
+  // Set up signal handling ------------------------------------------------------------------------------------------
+
+  sighandler_t sigtest;
+
+  sigtest = signal(SIGPIPE, SIG_IGN);
+  if (sigtest == SIG_ERR)
+  {
+    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGPIPE. Aborting.");
+    shutdown(1);
+  }
+  sigtest = signal(SIGINT, sighandler);
+  if (sigtest == SIG_ERR)
+  {
+    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGINT. Aborting.");
+    shutdown(1);
+  }
+  sigtest = signal(SIGTERM, sighandler);
+  if (sigtest == SIG_ERR)
+  {
+    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGTERM. Aborting.");
+    shutdown(1);
+  }
+  sigtest = signal(SIGUSR1, sighandler);
+  if (sigtest == SIG_ERR)
+  {
+    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR1. Aborting.");
+    shutdown(1);
+  }
+  sigtest = signal(SIGUSR2, sighandler);
+  if (sigtest == SIG_ERR)
+  {
+    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR2. Aborting.");
+    shutdown(1);
+  }
+  sigtest = signal(SIGURG, sighandler);
+  if (sigtest == SIG_ERR)
+  {
+    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGURG. Aborting.");
+    shutdown(1);
+  }
+
+  logger->log("Core", Log::INFO, "Signal handlers set up successfully");
+
+
+  // Init modules ----------------------------------------------------------------------------------------------------
+  int success;
+
+  success = remote->init("/dev/rawir");
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "Remote module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "Remote module failed to initialise");
+    shutdown(1);
+  }
+
+  success = led->init(remote->getDevice());
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "LED module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "LED module failed to initialise");
+    shutdown(1);
+  }
+
+  success = mtd->init("/dev/mtd1");
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "Mtd module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "Mtd module failed to initialise");
+    shutdown(1);
+  }
+
+  success = osd->init("/dev/stbgfx", SCREENHEIGHT, SCREENWIDTH, 1);
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "OSD module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "OSD module failed to initialise");
+    shutdown(1);
+  }
+
+  success = vdr->init(3024);
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "VDR module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "VDR module failed to initialise");
+    shutdown(1);
+  }
+
+  success = video->init(Video::PAL, Video::SCART, Video::ASPECT4X3, Video::NORMAL);
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "Video module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "Video module failed to initialise");
+    shutdown(1);
+  }
+
+  success = audio->init(Audio::MPEG2_PES);
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "Audio module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "Audio module failed to initialise");
+    shutdown(1);
+  }
+
+  success = viewman->init();
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "ViewMan module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "ViewMan module failed to initialise");
+    shutdown(1);
+  }
+
+  success = command->init();
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "Command module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "Command module failed to initialise");
+    shutdown(1);
+  }
+
+  // Other init ------------------------------------------------------------------------------------------------------
+
+  logger->log("Core", Log::NOTICE, "Startup successful");
+
+  // Run main loop ---------------------------------------------------------------------------------------------------
+
+  // Ok, all major device components and other bits are loaded and ready
+  command->run();
+
+  // When that returns quit ------------------------------------------------------------------------------------------
+
+  shutdown(0);
+  return 0;
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+
+void shutdown(int code)
+{
+  if (command)
+  {
+    command->shutdown();
+    delete command;
+    logger->log("Core", Log::NOTICE, "Command module shut down");
+  }
+
+  if (viewman)
+  {
+    viewman->shutdown();
+    delete viewman;
+    logger->log("Core", Log::NOTICE, "ViewMan module shut down");
+  }
+
+  if (audio)
+  {
+    audio->shutdown();
+    delete audio;
+    logger->log("Core", Log::NOTICE, "Audio module shut down");
+  }
+
+  if (video)
+  {
+    video->shutdown();
+    delete video;
+    logger->log("Core", Log::NOTICE, "Video module shut down");
+  }
+
+  if (vdr)
+  {
+    vdr->shutdown();
+    delete vdr;
+    logger->log("Core", Log::NOTICE, "VDR module shut down");
+  }
+
+  if (osd)
+  {
+    osd->shutdown();
+    delete osd;
+    logger->log("Core", Log::NOTICE, "OSD module shut down");
+  }
+
+  if (mtd)
+  {
+    mtd->shutdown();
+    delete mtd;
+    logger->log("Core", Log::NOTICE, "MTD module shut down");
+  }
+
+  if (led)
+  {
+    led->shutdown();
+    delete led;
+    logger->log("Core", Log::NOTICE, "LED module shut down");
+  }
+
+  if (remote)
+  {
+    remote->shutdown();
+    delete remote;
+    logger->log("Core", Log::NOTICE, "Remote module shut down");
+  }
+
+  if (logger)
+  {
+    logger->log("Core", Log::NOTICE, "Log module shutting down... bye!\n\n");
+    logger->shutdown();
+    delete logger;
+  }
+
+  exit(code);
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+
+void sighandler(int signal)
+{
+  Log* logger = Log::getInstance();
+
+  logger->log("Core", Log::NOTICE, "Signal %i received", signal);
+
+  switch (signal)
+  {
+    case SIGINT:
+    {
+      logger->log("Core", Log::NOTICE, "Interrupt signal, shutting down...");
+      command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe?
+      break;
+    }
+    case SIGTERM:
+    {
+      logger->log("Core", Log::NOTICE, "Term signal, shutting down...");
+      command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe?
+      break;
+    }
+    case SIGUSR1:
+    {
+      logger->log("Core", Log::DEBUG, "SIGUSR1 caught");
+      logger->upLogLevel();
+      break;
+    }
+    case SIGUSR2:
+    {
+      logger->log("Core", Log::DEBUG, "SIGUSR2 caught");
+      logger->downLogLevel();
+      break;
+    }
+    case SIGURG:
+    {
+      logger->log("Core", Log::DEBUG, "SIGURG caught");
+      break;
+    }
+  }
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+
+ULLONG ntohll(ULLONG a)
+{
+  return htonll(a);
+}
+
+ULLONG htonll(ULLONG a)
+{
+  #if BYTE_ORDER == BIG_ENDIAN
+    return a;
+  #else
+    ULLONG b = 0;
+
+    b = ((a << 56) & 0xFF00000000000000ULL)
+      | ((a << 40) & 0x00FF000000000000ULL)
+      | ((a << 24) & 0x0000FF0000000000ULL)
+      | ((a <<  8) & 0x000000FF00000000ULL)
+      | ((a >>  8) & 0x00000000FF000000ULL)
+      | ((a >> 24) & 0x0000000000FF0000ULL)
+      | ((a >> 40) & 0x000000000000FF00ULL)
+      | ((a >> 56) & 0x00000000000000FFULL) ;
+
+    return b;
+  #endif
+}
diff --git a/message.cc b/message.cc
new file mode 100644 (file)
index 0000000..21e693d
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "message.h"
+
+Message::Message()
+{
+  from = NULL;
+  to = NULL;
+  message = 0;
+  parameter = 0;
+  tag = 0;
+}
diff --git a/message.h b/message.h
new file mode 100644 (file)
index 0000000..523bf76
--- /dev/null
+++ b/message.h
@@ -0,0 +1,52 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef MESSAGE_H
+#define MESSAGE_H
+
+#include <stdio.h>
+#include "defines.h"
+
+class View;
+
+class Message
+{
+  public:
+    Message();
+
+    void* from;
+    void* to;
+    ULONG message;
+    ULONG parameter;
+    ULONG tag;     // use this for identifying which object / question is being replied to
+
+    const static ULONG QUESTION_YES = 1;
+    const static ULONG CLOSE_ME = 2;
+    const static ULONG PLAY_SELECTED_RECORDING = 3;
+    const static ULONG DELETE_SELECTED_RECORDING = 4;
+    const static ULONG UPDATE_SCREEN = 5;
+    const static ULONG SWAP_ME_FOR = 6;
+    const static ULONG CHANNEL_CHANGE = 7;
+    const static ULONG RESUME_SELECTED_RECORDING = 8;
+    const static ULONG STANDBY = 9;
+    const static ULONG STOP_PLAYBACK = 10;
+};
+
+#endif
diff --git a/messagequeue.cc b/messagequeue.cc
new file mode 100644 (file)
index 0000000..5c4bbd9
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "messagequeue.h"
+
+void MessageQueue::postMessage(Message* m)
+{
+  messages.store(m);
+  Log::getInstance()->log("MessageQueue", Log::DEBUG, "have stored message in queue");
+}
+
+void MessageQueue::processMessageQueue()
+{
+  Message *m;
+  while((m = (Message*)messages.retrieve()))
+  {
+    Log::getInstance()->log("MessageQueue", Log::DEBUG, "retrieved message from queue");
+    processMessage(m);
+    delete m;
+  }
+}
diff --git a/messagequeue.h b/messagequeue.h
new file mode 100644 (file)
index 0000000..6e36a9b
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef MESSAGEQUEUE_H
+#define MESSAGEQUEUE_H
+
+#include "queue.h"
+#include "message.h"
+#include "log.h"
+
+class MessageQueue
+{
+  public:
+    MessageQueue() {};
+    virtual ~MessageQueue() {};
+
+    virtual void postMessage(Message* m);
+
+  protected:
+    virtual void processMessageQueue();
+    virtual void processMessage(Message* m)=0;
+
+    Queue messages;
+
+  private:
+
+};
+
+#endif
diff --git a/mtd.cc b/mtd.cc
new file mode 100644 (file)
index 0000000..f5d900c
--- /dev/null
+++ b/mtd.cc
@@ -0,0 +1,127 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "mtd.h"
+
+Mtd* Mtd::instance = NULL;
+
+Mtd::Mtd()
+{
+  if (instance) return;
+  instance = this;
+  initted = 0;
+}
+
+Mtd::~Mtd()
+{
+  instance = NULL;
+}
+
+Mtd* Mtd::getInstance()
+{
+  return instance;
+}
+
+int Mtd::init(char* device)
+{
+  if (initted) return 0;
+  initted = 1;
+
+  int fd;
+
+  if ((fd = open(device, O_RDONLY)) < 0)
+  {
+    initted = 0;
+    return 0;
+  }
+
+  if (read(fd, data, 8192) < 8192)
+  {
+    initted = 0;
+    return 0;
+  }
+
+  close(fd);
+
+  logit();
+
+  return 1;
+}
+
+int Mtd::shutdown()
+{
+  if (!initted) return 0;
+  initted = 0;
+  return 1;
+}
+
+short Mtd::getVideoMode()
+{
+  return data[2119];
+}
+
+short Mtd::getAspect()
+{
+  return data[2125];
+}
+
+short Mtd::getFlicker()
+{
+  return data[2124];
+}
+
+short Mtd::getBootLogoOutput()
+{
+  return data[2116];
+}
+
+short Mtd::getBootLogoDisplayVideoLeft()
+{
+  return data[2120];
+}
+
+short Mtd::getBootLogoDisplayVideoUpper()
+{
+  return data[2121];
+}
+
+short Mtd::getBootLogoDisplayVideoWidth()
+{
+  return data[2122];
+}
+
+short Mtd::getBootLogoDisplayVideoHeight()
+{
+  return data[2123];
+}
+
+void Mtd::logit()
+{
+  Log* logger = Log::getInstance();
+
+  logger->log("MTD", Log::DEBUG, "Mode: %i", getVideoMode());
+  logger->log("MTD", Log::DEBUG, "Aspect: %i", getAspect());
+  logger->log("MTD", Log::DEBUG, "Flicker: %i", getFlicker());
+  logger->log("MTD", Log::DEBUG, "Bootlogo output: %i", getBootLogoOutput());
+  logger->log("MTD", Log::DEBUG, "Bootlogo display video left: %i", getBootLogoDisplayVideoLeft());
+  logger->log("MTD", Log::DEBUG, "Bootlogo display video upper: %i", getBootLogoDisplayVideoUpper());
+  logger->log("MTD", Log::DEBUG, "Bootlogo display video width: %i", getBootLogoDisplayVideoWidth());
+  logger->log("MTD", Log::DEBUG, "Bootlogo display video height: %i", getBootLogoDisplayVideoHeight());
+}
diff --git a/mtd.h b/mtd.h
new file mode 100644 (file)
index 0000000..c143222
--- /dev/null
+++ b/mtd.h
@@ -0,0 +1,59 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+// Information for this class taken from the mvpmc project - thanks
+
+#ifndef MTD_H
+#define MTD_H
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "log.h"
+
+class Mtd
+{
+  public:
+    Mtd();
+    ~Mtd();
+    static Mtd* getInstance();
+
+    int init(char* device);
+    int shutdown();
+
+    short getVideoMode();
+    short getAspect();
+    short getFlicker();
+    short getBootLogoOutput();
+    short getBootLogoDisplayVideoLeft();
+    short getBootLogoDisplayVideoUpper();
+    short getBootLogoDisplayVideoWidth();
+    short getBootLogoDisplayVideoHeight();
+
+    void logit();
+
+  private:
+    static Mtd* instance;
+    int initted;
+
+    short data[4096];
+};
+
+#endif
diff --git a/node.cc b/node.cc
new file mode 100644 (file)
index 0000000..c99db45
--- /dev/null
+++ b/node.cc
@@ -0,0 +1,46 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "node.h"
+
+Node::Node(void *newData, Node *ptr)
+{
+  myData = newData;
+  ptrNext = ptr;
+}
+
+Node::~Node()
+{
+}
+
+void *Node::getData(void)
+{
+  return myData;
+}
+
+Node *Node::getPtr(void)
+{
+  return ptrNext;
+}
+
+void Node::setPtr(Node *newPtr)
+{
+  ptrNext = newPtr;
+}
diff --git a/node.h b/node.h
new file mode 100644 (file)
index 0000000..50788dc
--- /dev/null
+++ b/node.h
@@ -0,0 +1,37 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef NODE_H
+#define NODE_H
+
+class Node
+{
+  public:
+    Node(void *, Node *);
+    ~Node();
+    void *getData(void);
+    Node *getPtr(void);
+    void setPtr(Node *);
+  private:
+    void *myData;
+    Node *ptrNext;
+};
+
+#endif
diff --git a/osd.cc b/osd.cc
new file mode 100644 (file)
index 0000000..d325301
--- /dev/null
+++ b/osd.cc
@@ -0,0 +1,111 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "osd.h"
+
+Osd* Osd::instance = NULL;
+
+Osd::Osd()
+{
+  if (instance) return;
+  instance = this;
+  initted = 0;
+
+  fdOsd = 0;
+  screen = NULL;
+  buffer = NULL;
+}
+
+Osd::~Osd()
+{
+  if (initted) shutdown();
+  instance = NULL;
+}
+
+Osd* Osd::getInstance()
+{
+  return instance;
+}
+
+int Osd::getFD()
+{
+  if (!initted) return 0;
+  return fdOsd;
+}
+
+int Osd::getScreenHeight()
+{
+  return height;
+}
+
+int Osd::getScreenWidth()
+{
+  return width;
+}
+
+int Osd::init(char* device, int height, int width, int doubleBuffering)
+{
+  if (initted) return 0;
+
+  fdOsd = open(device, O_RDWR);
+  if (!fdOsd)
+  {
+    Log::getInstance()->log("OSD", Log::DEBUG, "Could not open OSD device!");
+    return 0;
+  }
+
+  initted = 1; // must set this here or create surface won't work
+
+  this->height = height;
+  this->width = width;
+
+  Surface::initConversionTables();
+
+  screen = new Surface(fdOsd, Surface::SCREEN);
+  screen->create(height, width);
+  screen->display();
+
+  if (doubleBuffering)
+  {
+    buffer = new Surface(fdOsd, Surface::BUFFER);
+    buffer->create(height, width);
+  }
+  else
+  {
+    Surface::disableBuffer();
+  }
+
+  return 1;
+}
+
+int Osd::shutdown()
+{
+  if (!initted) return 0;
+  initted = 0;
+  if (buffer) delete buffer;
+  delete screen;
+  close(fdOsd);
+  return 1;
+}
+
+void Osd::screenShot(char* fileName)
+{
+  screen->screenShot(fileName);
+}
diff --git a/osd.h b/osd.h
new file mode 100644 (file)
index 0000000..1c11504
--- /dev/null
+++ b/osd.h
@@ -0,0 +1,61 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef OSD_H
+#define OSD_H
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "defines.h"
+#include "log.h"
+#include "surface.h"
+
+class Osd
+{
+  public:
+    Osd();
+    ~Osd();
+    static Osd* getInstance();
+
+    int init(char* device, int height, int width, int doubleBuffering);
+    int shutdown();
+
+    int getFD();
+    int getScreenHeight();
+    int getScreenWidth();
+
+    void screenShot(char* fileName);
+
+  private:
+    static Osd* instance;
+    int initted;
+
+    Surface* screen;
+    Surface* buffer;
+
+    int fdOsd;
+    int width;
+    int height;
+
+};
+
+#endif
diff --git a/other/licence.txt b/other/licence.txt
new file mode 100644 (file)
index 0000000..f780226
--- /dev/null
@@ -0,0 +1,45 @@
+vdr.jpg is lifted from VDR's home page which states:
+"Free project statement This is a FREE and completely non-commercial project.
+Any information posted on these pages is freely available to anybody. All
+source code published here is protected by the GNU general public licence."
+
+------------------------------------------------------------------
+
+wallpaper.jpg is actually blue-bend.jpg from the KDE wallpapers.
+It was taken from the debian package kdebase-data - the copyright
+file is below.
+
+------------------------------------------------------------------
+
+This package was debianized by Christopher L Cheney <ccheney@debian.org> on
+Tue, 16 Apr 2002 22:00:00 -0500.
+
+It was downloaded via CVS from cvs.kde.org
+
+Upstream Authors: Stephan Kulow <coolo@kde.org> and many others...
+
+License:
+
+All programs are either under the GPL or LGPL. On Debian systems,
+the complete text of the GPL and LGPL licenses can be found in the
+/usr/share/common-licenses/GPL and /usr/share/common-licenses/LGPL files.
+
+When in doubt, check the individual file, they should all have license
+headings and other identifying marks.
+
+Artistic
+--------
+kdcop, kdesu, klipper
+
+BSD
+---
+drkonqi, kaddressbook, kicker, ksmserver, ksplash, kwin, legacyimport
+
+GPL
+---
+kappfinder, kate, kcheckpass, kdeprint, kdm, kfind, khelpcenter, kmenuedit,
+konqueror, konsole, kpager, kpersonalizer, kreadconfig, kstart, ksysguard, ktip
+
+LGPL
+----
+kdebugdialog, kdesktop, khotkeys, kxkb, libkonq, nsplugins
diff --git a/other/vdr.jpg b/other/vdr.jpg
new file mode 100644 (file)
index 0000000..37be1c9
Binary files /dev/null and b/other/vdr.jpg differ
diff --git a/other/wallpaper.jpg b/other/wallpaper.jpg
new file mode 100644 (file)
index 0000000..ed56138
Binary files /dev/null and b/other/wallpaper.jpg differ
diff --git a/player.cc b/player.cc
new file mode 100644 (file)
index 0000000..d77d5aa
--- /dev/null
+++ b/player.cc
@@ -0,0 +1,497 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "player.h"
+
+Player::Player(MessageQueue* messageQueue)
+: vfeed(this), afeed(this)
+{
+  initted = 0;
+  commandMessageQueue = messageQueue;
+
+  paused = 0;
+  playing = 0;
+  ffwd = 0;
+  fbwd = 0;
+  feedPosition = 0;
+  feedMode = MODE_NORMAL;
+
+  streamLength = 0;
+  // FIXME - this might need settings back to zero for new live play depending on what is done with it
+}
+
+Player::~Player()
+{
+  if (initted) shutdown();
+}
+
+int Player::init()
+{
+  if (initted) return 0;
+
+  video = Video::getInstance();
+  audio = Audio::getInstance();
+
+  if (demuxer.init()) // inverted
+  {
+    Log::getInstance()->log("Player", Log::ERR, "Demuxer failed to init");
+    shutdown();
+    return 0;
+  }
+
+  vfeed.init(video->getFD());
+  afeed.init(audio->getFD());
+
+  video->stop();
+  video->blank();
+  audio->stop();
+
+  startup = 0;
+  initted = 1;
+  return 1;
+}
+
+int Player::shutdown()
+{
+  if (!initted) return 0;
+  initted = 0;
+
+  Log::getInstance()->log("Player", Log::DEBUG, "Player shutdown...");
+
+  // copy of stop
+  if (playing)
+  {
+    playing = 0;
+    threadStop();
+    video->stop();
+    video->blank();
+    audio->stop();
+    vfeed.stop();
+    afeed.stop();
+    video->reset();
+    demuxer.reset();
+    feedPosition = 0;
+  }
+
+  return 1;
+}
+
+int Player::play()
+{
+  if (!initted) return 0;
+
+  // If we are just paused, unpause!
+  if (paused)
+  {
+    togglePause();
+    return 1;
+  }
+
+  // If we are fast forwarding, set to normal
+  if (ffwd)
+  {
+    toggleFastForward();
+    return 1;
+  }
+
+  // If we are fast backwarding, set to normal
+  if (fbwd)
+  {
+    toggleFastBackward();
+    return 1;
+  }
+
+  // If we are already playing, bail // FIXME - resync?
+  if (playing)
+  {
+    Log::getInstance()->log("Player", Log::DEBUG, "DOING RESYNC");
+
+    vfeed.stop();
+    afeed.stop();
+    video->reset();
+    audio->reset();
+    demuxer.flush();
+    demuxer.seek();
+    vfeed.start();
+    afeed.start();
+
+
+    video->play();
+    audio->play();
+    video->sync();
+    audio->sync();
+    call();
+
+    return 1;
+  }
+
+  // Standard play start
+
+  audio->reset();
+  video->reset();
+  demuxer.reset();
+  startup = 1;
+
+// ------------------------ This one works, but doesn't allow any pre-buffering.
+  threadStart();
+  vfeed.start();
+  afeed.start();
+  video->play();
+  audio->play();
+  video->sync();
+  audio->sync();
+// ------------------------ This one doesn't work, but it should, and would allow for prebuffering.
+
+/*
+
+  threadStart();
+  sleep(2);
+
+//  struct timespec delay;
+//  delay.tv_sec = 1;
+//  delay.tv_nsec = 500000000;
+//  nanosleep(&delay, NULL);
+
+  vfeed.start();
+  afeed.start();
+  video->play();
+  audio->play();
+  video->sync();
+  audio->sync();
+*/
+// ------------------------------------------------------------------------------------------------
+
+  playing = 1;
+  return 1;
+}
+
+void Player::stop()
+{
+  if (!initted) return;
+  if (!playing) return;
+
+  if (ffwd || fbwd)
+  {
+    ffwd = 0;
+    fbwd = 0;
+    afeed.enable();
+    video->unFastForward();
+    audio->systemMuteOff();
+    feedMode = MODE_NORMAL;
+  }
+
+  playing = 0;
+
+  threadStop();
+  video->stop();
+  video->blank();
+  audio->stop();
+  vfeed.stop();
+  afeed.stop();
+  video->reset();
+  demuxer.reset();
+
+  feedPosition = 0;
+}
+
+void Player::togglePause()
+{
+  if (!initted) return;
+  if (!playing) return;
+
+  if (ffwd) toggleFastForward();
+  if (fbwd) toggleFastBackward();
+
+  if (paused)
+  {
+    video->unPause();
+    audio->unPause();
+    paused = 0;
+  }
+  else
+  {
+    video->pause();
+    audio->pause();
+    paused = 1;
+  }
+}
+
+void Player::test()
+{
+  Log::getInstance()->log("Player", Log::DEBUG, "PLAYER TEST");
+
+  video->test();
+
+//  static int flipflop = 0;
+
+//  if (flipflop) video->setAspectRatio(Video::ASPECT16X9);
+//  else video->setAspectRatio(Video::ASPECT4X3);
+
+//  flipflop = !flipflop;
+
+}
+
+void Player::test2()
+{
+  Log::getInstance()->log("Player", Log::DEBUG, "PLAYER TEST");
+
+  video->test2();
+}
+
+void Player::setPosition(ULLONG position)
+{
+  feedPosition = position;
+}
+
+void Player::setLength(ULLONG length)
+{
+  streamLength = length;
+  Log::getInstance()->log("Player", Log::DEBUG, "Player has received length of %llu", streamLength);
+}
+
+void Player::skipForward(int seconds)
+{
+  // skip forward 1 minute
+  Log::getInstance()->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds);
+
+  if (paused) togglePause();
+
+  ULLONG moveBy = seconds * 500000;
+
+  threadStop();
+  vfeed.stop();
+  afeed.stop();
+  video->stop();
+  video->reset();
+  audio->reset();
+  audio->doMuting();  // ???
+  demuxer.flush();
+  feedPosition += moveBy;
+
+  printf("Audio test %i\n", audio->test());
+
+  vfeed.start();
+  afeed.start();
+  threadStart();
+  video->sync();
+  audio->sync();
+  video->play();
+  audio->play();
+
+}
+
+void Player::skipBackward(int seconds)
+{
+  // skip forward 1 minute
+  Log::getInstance()->log("Player", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds);
+
+  if (paused) togglePause();
+
+  ULLONG moveBy = seconds * 500000;
+
+  threadStop();
+  vfeed.stop();
+  afeed.stop();
+  video->stop();
+  audio->stop();
+  video->reset();
+  audio->reset();
+  audio->doMuting(); // ???
+  demuxer.flush();
+  if (feedPosition > moveBy) feedPosition -= moveBy;
+  vfeed.start();
+  afeed.start();
+  threadStart();
+  video->play();
+  audio->play();
+  video->sync();
+  audio->sync();
+}
+
+void Player::toggleFastForward()
+{
+  if (!initted) return;
+  if (!playing) return;
+
+  if (paused) togglePause();
+  if (fbwd) toggleFastBackward();
+
+  if (ffwd)
+  {
+    ffwd = 0;
+    afeed.enable();
+    video->unFastForward();
+    audio->reset();
+    video->sync();
+    audio->sync();
+    audio->systemMuteOff();
+  }
+  else
+  {
+    ffwd = 1;
+    afeed.disable();
+    audio->systemMuteOn();
+    video->fastForward();
+  }
+}
+
+void Player::toggleFastBackward()
+{
+  if (!initted) return;
+  if (!playing) return;
+
+  if (paused) togglePause();
+  if (ffwd) toggleFastForward();
+
+  if (fbwd)
+  {
+    fbwd = 0;
+    afeed.enable();
+    audio->systemMuteOff();
+
+//    threadStop();
+    feedMode = MODE_NORMAL;
+//    threadStart();
+  }
+  else
+  {
+    fbwd = 1;
+    afeed.disable();
+    audio->systemMuteOn();
+
+    threadStop();
+    feedMode = MODE_BACKWARDS;
+    video->reset();
+    video->play();
+    demuxer.flush();
+    threadStart();
+  }
+}
+
+void Player::jumpToPercent(int percent)
+{
+  threadStop();
+  vfeed.stop();
+  afeed.stop();
+  video->stop();
+  audio->stop();
+  video->reset();
+  audio->reset();
+  demuxer.flush();
+  demuxer.seek();
+  feedPosition = streamLength * percent / 100;
+  vfeed.start();
+  afeed.start();
+  threadStart();
+  video->play();
+  audio->play();
+  video->sync();
+  audio->sync();
+}
+
+
+void Player::call()
+{
+  threadSignalNoLock();
+}
+
+// Feed thread
+
+void Player::threadMethod()
+{
+  UCHAR buf[blockSize];
+  int thisRead;
+  int writeLength;
+  int thisWrite;
+
+  VDR* vdr = VDR::getInstance();
+
+  int askFor;
+  while(1)
+  {
+    thisRead = 0;
+    writeLength = 0;
+    thisWrite = 0;
+
+    threadCheckExit();
+
+    // a bit hackey. this needs to be split to live and rec players
+    if (streamLength && (feedPosition >= streamLength)) break;
+    askFor = blockSize;
+    if (streamLength && ((feedPosition + blockSize) > streamLength))
+    {
+      askFor = streamLength - feedPosition;
+    }
+    thisRead = vdr->getBlock(buf, feedPosition, askFor);
+    if (startup)
+    {
+      int a_stream = demuxer.scan(buf, thisRead);
+      demuxer.setAudioStream(a_stream);
+      Log::getInstance()->log("Player", Log::DEBUG, "Startup Audio stream chosen %x", a_stream);
+      startup = 0;
+    }
+
+    if (feedMode == MODE_NORMAL)
+    {
+      feedPosition += thisRead;
+    }
+    else if (feedMode == MODE_BACKWARDS)
+    {
+      if (feedPosition >= 100000)
+      {
+        feedPosition -= 100000;
+        demuxer.seek();
+      }
+      else
+      {
+        // got to the start of the recording.. revert to play mode? how?
+        feedPosition += thisRead;
+      }
+    }
+
+    threadCheckExit();
+
+    while(writeLength < thisRead)
+    {
+      thisWrite = demuxer.put(buf + writeLength, thisRead - writeLength);
+      writeLength += thisWrite;
+
+      if (!thisWrite)
+      {
+        Log::getInstance()->log("Player", Log::DEBUG, "DEMUXER FULL!!!");
+        // demuxer is full and cant take anymore
+        threadWaitForSignal();
+        Log::getInstance()->log("Player", Log::DEBUG, "BACK FROM WAIT");
+      }
+
+      threadCheckExit();
+    }
+  }
+
+  // end of recording
+  Log::getInstance()->log("Player", Log::DEBUG, "Recording playback ends");
+  Message* m = new Message();
+  m->message = Message::STOP_PLAYBACK;
+  Log::getInstance()->log("Player", Log::DEBUG, "Posting message...");
+  commandMessageQueue->postMessage(m);
+  Log::getInstance()->log("Player", Log::DEBUG, "Message posted...");
+
+
+}
diff --git a/player.h b/player.h
new file mode 100644 (file)
index 0000000..ca9183b
--- /dev/null
+++ b/player.h
@@ -0,0 +1,85 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#include <stdio.h>
+
+#include "audio.h"
+#include "video.h"
+#include "demuxer.h"
+#include "vfeed.h"
+#include "afeed.h"
+#include "remote.h"
+#include "thread.h"
+#include "vdr.h"
+#include "callback.h"
+#include "message.h"
+#include "messagequeue.h"
+
+class Player : public Thread, public Callback
+{
+  public:
+    Player(MessageQueue* messageQueue);
+    virtual ~Player();
+
+    int init();
+    int shutdown();
+
+    int play();
+    void stop();
+    void togglePause();
+    void toggleFastForward();
+    void toggleFastBackward();
+    void jumpToPercent(int percent);
+    void skipForward(int seconds);
+    void skipBackward(int seconds);
+    void test();
+    void test2();
+    void call(); // for callback interface
+    void setPosition(ULLONG position);
+    void setLength(ULLONG length);
+
+    void threadMethod();
+
+  private:
+    int initted;
+    MessageQueue* commandMessageQueue;
+    Video* video;
+    Audio* audio;
+    Demuxer demuxer;
+    int startup;
+    VFeed vfeed;
+    AFeed afeed;
+    ULLONG streamLength;
+    ULLONG feedPosition;
+    UCHAR feedMode;
+    const static UCHAR MODE_NORMAL = 1;
+    const static UCHAR MODE_BACKWARDS = 2;
+    const static int blockSize = 100000;
+
+    UCHAR playing;    // As in not stopped, (playing && paused) can == TRUE
+    UCHAR paused;     // Must be in playing state as well
+    UCHAR ffwd;       // Must be in playing state as well
+    UCHAR fbwd;       // Must be in playing state as well
+};
+
+#endif
diff --git a/playerradio.cc b/playerradio.cc
new file mode 100644 (file)
index 0000000..b8f05ce
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+// this is a total copy from player but with video stuff taken out
+// most of this isn't used because it's designed for recording playback
+
+
+#include "playerradio.h"
+
+PlayerRadio::PlayerRadio()
+: afeedr(this, &stream)
+{
+  initted = 0;
+
+  paused = 0;
+  playing = 0;
+  ffwd = 0;
+  fbwd = 0;
+  feedPosition = 0;
+  feedMode = MODE_NORMAL;
+
+  streamLength = 0;
+  // FIXME - this might need settings back to zero for new live play depending on what is done with it
+}
+
+PlayerRadio::~PlayerRadio()
+{
+  if (initted) shutdown();
+}
+
+int PlayerRadio::init()
+{
+  if (initted) return 0;
+
+  audio = Audio::getInstance();
+  stream.init(120000);
+  afeedr.init(audio->getFD());
+
+  audio->stop();
+
+  initted = 1;
+  return 1;
+}
+
+int PlayerRadio::shutdown()
+{
+  if (!initted) return 0;
+  initted = 0;
+
+  Log::getInstance()->log("PlayerRadio", Log::DEBUG, "PlayerRadio shutdown...");
+
+  // copy of stop
+  if (playing)
+  {
+    playing = 0;
+    threadStop();
+    audio->stop();
+    afeedr.stop();
+    feedPosition = 0;
+  }
+
+  return 1;
+}
+
+int PlayerRadio::play()
+{
+  if (!initted) return 0;
+
+  // If we are just paused, unpause!
+  if (paused)
+  {
+    togglePause();
+    return 1;
+  }
+
+  // If we are fast forwarding, set to normal
+  if (ffwd)
+  {
+    toggleFastForward();
+    return 1;
+  }
+
+  // If we are fast backwarding, set to normal
+  if (fbwd)
+  {
+    toggleFastBackward();
+    return 1;
+  }
+
+  // If we are already playing, bail // FIXME - resync?
+  if (playing)
+  {
+    Log::getInstance()->log("PlayerRadio", Log::DEBUG, "DOING RESYNC");
+
+    afeedr.stop();
+    audio->reset();
+    afeedr.start();
+
+    audio->play();
+    call();
+
+    return 1;
+  }
+
+  // Standard play start
+
+  audio->reset();
+
+/*
+// ------------------------ This one works, but doesn't allow any pre-buffering.
+  threadStart();
+  afeedr.start();
+  audio->play();
+  audio->sync();
+
+// ------------------------ This one doesn't work, but it should, and would allow for prebuffering.
+*/
+
+  threadStart();
+    sleep(6);
+
+//  struct timespec delay;
+//  delay.tv_sec = 1;
+//  delay.tv_nsec = 500000000;
+//  nanosleep(&delay, NULL);
+
+  afeedr.start();
+  audio->play();
+//  audio->sync();
+// ------------------------------------------------------------------------------------------------
+
+  playing = 1;
+  return 1;
+}
+
+void PlayerRadio::stop()
+{
+  if (!initted) return;
+  if (!playing) return;
+  playing = 0;
+
+  threadCancel();
+  audio->stop();
+  afeedr.stop();
+
+  feedPosition = 0;
+}
+
+void PlayerRadio::togglePause()
+{
+  if (!initted) return;
+  if (!playing) return;
+
+  if (ffwd) toggleFastForward();
+  if (fbwd) toggleFastBackward();
+
+  if (paused)
+  {
+    audio->unPause();
+    paused = 0;
+  }
+  else
+  {
+    audio->pause();
+    paused = 1;
+  }
+}
+
+void PlayerRadio::setPosition(ULLONG position)
+{
+  feedPosition = position;
+}
+
+void PlayerRadio::setLength(ULLONG length)
+{
+  streamLength = length;
+  Log::getInstance()->log("PlayerRadio", Log::DEBUG, "PlayerRadio has received length of %llu", streamLength);
+}
+
+void PlayerRadio::skipForward()
+{
+  // skip forward 1 minute
+  Log::getInstance()->log("PlayerRadio", Log::DEBUG, "SKIP FORWARD 1 MINUTE");
+
+  if (paused) togglePause();
+
+  threadStop();
+  afeedr.stop();
+  audio->stop();
+  audio->reset();
+  audio->doMuting();  // ???
+  feedPosition += 30000000;
+  afeedr.start();
+  threadStart();
+  audio->play();
+}
+
+void PlayerRadio::skipBackward()
+{
+  // skip forward 1 minute
+  Log::getInstance()->log("PlayerRadio", Log::DEBUG, "SKIP BACKWARD 1 MINUTE");
+
+  if (paused) togglePause();
+
+  threadStop();
+  afeedr.stop();
+  audio->stop();
+  audio->reset();
+  audio->doMuting(); // ???
+  if (feedPosition > 30000000) feedPosition -= 30000000;
+  afeedr.start();
+  threadStart();
+  audio->play();
+}
+
+void PlayerRadio::toggleFastForward()
+{
+  if (!initted) return;
+  if (!playing) return;
+
+  if (paused) togglePause();
+  if (fbwd) toggleFastBackward();
+
+  if (ffwd)
+  {
+    ffwd = 0;
+//    afeedr.enable();
+    audio->reset();
+    audio->systemMuteOff();
+  }
+  else
+  {
+    ffwd = 1;
+//    afeedr.disable();
+    audio->systemMuteOn();
+  }
+}
+
+void PlayerRadio::toggleFastBackward()
+{
+  if (!initted) return;
+  if (!playing) return;
+
+  if (paused) togglePause();
+  if (ffwd) toggleFastForward();
+
+  if (fbwd)
+  {
+    fbwd = 0;
+//    afeedr.enable();
+    audio->systemMuteOff();
+
+//    threadStop();
+    feedMode = MODE_NORMAL;
+//    threadStart();
+  }
+  else
+  {
+    fbwd = 1;
+//    afeedr.disable();
+    audio->systemMuteOn();
+
+    threadStop();
+    feedMode = MODE_BACKWARDS;
+    threadStart();
+  }
+}
+
+void PlayerRadio::jumpToPercent(int percent)
+{
+  threadStop();
+  afeedr.stop();
+  audio->stop();
+  audio->reset();
+  feedPosition = streamLength * percent / 100;
+  afeedr.start();
+  threadStart();
+  audio->play();
+  audio->sync();
+}
+
+
+void PlayerRadio::call()
+{
+  threadSignalNoLock();
+}
+
+// Feed thread
+
+void PlayerRadio::threadMethod()
+{
+  UCHAR buf[blockSize];
+  int thisRead;
+  int writeLength;
+  int thisWrite;
+
+  VDR* vdr = VDR::getInstance();
+
+  int askFor;
+  while(1)
+  {
+    thisRead = 0;
+    writeLength = 0;
+    thisWrite = 0;
+
+    threadCheckExit();
+
+    // a bit hackey. this needs to be split to live and rec players
+    if (streamLength && (feedPosition >= streamLength)) break;
+    askFor = blockSize;
+    if (streamLength && ((feedPosition + blockSize) > streamLength))
+    {
+      askFor = streamLength - feedPosition;
+    }
+    thisRead = vdr->getBlock(buf, feedPosition, askFor);
+
+    if (feedMode == MODE_NORMAL)
+    {
+      feedPosition += thisRead;
+    }
+    else if (feedMode == MODE_BACKWARDS)
+    {
+      if (feedPosition >= 100000)
+      {
+        feedPosition -= 100000;
+      }
+      else
+      {
+        // got to the start of the recording.. revert to play mode? how?
+        feedPosition += thisRead;
+      }
+    }
+
+    threadCheckExit();
+
+    while(writeLength < thisRead)
+    {
+      thisWrite = stream.put(buf + writeLength, thisRead - writeLength);
+      writeLength += thisWrite;
+
+      if (!thisWrite)
+      {
+        Log::getInstance()->log("Player", Log::DEBUG, "RADIO OUTPUT STREAM FULL!!!");
+        // stream is full and cant take anymore
+        threadWaitForSignal();
+        Log::getInstance()->log("Player", Log::DEBUG, "BACK FROM WAIT");
+      }
+
+      threadCheckExit();
+    }
+
+    Log::getInstance()->log("PlayerRadio", Log::DEBUG, "Written audio");
+
+  }
+}
diff --git a/playerradio.h b/playerradio.h
new file mode 100644 (file)
index 0000000..ba17295
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef PLAYERRADIO_H
+#define PLAYERRADIO_H
+
+#include <stdio.h>
+
+#include "audio.h"
+#include "afeedr.h"
+#include "remote.h"
+#include "thread.h"
+#include "vdr.h"
+#include "callback.h"
+#include "stream.h"
+
+class PlayerRadio : public Thread, public Callback
+{
+  public:
+    PlayerRadio();
+    virtual ~PlayerRadio();
+
+    int init();
+    int shutdown();
+
+    int play();
+    void stop();
+    void togglePause();
+    void toggleFastForward();
+    void toggleFastBackward();
+    void jumpToPercent(int percent);
+    void skipForward();
+    void skipBackward();
+    void call(); // for callback interface
+    void setPosition(ULLONG position);
+    void setLength(ULLONG length);
+
+    void threadMethod();
+
+  private:
+    int initted;
+    Audio* audio;
+    int startup;
+    Stream stream;
+    AFeedR afeedr;
+    ULLONG streamLength;
+    ULLONG feedPosition;
+    UCHAR feedMode;
+    const static UCHAR MODE_NORMAL = 1;
+    const static UCHAR MODE_BACKWARDS = 2;
+    const static int blockSize = 30000;
+
+    UCHAR playing;    // As in not stopped, (playing && paused) can == TRUE
+    UCHAR paused;     // Must be in playing state as well
+    UCHAR ffwd;       // Must be in playing state as well
+    UCHAR fbwd;       // Must be in playing state as well
+};
+
+#endif
diff --git a/queue.cc b/queue.cc
new file mode 100644 (file)
index 0000000..d33fa03
--- /dev/null
+++ b/queue.cc
@@ -0,0 +1,79 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "queue.h"
+
+// ------ Constructor add delete get methods -------------------------------------
+
+Queue::Queue(void)
+{
+  start = NULL;
+  end = NULL;
+}
+
+Queue::~Queue()
+{
+  while(!isEmpty()) retrieve();
+}
+
+void Queue::store(void *newData)
+{
+  Node *temp = new Node(newData, NULL);
+  if (temp == NULL)
+  {
+    // oh dear.
+  }
+  if (start == NULL) // add to empty queue
+  {
+    start = temp;
+    end = temp;
+  }
+  else // add to non-empty queue
+  {
+    end->setPtr(temp);
+    end = temp;
+  }
+}
+
+void *Queue::retrieve(void)
+{
+  if (start == NULL) { return NULL; } // there was an exit EXIT here bug?!!?!?
+  if (start == end) // then we are removing the last node so set end to 0
+  {
+    end = NULL;
+  }
+  void *toReturn = start->getData();
+  Node *next = start->getPtr();
+  delete start;
+  start = next;
+  return toReturn;
+}
+
+void *Queue::peekNext(void)
+{
+  return start->getData();
+}
+
+// ------ Boolean methods -----------------------------------------------------
+
+short Queue::isEmpty(void) const
+{
+  return (start == NULL);
+}
diff --git a/queue.h b/queue.h
new file mode 100644 (file)
index 0000000..29cdd85
--- /dev/null
+++ b/queue.h
@@ -0,0 +1,45 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef QUEUE_H
+#define QUEUE_H
+
+#include <stdio.h>
+
+#include "node.h"
+
+class Queue
+{
+  public:
+    Queue();
+    ~Queue();
+    void store(void *);
+    void *retrieve(void);
+    short isEmpty(void) const;
+    void *peekNext(void);
+
+  private:
+    Node *start;
+    Node *end;
+};
+
+/* The destructor deletes any remaining QNodes but not stored objects. */
+
+#endif
diff --git a/recording.cc b/recording.cc
new file mode 100644 (file)
index 0000000..016ef5a
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "recording.h"
+
+Recording::Recording()
+{
+  start = 0;
+  dirName = NULL;
+  progName = NULL;
+  fileName = NULL;
+
+  index = -1;
+}
+
+Recording::~Recording()
+{
+  if (dirName) delete[] dirName;
+  if (progName) delete[] progName;
+  if (fileName) delete[] fileName;
+  index = -1; // just in case
+}
+
+int Recording::isInDir()
+{
+//  if (strstr(name, "~")) return 1;
+//  else return 0;
+  return (dirName != NULL);
+}
+
+char* Recording::getDirName()
+{
+/*  char* sub = strstr(name, "~");
+  if (!sub) return NULL;
+
+  char* dirName = new char[sub - name + 1];
+  memcpy(dirName, name, sub - name);
+  dirName[sub - name] = '\0';
+  return dirName;
+*/
+  return dirName;
+}
+
+char* Recording::getProgName()
+{
+  return progName;
+}
+
+void Recording::setName(char* name)
+{
+  char* sub = strstr(name, "~");
+
+  if (sub) // Its in a dir
+  {
+    dirName = new char[sub - name + 1];
+    memcpy(dirName, name, sub - name);
+    dirName[sub - name] = '\0';
+
+    sub++;
+    int sublen = strlen(sub);
+    progName = new char[sublen + 1];
+    memcpy(progName, sub, strlen(sub));
+    progName[sublen] = '\0';
+  }
+  else
+  {
+    int len = strlen(name);
+    progName = new char[len + 1];
+    memcpy(progName, name, len);
+    progName[len] = '\0';
+  }
+}
diff --git a/recording.h b/recording.h
new file mode 100644 (file)
index 0000000..57e0701
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef RECORDING_H
+#define RECORDING_H
+
+#include <stdio.h>
+#include <string.h>
+
+class Recording
+{
+  public:
+    Recording();
+    ~Recording();
+
+    void setName(char* name);
+
+    int isInDir();
+    char* getDirName();
+    char* getProgName();
+
+    unsigned long start;
+    char* fileName;
+
+    int index;
+
+  private:
+    char* dirName;
+    char* progName;
+};
+
+#endif
diff --git a/remote.cc b/remote.cc
new file mode 100644 (file)
index 0000000..080bab8
--- /dev/null
+++ b/remote.cc
@@ -0,0 +1,124 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "remote.h"
+
+Remote* Remote::instance = NULL;
+
+Remote::Remote()
+{
+  if (instance) return;
+  instance = this;
+  initted = 0;
+  device = 0;
+  tv.tv_sec = 0;
+  tv.tv_usec = 0;
+}
+
+Remote::~Remote()
+{
+  instance = NULL;
+}
+
+Remote* Remote::getInstance()
+{
+  return instance;
+}
+
+int Remote::init(char* devName)
+{
+  if (initted) return 0;
+  initted = 1;
+
+  device = open(devName, O_RDONLY);
+  if (device < 0)
+  {
+    initted = 0;
+    return 0;
+  }
+
+  return 1;
+}
+
+int Remote::shutdown()
+{
+  if (!initted) return 0;
+  initted = 0;
+  close(device);
+  device = 0;
+  return 1;
+}
+
+int Remote::getDevice()
+{
+  if (!initted) return 0;
+  return device;
+}
+
+UCHAR Remote::getButtonPress(int waitType)
+{
+  /* how = 0 - block
+     how = 1 - start new wait
+     how = 2 - continue wait
+  */
+
+  unsigned long input;
+  struct timeval* passToSelect = NULL;
+  int retval;
+  fd_set readfds;
+
+  if (waitType == 0)
+  {
+    passToSelect = NULL;
+  }
+  else if (waitType == 1)
+  {
+    tv.tv_sec = 1;
+    tv.tv_usec = 000000;
+    passToSelect = &tv;
+  }
+  else if (waitType == 2)
+  {
+    if ((tv.tv_sec == 0) && (tv.tv_usec == 0))  // protection in case timer = 0
+    {
+      tv.tv_sec = 1;
+      tv.tv_usec = 000000;
+    }
+    passToSelect = &tv;
+  }
+  FD_ZERO(&readfds);
+  FD_SET(device, &readfds);
+
+  retval = select(device + 1, &readfds, NULL, NULL, &tv);
+  // 0 = nothing happened
+  // 1 = data arrived (actually num of descriptors that changed)
+  // other value = signal or error
+  if (retval == 0) return NONE;
+  if (retval == -1) return SIGNAL;
+
+  int count = read(device, &input, 4);
+  if (count == 4)
+  {
+    input = (0X00FF0000 & input) >> 16;
+    Log::getInstance()->log("Remote", Log::DEBUG, "Button %i", input);
+    return (UCHAR) input;
+  }
+  return UNKNOWN;
+}
diff --git a/remote.h b/remote.h
new file mode 100644 (file)
index 0000000..440718c
--- /dev/null
+++ b/remote.h
@@ -0,0 +1,88 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef REMOTE_H
+#define REMOTE_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "defines.h"
+#include "log.h"
+
+class Remote
+{
+  public:
+    Remote();
+    ~Remote();
+    static Remote* getInstance();
+
+    int init(char *devName);
+    int shutdown();
+    int getDevice();
+    UCHAR getButtonPress(int how);
+
+    const static UCHAR ZERO        = 0;
+    const static UCHAR ONE         = 1;
+    const static UCHAR TWO         = 2;
+    const static UCHAR THREE       = 3;
+    const static UCHAR FOUR        = 4;
+    const static UCHAR FIVE        = 5;
+    const static UCHAR SIX         = 6;
+    const static UCHAR SEVEN       = 7;
+    const static UCHAR EIGHT       = 8;
+    const static UCHAR NINE        = 9;
+    const static UCHAR POWER       = 61;
+    const static UCHAR GO          = 59;
+    const static UCHAR BACK        = 31;
+    const static UCHAR MENU        = 13;
+    const static UCHAR RED         = 11;
+    const static UCHAR GREEN       = 46;
+    const static UCHAR YELLOW      = 56;
+    const static UCHAR BLUE        = 41;
+    const static UCHAR LEFT        = 17;
+    const static UCHAR RIGHT       = 16;
+    const static UCHAR UP          = 32;
+    const static UCHAR DOWN        = 33;
+    const static UCHAR MUTE        = 15;
+    const static UCHAR OSD         = 12;
+    const static UCHAR FULL        = 60;
+    const static UCHAR REVERSE     = 50;
+    const static UCHAR PLAY        = 53;
+    const static UCHAR FORWARD     = 52;
+    const static UCHAR RECORD      = 55;
+    const static UCHAR STOP        = 54;
+    const static UCHAR PAUSE       = 48;
+    const static UCHAR SKIPBACK    = 36;
+    const static UCHAR SKIPFORWARD = 30;
+    const static UCHAR OK          = 37;
+    const static UCHAR NONE        = 98;
+    const static UCHAR UNKNOWN     = 99;
+    const static UCHAR SIGNAL      = 100;
+
+  private:
+    static Remote* instance;
+    int initted;
+    int device;
+    struct timeval tv;
+};
+
+#endif
diff --git a/stb.h b/stb.h
new file mode 100644 (file)
index 0000000..62e6873
--- /dev/null
+++ b/stb.h
@@ -0,0 +1,220 @@
+/*
+
+    This file is modified by Chris Tallon from the original stb.h
+    in libav, from the mvpmc project. libav is licensed under the
+    Lesser General Public License.
+
+    As per point 3 of the Lesser General Public License, I am
+    applying the General Public License to my copy of the library
+    and therefore to this file. The copyright notice below has been
+    changed accordingly.
+
+*/
+
+/*
+    Copyright (C) 2004, BtB, Jon Gettler
+    http://mvpmc.sourceforge.net/
+
+    This file 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 file 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 file; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+ */
+
+
+#ifndef STB_H
+#define STB_H
+
+/*
+ * $Id$
+ *
+ * This describes the IBM STBx25xx/STBx30xxx hardware interface.
+ *
+ * Jon Gettler <gettler@acm.org>
+ */
+
+#include <stdint.h>
+
+typedef struct {
+  int arg;
+  int a;
+  int b;
+  int c;
+  int d;
+  int e;
+  int f;
+} set_display_t;
+
+
+
+typedef struct {
+  unsigned long handle1;
+  unsigned long x;
+  unsigned long y;
+  unsigned long w;
+  unsigned long h;
+  unsigned long handle2;
+  unsigned long x1;
+  unsigned long y1;
+  unsigned long w1;
+  unsigned long h1;
+  unsigned long colour1;
+} osd_blend_t;
+
+typedef struct {
+  unsigned long handle;
+  unsigned long x;
+  unsigned long y;
+  unsigned long w;
+  unsigned long h;
+  unsigned long colour1;
+  unsigned long colour2;
+  unsigned long colour3;
+  unsigned long colour4;
+  unsigned long colour5;
+  unsigned long colour6;
+  unsigned long colour7;
+  unsigned char c[2];
+} osd_afillblt_t;
+
+typedef struct {
+  unsigned long handle;
+  unsigned long left;
+  unsigned long top;
+  unsigned long right;
+  unsigned long bottom;
+} osd_clip_rec_t;
+
+typedef struct {
+  int w;
+  int h;
+  int scale;
+  int x1;
+  int y;
+  int x;
+  int y2;
+  int x3;
+  int y3;
+  int x4;
+  int y4;
+} vid_pos_regs_t;
+
+typedef struct {
+  int stc_b32;
+  int stc_b0;
+  int pts_b32;
+  int pts_b0;
+} pts_sync_data_t;
+
+typedef struct {
+  int parm1;
+  int parm2;
+} aud_sync_parms_t;
+
+typedef struct {
+  int aud_ctl0;
+  int aud_ctl1;
+  int aud_ctl2;
+} aud_ctl_regs_t;
+
+typedef struct {
+  int denc0_cr1;
+  int denc1_cr1;
+  int dencmux;
+  int vid_disp_mode;
+} vid_ctl_regs_t;
+
+struct vid_regs {
+  unsigned char dummy[44];
+};
+
+typedef struct {
+  int nleft;
+  int state;
+} vid_state_regs_t;
+
+typedef struct {
+  uint64_t stc;
+  uint64_t pts;
+} sync_data_t;
+
+
+/*
+ * /dev/adec_mpeg
+ */
+#define AV_SET_AUD_PLAY   _IOW('a',2,int)
+#define AV_SET_AUD_PAUSE  _IOW('a',3,int)
+#define AV_SET_AUD_UNPAUSE  _IOW('a',4,int)
+#define AV_SET_AUD_SRC    _IOW('a',5,int)
+#define AV_SET_AUD_MUTE   _IOW('a',6,int)
+#define AV_SET_AUD_CHANNEL  _IOW('a',9,int)
+#define AV_GET_AUD_INFO   _IOR('a',10,int)
+#define AV_SET_AUD_VOLUME _IOW('a',13,int)
+#define AV_GET_AUD_VOLUME _IOR('a',14,int)
+#define AV_SET_AUD_STREAMTYPE _IOW('a',15,int)
+#define AV_SET_AUD_FORMAT _IOW('a',16,int)
+#define AV_GET_AUD_SYNC   _IOR('a',21,pts_sync_data_t*)
+#define AV_SET_AUD_STC    _IOW('a',22,uint64_t *)
+#define AV_SET_AUD_SYNC   _IOW('a',23,int)
+#define AV_SET_AUD_DISABLE_SYNC _IOW('a',24,aud_sync_parms_t*)
+#define AV_SET_AUD_RESET  _IOW('a',26,int)
+#define AV_SET_AUD_DAC_CLK  _IOW('a',27,int)
+#define AV_GET_AUD_REGS   _IOW('a',28,aud_ctl_regs_t*)
+
+/*
+ * /dev/vdec_dev
+ */
+
+// CJT
+#define AV_SET_VID_STOP    _IOW('v', 21, int)
+
+
+#define AV_SET_VID_PLAY   _IOW('v',22,int)
+#define AV_SET_VID_FREEZE _IOW('v',23,int)
+#define AV_SET_VID_RESUME _IOW('v',24,int)
+#define AV_SET_VID_SRC    _IOW('v',25,int)
+#define AV_SET_VID_FB   _IOW('v',26,int)
+#define AV_GET_VID_STATE  _IOR('v',27,vid_state_regs_t*)
+#define AV_SET_VID_PAUSE  _IOW('v',28,int)
+#define AV_SET_VID_FFWD   _IOW('v',29,int)
+#define AV_SET_VID_SLOMO  _IOW('v',30,int)
+#define AV_SET_VID_BLANK  _IOW('v',32,int)
+#define AV_SET_VID_POSITION _IOW('v',36,vid_pos_regs_t*)
+#define AV_SET_VID_SCALE_ON _IOW('v',37,int)
+#define AV_SET_VID_SCALE_OFF  _IOW('v',38,int)
+#define AV_GET_VID_SYNC   _IOR('v',39,int)
+#define AV_SET_VID_STC    _IOW('v',40,uint64_t *)
+#define AV_SET_VID_RATIO  _IOW('v',41,int)
+#define AV_SET_VID_SYNC   _IOW('v',42,int)
+#define AV_SET_VID_DISABLE_SYNC _IOW('v',43,int)
+#define AV_SET_VID_DISP_FMT _IOW('v',45,int)
+#define AV_SET_VID_RESET  _IOW('v',51,int)
+#define AV_SET_VID_OUTPUT _IOW('v',57,int)
+#define AV_SET_VID_MODE   _IOW('v',58,int)
+#define AV_GET_VID_REGS   _IOR('v',61,struct vid_regs*)
+#define AV_SET_VID_COLORBAR _IOW('v',62,int)
+#define AV_SET_VID_DENC   _IOW('v',63,int)
+#define AV_CHK_SCART    _IOW('v',64,int)
+
+/*
+ * screen device
+ */
+#define AV_GET_VID_INFO   _IOR('s',44,int)
+
+/*
+ * /dev/rawir
+ */
+#define IR_SET_LED    _IOW('i',21,int)
+
+
+#endif /* STB_H */
diff --git a/stream.cc b/stream.cc
new file mode 100644 (file)
index 0000000..116d8ea
--- /dev/null
+++ b/stream.cc
@@ -0,0 +1,128 @@
+/*
+    Copyright 2005 Mark Calderbank
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "stream.h"
+
+Stream::Stream()
+{
+  initted = 0;
+}
+
+Stream::~Stream()
+{
+  shutdown();
+}
+
+void Stream::shutdown()
+{
+  if (initted) {
+    free(outbuf);
+  }
+  initted = 0;
+}
+
+int Stream::init(int bufsize)
+{
+  outbuf = (UCHAR*) malloc(bufsize);
+  if (!outbuf) return 1;
+  bufferSize = bufsize;
+  bufferHead = bufferTail = 0;
+  full = 0;
+  initted = 1;
+  return 0;
+}
+
+void Stream::flush()
+{
+  bufferHead = bufferTail = 0;
+  full = 0;
+}
+
+int Stream::put(UCHAR* inbuf, int len)
+{
+  int ret = 0;
+  int localTail = bufferTail;
+  if (len == 0 || (full)) return ret;
+
+  if (bufferHead >= localTail)
+  {
+    // We have free rein to the end of the buffer
+    if (len < (bufferSize - bufferHead))
+    {
+      // We won't reach the end of the buffer.
+      memcpy(outbuf + bufferHead, inbuf, len);
+      bufferHead += len;
+      ret += len; return ret;
+    } else
+    {
+      // We'll reach the end of the buffer and loop round.
+      memcpy(outbuf + bufferHead, inbuf, (bufferSize - bufferHead));
+      inbuf += (bufferSize - bufferHead);
+      ret += (bufferSize - bufferHead);
+      len -= (bufferSize - bufferHead);
+      bufferHead = 0;
+      if (localTail == 0) full = 1;
+      if (len == 0 || (full)) return ret;
+    }
+  }
+  // We can advance the head up to the tail
+  // If we reach it, we are full.
+  if (len < (localTail - bufferHead))
+  {
+    // We'll fall short of the tail.
+    memcpy(outbuf + bufferHead, inbuf, len);
+    bufferHead += len;
+    ret += len; return ret;
+  } else
+  {
+    // We'll hit the tail.
+    memcpy(outbuf + bufferHead, inbuf, (localTail - bufferHead));
+    ret += (localTail - bufferHead);
+    bufferHead = localTail; full = 1;
+    return ret;
+  }
+}
+
+int Stream::drain(int fd)
+{
+  int ret = 0;
+  int localHead = bufferHead;
+  int written;
+  if (localHead == bufferTail && (!full)) return ret;
+
+  if (localHead <= bufferTail)
+  {
+    // Drain to the end of the buffer
+    written = write(fd, outbuf + bufferTail, (bufferSize - bufferTail));
+    if (written < 0) return ret;
+    full = 0;
+    ret += written;
+    if (written == (bufferSize - bufferTail))
+      bufferTail = 0;
+    else
+      bufferTail += written;
+    if (localHead == 0) return ret;
+  }
+  written = write(fd, outbuf + bufferTail, (localHead - bufferTail));
+  if (written < 0) return ret;
+  ret += written;
+  bufferTail += written;
+  return ret;
+}
diff --git a/stream.h b/stream.h
new file mode 100644 (file)
index 0000000..bb3b572
--- /dev/null
+++ b/stream.h
@@ -0,0 +1,50 @@
+/*
+    Copyright 2005 Mark Calderbank
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef STREAM_H
+#define STREAM_H
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <memory.h>
+#include "defines.h"
+
+class Stream
+{
+  public:
+    Stream();
+    ~Stream();
+    int init(int bufsize);
+    void shutdown();
+    void flush();
+    int put(UCHAR* inbuf, int len);
+    int drain(int fd);
+
+  private:
+
+    int initted;
+    UCHAR* outbuf;
+    int bufferSize;
+    int bufferHead;
+    int bufferTail;
+    int full;
+};
+
+#endif
diff --git a/surface.cc b/surface.cc
new file mode 100644 (file)
index 0000000..d550b30
--- /dev/null
@@ -0,0 +1,526 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+    Portions copyright 2004 Jon Gettler
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "surface.h"
+
+Surface* Surface::screen = NULL;
+Surface* Surface::buffer = NULL;
+int Surface::disableDoubleBuffering = 0;
+
+Surface::Surface(int fd, int id)
+{
+  if (id == SCREEN) screen = this;
+  if (id == BUFFER) buffer = this;
+
+  fdOsd = fd;
+  memset(&surface, 0, sizeof(osd_surface_t));
+  memset(&surface.sfc, 0, sizeof(stbgfx_sfc_t));
+  memset(&surface.map, 0, sizeof(stbgfx_map_t));
+
+  font = &font_helvB18;
+}
+
+Surface::~Surface()
+{
+  for (int i = 0; i < 3; i++)
+  {
+    if (surface.base[i]) munmap(surface.base[i], surface.map.map[i].size);
+  }
+
+  int a;
+
+  a = ioctl(fdOsd, GFX_FB_SFC_UNMAP, surface.sfc.handle);
+  if (a) Log::getInstance()->log("Surface", Log::ERR, "Surface unmap failed");
+
+  a = ioctl(fdOsd, GFX_FB_SFC_FREE, surface.sfc.handle);
+  if (a) Log::getInstance()->log("Surface", Log::ERR, "Surface destroy failed");
+
+}
+
+void Surface::disableBuffer()
+{
+  disableDoubleBuffering = 1;
+}
+
+Surface* Surface::getObject(int id)
+{
+  if (id == SCREEN) return screen;
+  if (disableDoubleBuffering) return screen;
+  if (id == BUFFER) return buffer;
+  return NULL;
+}
+
+int Surface::create(int height, int width)
+{
+  int r = 0;
+  int displayNumber = 0; // mvpmc iterates 0->15 till it gets one that works?
+
+  surface.sfc.width = width;
+  surface.sfc.height = height;
+  surface.sfc.flags = 0x3f1533;
+
+  surface.sfc.unknown = -1;
+
+  r = ioctl(fdOsd, GFX_FB_SET_OSD, &displayNumber);
+  if (r) return 0;
+
+  r = ioctl(fdOsd, GFX_FB_OSD_SURFACE, &displayNumber);
+  if (r) return 0;
+
+  r = ioctl(fdOsd, GFX_FB_SFC_ALLOC, &surface.sfc);
+  if (r) return 0;
+
+  surface.map.map[0].unknown = surface.sfc.handle;
+  r = ioctl(fdOsd, GFX_FB_MAP, &surface.map);
+  if (r) return 0;
+
+  surface.base[0] = (unsigned char *)mmap(NULL, surface.map.map[0].size, PROT_READ|PROT_WRITE, MAP_SHARED, fdOsd, surface.map.map[0].addr);
+  if (surface.base[0] == MAP_FAILED) return 0;
+
+  surface.base[1] = (unsigned char *)mmap(NULL, surface.map.map[1].size, PROT_READ|PROT_WRITE, MAP_SHARED, fdOsd, surface.map.map[1].addr);
+  if (surface.base[1] == MAP_FAILED) return 0;
+
+  surface.base[2] = (unsigned char *)mmap(NULL, surface.map.map[2].size, PROT_READ|PROT_WRITE, MAP_SHARED, fdOsd, surface.map.map[2].addr);
+  if (surface.base[2] == MAP_FAILED) return 0;
+
+  surface.display.num = displayNumber;
+  r = ioctl(fdOsd, GFX_FB_MOVE_DISPLAY, &surface.display);
+  if (r) return 0;
+
+  r = ioctl(fdOsd, GFX_FB_SET_DISPLAY, &surface.display);
+  if (r) return 0;
+
+  return 1;
+}
+
+void Surface::display()
+{
+  unsigned long fb_descriptor[2];
+
+  fb_descriptor[0] = surface.sfc.handle;
+  fb_descriptor[1] = 1;
+
+  ioctl(fdOsd, GFX_FB_ATTACH, fb_descriptor);
+}
+
+unsigned long Surface::getSurfaceHandle()
+{
+  return surface.sfc.handle;
+}
+
+// ----------------------------------------------------------------------------
+
+// Now for the drawing functions
+
+/*
+ * RGB to YUV conversion tables
+ */
+int Surface::conv_YB[256];
+int Surface::conv_YG[256];
+int Surface::conv_YR[256];
+int Surface::conv_UB[256];
+int Surface::conv_UG[256];
+int Surface::conv_UR[256];
+int Surface::conv_VB[256];
+int Surface::conv_VG[256];
+int Surface::conv_VR[256];
+
+int Surface::conv_BY[256];
+int Surface::conv_GY[256];
+int Surface::conv_RY[256];
+int Surface::conv_BU[256];
+int Surface::conv_GU[256];
+int Surface::conv_RU[256];
+int Surface::conv_BV[256];
+int Surface::conv_GV[256];
+int Surface::conv_RV[256];
+
+/*
+ * gfx_init() - initialize the RGB to YUV conversion tables
+ */
+void Surface::initConversionTables(void)
+{
+  int i;
+
+  for (i=0; i<256; i++) {
+    conv_YB[i] = (int)(0.299 * (double)i);
+    conv_BY[i] = i;
+  }
+  for (i=0; i<256; i++) {
+    conv_YG[i] = (int)(0.587 * (double)i);
+    conv_GY[i] = i;
+  }
+  for (i=0; i<256; i++) {
+    conv_YR[i] = (int)(0.114 * (double)i);
+    conv_RY[i] = i;
+  }
+
+  for (i=0; i<256; i++) {
+    conv_UB[i] = (int)(0.5 * (double)i);
+    conv_BU[i] = (int)(1.732 * (i - 128));
+  }
+  for (i=0; i<256; i++) {
+    conv_UG[i] = (int)(-0.33126 * (double)i);
+    conv_GU[i] = (int)(-0.338 * (i - 128));
+  }
+  for (i=0; i<256; i++) {
+    conv_UR[i] = (int)(-0.16874 * (double)i);
+    conv_RU[i] = 0;
+  }
+
+  for (i=0; i<256; i++) {
+    conv_VB[i] = (int)(-0.08131 * (double)i);
+    conv_BV[i] = 0;
+  }
+  for (i=0; i<256; i++) {
+    conv_VG[i] = (int)(-0.41869 * (double)i);
+    conv_GV[i] = (int)(-0.698 * (i - 128));
+  }
+  for (i=0; i<256; i++) {
+    conv_VR[i] = (int)(0.5 * (double)i);
+    conv_RV[i] = (int)(1.370 * ((double)i - 128));
+  }
+}
+
+/*
+ * rgb2yuv() - convert an RGB pixel to YUV
+ */
+ //inline me?
+void Surface::rgb2yuv(unsigned char r, unsigned char g, unsigned char b, unsigned char *y, unsigned char *u, unsigned char *v)
+{
+  int Y, U, V;
+
+  Y = conv_YB[b] + conv_YG[g] + conv_YR[r];
+  U = conv_UB[b] + conv_UG[g] + conv_UR[r] + 128;
+  V = conv_VB[b] + conv_VG[g] + conv_VR[r] + 128;
+
+  if (Y > 255)
+    Y = 255;
+  else if (Y < 0)
+    Y = 0;
+  if (U > 255)
+    U = 255;
+  else if (U < 0)
+    U = 0;
+  if (V > 255)
+    V = 255;
+  else if (V < 0)
+    V = 0;
+
+  *y = Y;
+  *u = U;
+  *v = V;
+}
+
+int Surface::fillblt(int x, int y, int width, int height, unsigned int c)
+{
+  osd_fillblt_t fblt;
+
+  fblt.handle = surface.sfc.handle;
+  fblt.x = x;
+  fblt.y = y;
+  fblt.width = width;
+  fblt.height = height;
+  fblt.colour = c;
+
+  return ioctl(fdOsd, GFX_FB_OSD_FILLBLT, &fblt);
+}
+
+void Surface::drawPixel(int x, int y, unsigned int c)
+{
+  int offset;
+  unsigned char r, g, b, a, Y, U, V;
+  unsigned int line, remainder;
+
+  if ((x >= (int)surface.sfc.width) || (y >= (int)surface.sfc.height))
+    return;
+
+  c2rgba(c, &r, &g, &b, &a);
+
+  rgb2yuv(r, g, b, &Y, &U, &V);
+
+  remainder = (surface.sfc.width % 4);
+  if (remainder == 0)
+    line = surface.sfc.width;
+  else
+    line = surface.sfc.width + (4 - remainder);
+
+  offset = (y * line) + x;
+
+  *(surface.base[0] + offset) = Y;
+  *(surface.base[1] + (offset & 0xfffffffe)) = U;
+  *(surface.base[1] + (offset & 0xfffffffe) + 1) = V;
+  *(surface.base[2] + offset) = a;
+
+}
+
+void Surface::drawHorzLine(int x1, int x2, int y, unsigned int c)
+{
+  fillblt(x1, y, x2-x1, 1, c);
+}
+
+void Surface::drawVertLine(int x, int y1, int y2, unsigned int c)
+{
+  fillblt(x, y1, 1, y2-y1, c);
+}
+
+void Surface::bufferToScreen() // static, this is for Box::showAll
+{
+  if (disableDoubleBuffering) return;
+  buffer->updateToScreen(0, 0, buffer->surface.sfc.width, buffer->surface.sfc.height);
+}
+
+int Surface::updateToScreen(int x, int y, int width, int height) // main method for all normal windows
+{
+  /*
+  With double buffering:
+    A view has buffer for its surface. this is buffer, copy area specified to screen
+  Without double buffering:
+    A view has screen for its surface. this is screen, all painting work has already been done. ignore
+  */
+
+  if (this == screen) return 0;
+
+  return blt(fdOsd, surface.sfc.handle, x, y, width, height, screen->getSurfaceHandle(), x, y);
+}
+
+int Surface::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
+{
+  osd_bitblt_t fblt;
+  memset(&fblt, 0, sizeof(fblt));
+
+  fblt.dst_handle = dhandle;
+  fblt.dst_x = dx;
+  fblt.dst_y = dy;
+
+  fblt.src_handle = shandle;
+  fblt.src_x = sx;
+  fblt.src_y = sy;
+
+  fblt.width = width;
+  fblt.height = height;
+
+  fblt.u1 = 1;
+  fblt.u2 = 0;
+  fblt.u3 = 0x0f;
+
+  return ioctl(fd, GFX_FB_OSD_BITBLT, &fblt);
+}
+
+int Surface::drawText(char* text, int x, int y, int r, int g, int b)
+{
+  int h, n, i;
+  int Y, X, cx;
+  unsigned long fg;
+
+  fg = rgba(r, g, b, 255);
+
+  n = strlen(text);
+  h = font->height;
+
+  X = 0;
+  cx = 0;
+  for (i=0; i<n; i++)
+  {
+    unsigned char c = text[i];
+    unsigned long *character = &font->content[font->offset[c]];
+    int w = font->width[c];
+    int pixels = 0;
+
+    for (X=0; X<w; X++)
+    {
+      for (Y=0; Y<h; Y++)
+      {
+        if ((character[Y] >> (32 - X)) & 0x1)
+        {
+          drawPixel(x+X+cx, y+Y, fg);
+          pixels++;
+        }
+      }
+    }
+    cx += w;
+  }
+  return 1;
+}
+
+int Surface::drawTextRJ(char* text, int x, int y, int r, int g, int b)
+{
+  int i, n, w;
+  w = 0;
+
+  n = strlen(text);
+
+  for (i = 0; i < n; i++)
+  {
+    w += font->width[text[i]];
+  }
+
+  x -= w;
+
+  if (x < 0) return 0;
+  else return drawText(text, x, y, r, g, b);
+}
+
+int Surface::getCharWidth(char c)
+{
+  return font->width[c];
+}
+
+int Surface::getFontHeight()
+{
+  return font->height;
+}
+
+void Surface::screenShot(char* fileName)
+{
+  Log* logger = Log::getInstance();
+
+  FILE* outfile = fopen(fileName, "w");
+  if (outfile == NULL)
+  {
+    logger->log("Surface", Log::ERR, "Can't open JPEG");
+    return;
+  }
+  logger->log("Surface", Log::DEBUG, "File opened %u %u", surface.sfc.height, surface.sfc.width);
+
+  struct jpeg_compress_struct cinfo;
+  struct jpeg_error_mgr jerr;
+  cinfo.err = jpeg_std_error(&jerr);
+  jpeg_create_compress(&cinfo);
+  jpeg_stdio_dest(&cinfo, outfile);
+  cinfo.image_width = surface.sfc.width;
+  cinfo.image_height = surface.sfc.height;
+  cinfo.input_components = 3;
+  cinfo.in_color_space = JCS_RGB;
+  jpeg_set_defaults(&cinfo);
+  jpeg_start_compress(&cinfo, TRUE);
+
+
+  unsigned char row[surface.sfc.width * 3];
+  unsigned char* prow = (unsigned char*)&row;
+  unsigned char r, g, b;
+
+  while (cinfo.next_scanline < cinfo.image_height)
+  {
+    for(unsigned int i = 0; i < surface.sfc.width; i++)
+    {
+      readPixel(i, cinfo.next_scanline, &r, &g, &b);
+      row[i * 3] = r;
+      row[(i * 3) + 1] = g;
+      row[(i * 3) + 2] = b;
+    }
+    jpeg_write_scanlines(&cinfo, (JSAMPLE **)&prow, 1);
+  }
+
+  jpeg_finish_compress(&cinfo);
+  jpeg_destroy_compress(&cinfo);
+  fclose(outfile);
+  logger->log("Surface", Log::DEBUG, "Jpeg saved");
+}
+
+void Surface::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
+{
+  int offset;
+  unsigned char a, Y, U, V;
+  unsigned int line, remainder;
+
+  if (((unsigned int)x >= surface.sfc.width) || ((unsigned int)y >= surface.sfc.height)) return;
+
+  remainder = (surface.sfc.width % 4);
+  if (remainder == 0)
+    line = surface.sfc.width;
+  else
+    line = surface.sfc.width + (4 - remainder);
+
+  offset = (y * line) + x;
+
+  Y = *(surface.base[0] + offset);
+  U = *(surface.base[1] + (offset & 0xfffffffe));
+  V = *(surface.base[1] + (offset & 0xfffffffe) + 1);
+  a = *(surface.base[2] + offset);
+
+  yuv2rgb(Y, U, V, r, g, b);
+}
+
+void Surface::yuv2rgb(int y, int u, int v, unsigned char* pr, unsigned char* pg, unsigned char* pb)
+{
+   // from http://www.fourcc.org/index.php?http%3A//www.fourcc.org/fccyvrgb.php
+
+//   unsigned int pixel32;
+//   unsigned char *pixel = (unsigned char *)&pixel32;
+   int r, g, b;
+
+
+   /*
+     One formula I found:  (not the right one)
+
+     R = 1.164(Y - 16) + 1.596(Cr - 128)
+     G = 1.164(Y - 16) - 0.813(Cr - 128) - 0.391(Cb - 128)
+     B = 1.164(Y - 16)                   + 2.018(Cb - 128)
+
+
+   r = (1.164 * (y - 16))
+      + (2.018 * (v - 128));
+   g = (1.164 * (y - 16))
+      - (0.813 * (u - 128))
+      - (0.391 * (v - 128));
+   b = (1.164 * (y - 16))
+      + (1.596 * (u - 128));
+
+
+     Another formula I found:  (seems to work)
+
+     R = Y + 1.370705 (V-128)
+     G = Y - 0.698001 (V-128) - 0.337633 (U-128)
+     B = Y + 1.732446 (U-128)
+   */
+
+   r = (int)( y + (1.370705 * (v-128)) );
+   g = (int)( y - (0.698001 * (v-128)) - (0.337633 * (u-128)) );
+   b = (int)( y + (1.732446 * (u-128)) );
+
+   // Even with proper conversion, some values still need clipping.
+   if (r > 255) r = 255;
+   if (g > 255) g = 255;
+   if (b > 255) b = 255;
+   if (r < 0) r = 0;
+   if (g < 0) g = 0;
+   if (b < 0) b = 0;
+
+   // Values only go from 0-220..  Why?
+//   pixel[0] = r * 220 / 256;
+//   pixel[1] = g * 220 / 256;
+//   pixel[2] = b * 220 / 256;
+//   pixel[3] = 0;
+
+   *pr = (unsigned char) (r * 220 / 256);
+   *pg = (unsigned char) (g * 220 / 256);
+   *pb = (unsigned char) (b * 220 / 256);
+
+   /* Debug
+   //printf("yuv2rgb(%i, %i, %i) -> %i, %i, %i  (0x%x)\n",
+    y, u, v,
+    pixel[0], pixel[1], pixel[2],
+    pixel32);
+   */
+
+//   return pixel32;
+}
diff --git a/surface.h b/surface.h
new file mode 100644 (file)
index 0000000..fde124d
--- /dev/null
+++ b/surface.h
@@ -0,0 +1,249 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+    Portions copyright 2004 Jon Gettler
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef SURFACE_H
+#define SURFACE_H
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+// Structures for surface management
+
+typedef struct
+{
+  unsigned long num;
+  unsigned long unknown[4];
+  unsigned long width;
+  unsigned long height;
+  char unknown2;
+} stbgfx_display_t;
+
+typedef struct
+{
+  unsigned long unknown;
+  unsigned long win_unknown;
+  unsigned long addr;
+  unsigned long size;
+  unsigned long unknown2;
+  unsigned long width;
+  unsigned long height;
+  unsigned long unknown3;
+  unsigned long unknown4;
+  unsigned long width2;
+  unsigned long unknown5;
+  unsigned long unknown6;
+} stbgfx_map_item_t;
+
+typedef struct {
+  stbgfx_map_item_t map[3];
+  unsigned long other[2];
+} stbgfx_map_t;
+
+typedef struct
+{
+  unsigned long handle; /* surface handle */
+  unsigned long width;
+  unsigned long height;
+  unsigned long flags;
+  long unknown;   //unsigned long
+  unsigned long depth;  /* number of subplanes */
+} stbgfx_sfc_t;
+
+typedef struct
+{
+  stbgfx_display_t display;
+  stbgfx_map_t map;
+  stbgfx_sfc_t sfc;
+  unsigned char *base[3];
+} osd_surface_t;
+
+
+// Structures for surface drawing
+
+typedef struct
+{
+  unsigned long handle;
+  unsigned long x;
+  unsigned long y;
+  unsigned long width;
+  unsigned long height;
+  unsigned long colour;
+} osd_fillblt_t;
+
+typedef struct {
+  unsigned long dst_handle;
+  unsigned long dst_x;
+  unsigned long dst_y;
+  unsigned long width;
+  unsigned long height;
+  unsigned long src_handle;
+  unsigned long src_x;
+  unsigned long src_y;
+  unsigned long u1;
+  unsigned long u2;
+  unsigned char u3;
+} osd_bitblt_t;
+
+// Font stuff
+
+typedef struct bogl_font {
+  char *name;     /* Font name. */
+  int height;     /* Height in pixels. */
+  unsigned long *content;   /* 32-bit right-padded bitmap array. */
+  short *offset;      /* 256 offsets into content. */
+  unsigned char *width;   /* 256 character widths. */
+} osd_font_t;
+
+extern osd_font_t font_CaslonRoman_1_25;
+extern osd_font_t font_helvB24;
+extern osd_font_t font_helvB18;
+
+// Surface ioctls
+
+#define GFX_FB_SFC_ALLOC  _IOWR(0xfb,1,int*)
+#define GFX_FB_SFC_FREE   _IOWR(0xfb,2,int)
+#define GFX_FB_MAP    _IOWR(0xfb,3,int*)
+#define GFX_FB_SFC_UNMAP  _IOWR(0xfb,4,int)
+#define GFX_FB_SET_PAL_1  _IOWR(0xfb,5,int*)
+#define GFX_FB_SET_PAL_2  _IOW(0xfb,6,int*)
+#define GFX_FB_OSD_SURFACE  _IO(0xfb,7)
+#define GFX_FB_SFC_SET_SHARE  _IOW(0xfb,8,int)
+#define GFX_FB_OSD_CUR_SETATTR  _IOW(0xfb,9,int*)
+#define GFX_FB_ATTACH   _IOW(0xfb,11,int)
+#define GFX_FB_SFC_DETACH _IOW(0xfb,12,int*)
+#define GFX_FB_MOVE_DISPLAY _IOWR(0xfb,13,int)
+#define GFX_FB_SET_DISPLAY  _IOW(0xfb,14,int)
+#define GFX_FB_OSD_CUR_MOVE_1 _IOW(0xfb,15,int*)
+#define GFX_FB_OSD_CUR_MOVE_2 _IOW(0xfb,16,int)
+#define GFX_FB_SET_OSD    _IOW(0xfb,18,int)
+#define GFX_FB_SET_DISP_CTRL  _IOW(0xfb,21,int*)
+#define GFX_FB_GET_DISP_CTRL  _IOWR(0xfb,22,int*)
+#define GFX_FB_SET_VIS_DEV_CTL  _IOWR(0xfb,23,int*)
+#define GFX_FB_GET_VIS_DEV_CTL  _IOWR(0xfb,24,int*)
+#define GFX_FB_OSD_BITBLT _IOW(0xfb,51,osd_bitblt_t*)
+#define GFX_FB_OSD_FILLBLT  _IOW(0xfb,53,osd_fillblt_t*)
+#define GFX_FB_OSD_ADVFILLBLT _IOW(0xfb,54,osd_afillblt_t*)
+#define GFX_FB_OSD_BLEND  _IOW(0xfb,55,int*)
+#define GFX_FB_OSD_ADVBLEND _IOW(0xfb,56,int*)
+#define GFX_FB_OSD_RESIZE _IOW(0xfb,58,int*)
+#define GFX_FB_ENGINE_WAIT  _IOW(0xfb,60,int)
+#define GFX_FB_RESET_ENGINE _IO(0xfb,61)
+#define GFX_FB_SET_ENGINE_MODE  _IOW(0xfb,62,int)
+#define GFX_FB_GET_ENGINE_MODE  _IO(0xfb,63)
+#define GFX_FB_GET_SFC_INFO _IO(0xfb,64,int*)
+#define GFX_FB_OSD_SFC_CLIP _IOW(0xfb,65,osd_clip_rec_t*)
+#define GFX_FB_OSD_COLOURKEY  _IOW(0xfb,67,int*)
+#define GFX_FB_GET_SFC_PSEUDO _IOWR(0xfb,68,int*)
+
+extern "C"
+{
+  #include <jpeglib.h>
+}
+
+#include "log.h"
+
+class Surface
+{
+  public:
+    Surface(int fd, int id);
+    ~Surface();
+
+    static Surface* getObject(int id);
+
+    int create(int height, int width);
+    void display();
+    unsigned long getSurfaceHandle();
+
+    int fillblt(int x, int y, int width, int height, unsigned int c);
+    void drawPixel(int x, int y, unsigned int c);
+    void drawHorzLine(int x1, int x2, int y, unsigned int c);
+    void drawVertLine(int x, int y1, int y2, unsigned int c);
+    int updateToScreen(int x, int y, int width, int height);
+    int drawText(char* text, int x, int y, int r, int g, int b);
+    int drawTextRJ(char* text, int x, int y, int r, int g, int b);
+    int getCharWidth(char c);
+    int getFontHeight();
+    void readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b);
+    void yuv2rgb(int y, int u, int v, unsigned char* pr, unsigned char* pg, unsigned char* pb);
+    void screenShot(char* fileName);
+
+    static void initConversionTables();
+
+    static void disableBuffer();
+    static void bufferToScreen();
+    static int blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy);
+
+    const static int SCREEN = 1;
+    const static int BUFFER = 2;
+
+    // Implicit inlines
+    void c2rgba(unsigned long c, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)
+    {
+      *a = (c & 0xff000000) >> 24;
+      *r = (c & 0x00ff0000) >> 16;
+      *g = (c & 0x0000ff00) >> 8;
+      *b = (c & 0x000000ff);
+    }
+
+    unsigned long rgba(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+    {
+      return (a<<24) | (r<<16) | (g<<8) | b;
+
+    }
+
+  private:
+    static Surface* screen;
+    static Surface* buffer;
+    static int disableDoubleBuffering;
+
+    int fdOsd;
+
+    osd_surface_t surface;
+    osd_font_t* font;
+
+    void rgb2yuv(unsigned char r, unsigned char g, unsigned char b, unsigned char *y, unsigned char *u, unsigned char *v);
+
+    static int conv_YB[256];
+    static int conv_YG[256];
+    static int conv_YR[256];
+    static int conv_UB[256];
+    static int conv_UG[256];
+    static int conv_UR[256];
+    static int conv_VB[256];
+    static int conv_VG[256];
+    static int conv_VR[256];
+
+    static int conv_BY[256];
+    static int conv_GY[256];
+    static int conv_RY[256];
+    static int conv_BU[256];
+    static int conv_GU[256];
+    static int conv_RU[256];
+    static int conv_BV[256];
+    static int conv_GV[256];
+    static int conv_RV[256];
+
+};
+
+#endif
diff --git a/tcp.cc b/tcp.cc
new file mode 100644 (file)
index 0000000..ef78c96
--- /dev/null
+++ b/tcp.cc
@@ -0,0 +1,403 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+    Copyright 2003-2004 University Of Bradford
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "tcp.h"
+
+TCP::TCP()
+{
+  sock = 0;
+  connected = 0;
+  timeoutEnabled = 1;
+}
+
+TCP::~TCP()
+{
+  if (connected)
+  {
+    close(sock);
+    Log::getInstance()->log("TCP", Log::DEBUG, "Have closed");
+  }
+}
+
+void TCP::disableTimeout()
+{
+  timeoutEnabled = 0;
+}
+
+int TCP::connectTo(char* host, unsigned short port)
+{
+  sock = socket(PF_INET, SOCK_STREAM, 0);
+  if (sock == -1) return 0;
+
+  struct sockaddr_in dest_addr;
+  dest_addr.sin_family = AF_INET;
+  dest_addr.sin_port = htons(port);
+
+  if (!inet_aton(host, &dest_addr.sin_addr))
+  {
+    close(sock);
+    return 0;
+  }
+
+  memset(&(dest_addr.sin_zero), '\0', 8);
+
+  // set non blocking
+  int oldflags = fcntl (sock, F_GETFL, 0);
+  oldflags |= O_NONBLOCK;
+  fcntl(sock, F_SETFL, oldflags);
+
+  // ok, how to open a connection in non blocking mode (and therefore have a self set timeout!!)
+
+  int success = connect(sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr));
+
+  if (success == 0)  // if by some miracle the connection succeeded in no time flat, just return!
+  {
+    connected = 1;
+    return 1;
+  }
+
+  // first check errno for EINPROGRESS, otherwise it's a fail
+  // this doesn't work?
+  if (errno != EINPROGRESS)
+  {
+    close(sock);
+    return 0;
+  }
+
+  // now do a timeout wait on writability on the socket
+
+  fd_set connectSet;
+  struct timeval timeout;
+  FD_ZERO(&connectSet);
+  FD_SET(sock, &connectSet);
+  timeout.tv_sec = 10;
+  timeout.tv_usec = 0;
+  success = select(sock + 1, NULL, &connectSet, NULL, &timeout);
+  if (success < 1)
+  {
+    // timeout or error
+    close(sock);
+    return 0;
+  }
+
+  // so the socket became available for writing. Contrary to expectation, this doesn't actually
+  // mean it connected...
+
+  int soError;
+  socklen_t soErrorSize = sizeof(soError);
+  int gso = getsockopt(sock, SOL_SOCKET, SO_ERROR, &soError, &soErrorSize);
+
+  if ((gso == 0) && (soError == 0))
+  {
+    // success!
+    connected = 1;
+    return 1;
+  }
+  else
+  {
+    close(sock);
+    return 0;
+  }
+
+/*
+The full documentation:
+
+       EINPROGRESS
+              The  socket is non-blocking and the connection can­
+              not be completed immediately.  It  is  possible  to
+              select(2)  or  poll(2)  for completion by selecting
+              the socket  for  writing.  After  select  indicates
+              writability, use getsockopt(2) to read the SO_ERROR
+              option at level  SOL_SOCKET  to  determine  whether
+              connect  completed  successfully (SO_ERROR is zero)
+              or unsuccessfully (SO_ERROR is  one  of  the  usual
+              error  codes listed here, explaining the reason for
+              the failure).
+*/
+}
+
+void TCP::assignSocket(int tsocket)
+{
+  sock = tsocket;
+}
+
+int TCP::isConnected()
+{
+  return connected;
+}
+
+int TCP::sendPacket(void* buf, size_t count)
+{
+  size_t bytes_sent = 0;
+  int this_write;
+  int temp_write;
+
+  while (bytes_sent < count)
+  {
+    do
+    {
+      temp_write = this_write = write(sock, buf, count - bytes_sent);
+//      Log::getInstance()->log("TCP", Log::DEBUG, "TCP has written %i bytes", temp_write);
+    } while ( (this_write < 0) && (errno == EINTR) );
+
+
+    if (this_write <= 0)
+    {
+      return(this_write);
+    }
+    bytes_sent += this_write;
+    (unsigned char*)buf += this_write;
+  }
+  return(count);
+}
+
+UCHAR* TCP::receivePacket()
+{
+  ULONG packetLength;
+  int success;
+
+  success = readData((UCHAR*)&packetLength, sizeof(int));
+  if (!success) return NULL;
+
+  packetLength = ntohl(packetLength);
+
+  if (packetLength > 200000)
+  {
+    Log::getInstance()->log("TCP", Log::ERR, "Received packet > 200000");
+    return NULL;
+  }
+  if (packetLength == 0)
+  {
+    Log::getInstance()->log("TCP", Log::ERR, "Received packet len = 0");
+    return NULL;
+  }
+
+  UCHAR* buffer = (UCHAR*) malloc(packetLength);
+
+  success = readData(buffer, packetLength);
+
+  if (!success)
+  {
+    Log::getInstance()->log("TCP", Log::ERR, "readData failed");
+    free(buffer);
+    close(sock);
+    connected = 0;
+    return NULL;
+  }
+
+  dataLength = packetLength;
+  return buffer;
+}
+
+int TCP::getDataLength()
+{
+  return dataLength;
+}
+
+int TCP::readData(UCHAR* buffer, int totalBytes)
+{
+
+  int bytesRead = 0;
+  int thisRead;
+  int readTries = 0;
+  int success;
+  fd_set readSet;
+  struct timeval timeout;
+  struct timeval* passToSelect;
+
+  if (timeoutEnabled) passToSelect = &timeout;
+  else passToSelect = NULL;
+
+  while(1)
+  {
+    FD_ZERO(&readSet);
+    FD_SET(sock, &readSet);
+    timeout.tv_sec = 10;
+    timeout.tv_usec = 0;
+    success = select(sock + 1, &readSet, NULL, NULL, passToSelect);
+    if (success < 1)
+    {
+      Log::getInstance()->log("TCP", Log::ERR, "Error or timeout");
+      return 0;  // error, or timeout
+    }
+
+    thisRead = read(sock, &buffer[bytesRead], totalBytes - bytesRead);
+    if (!thisRead)
+    {
+      // if read returns 0 then connection is closed
+      // in non-blocking mode if read is called with no data available, it returns -1
+      // and sets errno to EGAGAIN. but we use select so it wouldn't do that anyway.
+      Log::getInstance()->log("TCP", Log::ERR, "Detected connection closed");
+      connected = 0;
+      return 0;
+    }
+    bytesRead += thisRead;
+
+    if (bytesRead == totalBytes)
+    {
+      return 1;
+    }
+    else
+    {
+      if (++readTries == 100)
+      {
+        Log::getInstance()->log("TCP", Log::ERR, "Too many reads");
+        return 0;
+      }
+    }
+  }
+}
+
+void TCP::dump(unsigned char* data, ULONG size)
+{
+  printf("Size = %lu\n", size);
+
+  ULONG c = 0;
+  while(c < size)
+  {
+    if ((size - c) > 15)
+    {
+      printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X  %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
+        data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
+        data[c+8], data[c+9], data[c+10], data[c+11], data[c+12], data[c+13], data[c+14], data[c+15],
+        dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
+        dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]), dcc(data[c+13]), dcc(data[c+14]), dcc(data[c+15]));
+      c += 16;
+    }
+    else
+    {
+      switch (size - c)
+      {
+        case 15:
+          printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X     %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
+            data[c+8], data[c+9], data[c+10], data[c+11], data[c+12], data[c+13], data[c+14],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
+            dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]), dcc(data[c+13]), dcc(data[c+14]));
+          c += 15;
+          break;
+        case 14:
+          printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X        %c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
+            data[c+8], data[c+9], data[c+10], data[c+11], data[c+12], data[c+13],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
+            dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]), dcc(data[c+13]));
+          c += 14;
+          break;
+        case 13:
+          printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X  %02X           %c%c%c%c%c%c%c%c%c%c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
+            data[c+8], data[c+9], data[c+10], data[c+11], data[c+12],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
+            dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]));
+          c += 13;
+          break;
+        case 12:
+          printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X               %c%c%c%c%c%c%c%c%c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
+            data[c+8], data[c+9], data[c+10], data[c+11],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
+            dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]));
+          c += 12;
+          break;
+        case 11:
+          printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X                  %c%c%c%c%c%c%c%c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
+            data[c+8], data[c+9], data[c+10],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
+            dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]));
+          c += 11;
+          break;
+        case 10:
+          printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X                     %c%c%c%c%c%c%c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
+            data[c+8], data[c+9],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
+            dcc(data[c+8]), dcc(data[c+9]));
+          c += 10;
+          break;
+        case 9:
+          printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X                        %c%c%c%c%c%c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
+            data[c+8],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
+            dcc(data[c+8]));
+          c += 9;
+          break;
+        case 8:
+          printf(" %02X %02X %02X %02X  %02X %02X %02X %02X                            %c%c%c%c%c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]));
+          c += 8;
+          break;
+        case 7:
+          printf(" %02X %02X %02X %02X  %02X %02X %02X                               %c%c%c%c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]));
+          c += 7;
+          break;
+        case 6:
+          printf(" %02X %02X %02X %02X  %02X %02X                                  %c%c%c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]));
+          c += 6;
+          break;
+        case 5:
+          printf(" %02X %02X %02X %02X  %02X                                     %c%c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3], data[c+4],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]));
+          c += 5;
+          break;
+        case 4:
+          printf(" %02X %02X %02X %02X                                         %c%c%c%c\n",
+            data[c], data[c+1], data[c+2], data[c+3],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]));
+          c += 4;
+          break;
+        case 3:
+          printf(" %02X %02X %02X                                            %c%c%c\n",
+            data[c], data[c+1], data[c+2],
+            dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]));
+          c += 3;
+          break;
+        case 2:
+          printf(" %02X %02X                                               %c%c\n",
+            data[c], data[c+1],
+            dcc(data[c]), dcc(data[c+1]));
+          c += 2;
+          break;
+        case 1:
+          printf(" %02X                                                  %c\n",
+            data[c],
+            dcc(data[c]));
+          c += 1;
+          break;
+      }
+    }
+  }
+}
+
+UCHAR TCP::dcc(UCHAR c)
+{
+  if (isspace(c)) return ' ';
+  if (isprint(c)) return c;
+  return '.';
+}
diff --git a/tcp.h b/tcp.h
new file mode 100644 (file)
index 0000000..5eeed6b
--- /dev/null
+++ b/tcp.h
@@ -0,0 +1,69 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+    Copyright 2003-2004 University Of Bradford
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef TCP_H
+#define TCP_H
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#include "defines.h"
+#include "log.h"
+
+class TCP
+{
+  public:
+    TCP();
+    ~TCP();
+
+    int connectTo(char *host, unsigned short port);
+    void assignSocket(int tsocket);
+
+    int isConnected();
+    void disableTimeout();
+
+    int sendPacket(void *, size_t size);
+    UCHAR* receivePacket();
+    int getDataLength();
+
+    int readData(UCHAR* buffer, int totalBytes);
+
+    static void dump(unsigned char* data, ULONG size);
+
+  private:
+    int sock;
+    int connected;
+    int timeoutEnabled;
+    int dataLength;
+
+    static UCHAR dcc(UCHAR c);
+};
+
+#endif
diff --git a/thread.cc b/thread.cc
new file mode 100644 (file)
index 0000000..75b4281
--- /dev/null
+++ b/thread.cc
@@ -0,0 +1,92 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "thread.h"
+
+// Undeclared functions, only for use in this file to start the thread
+void threadInternalStart(void *arg)
+{
+  // I don't want signals
+  sigset_t sigset;
+  sigfillset(&sigset);
+  pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+
+  Thread *t = (Thread *)arg;
+  t->threadInternalStart2();
+}
+
+void Thread::threadInternalStart2()
+{
+  threadMethod();
+}
+
+int Thread::threadStart()
+{
+  pthread_cond_init(&threadCond, NULL);
+  pthread_mutex_init(&threadCondMutex, NULL);
+
+  threadActive = 1;
+  if (pthread_create(&pthread, NULL, (void*(*)(void*))threadInternalStart, (void *)this) == -1) return 0;
+  return 1;
+}
+
+void Thread::threadStop()
+{
+  threadActive = 0;
+  // Signal thread here in case it's waiting
+  threadSignal();
+  pthread_join(pthread, NULL);
+}
+
+void Thread::threadCancel()
+{
+  threadActive = 0;
+  pthread_cancel(pthread);
+  pthread_join(pthread, NULL);
+}
+
+void Thread::threadCheckExit()
+{
+  if (!threadActive) pthread_exit(NULL);
+}
+
+char Thread::threadIsActive()
+{
+  return threadActive;
+}
+
+void Thread::threadSignal()
+{
+  pthread_mutex_lock(&threadCondMutex);
+  pthread_cond_signal(&threadCond);
+  pthread_mutex_unlock(&threadCondMutex);
+}
+
+void Thread::threadSignalNoLock()
+{
+  pthread_cond_signal(&threadCond);
+}
+
+void Thread::threadWaitForSignal()
+{
+  pthread_mutex_lock(&threadCondMutex);
+  pthread_cond_wait(&threadCond, &threadCondMutex);
+  pthread_mutex_unlock(&threadCondMutex);
+}
diff --git a/thread.h b/thread.h
new file mode 100644 (file)
index 0000000..d57375a
--- /dev/null
+++ b/thread.h
@@ -0,0 +1,57 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef THREAD_H
+#define THREAD_H
+
+#include <pthread.h>
+#include <signal.h>
+
+class Thread
+{
+  protected:
+    // Override this method in derived classes
+    virtual void threadMethod()=0;
+
+    // Methods to use from outside the thread
+    int threadStart();    // start the thread. threadMethod() will be called in derived class
+    void threadStop();    // stop the thread nicely. thread will be stopped when it next calls threadCheckExit()
+    void threadCancel();  // stop thread immediately. thread will be stopped at the next cancellation point
+    void threadSignal();  // releases a thread that has called threadWaitForSignal
+    void threadSignalNoLock();  // same as above but without locking guarantees. probably not a good idea.
+    char threadIsActive(); // returns 1 if thread has been started but not stop() or cancel() 'd
+
+    // Methods to use from inside the thread
+    void threadCheckExit();      // terminates thread if threadStop() has been called
+    void threadWaitForSignal();  // pauses thread until threadSignal() is called
+
+    // Internal bits and pieces
+
+  private:
+    char threadActive;
+    pthread_t pthread;
+    pthread_cond_t threadCond;
+    pthread_mutex_t threadCondMutex;
+
+  public:
+    void threadInternalStart2();
+};
+
+#endif
diff --git a/vchannellist.cc b/vchannellist.cc
new file mode 100644 (file)
index 0000000..f1a818f
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vchannellist.h"
+
+VChannelList::VChannelList(ULONG type)
+{
+  setScreenPos(80, 70);
+  setDimensions(420, 570);
+
+  setBackgroundColour(0, 0, 100, 255);
+  setTitleBarOn(1);
+
+  if (type == VDR::VIDEO)
+  {
+    setTitleText("Channels");
+  }
+  else if (type == VDR::RADIO)
+  {
+    setTitleText("Radio Stations");
+  }
+  setTitleBarColour(0, 0, 200, 255);
+
+  sl.setScreenPos(screenX + 10, screenY + 30 + 5);
+  sl.setDimensions(height - 30 - 15 - 30, width - 20);
+}
+
+VChannelList::~VChannelList()
+{
+  if (chanList)
+  {
+    while (!chanList->isEmpty())
+    {
+      chanList->reset();
+      delete (Channel*)chanList->remove();
+    }
+
+    delete chanList;
+  }
+}
+
+void VChannelList::setList(List* tlist)
+{
+  char str[500];
+
+  chanList = tlist;
+
+  Channel* chan;
+  int first = 1;
+  if (chanList)
+  {
+    chanList->reset();
+
+    while((chan = (Channel*)chanList->getCurrent()))
+    {
+      sprintf(str, "%lu. %s", chan->number, chan->name);
+      chan->index = sl.addOption(str, first);
+      first = 0;
+      chanList->next();
+    }
+  }
+}
+
+void VChannelList::draw()
+{
+  View::draw();
+  sl.draw();
+
+  // Put the status stuff at the bottom
+
+  WSymbol w;
+
+  w.nextSymbol = WSymbol::UP;
+  w.setScreenPos(screenX + 20, screenY + 385);
+  w.draw();
+
+  w.nextSymbol = WSymbol::DOWN;
+  w.setScreenPos(screenX + 50, screenY + 385);
+  w.draw();
+
+  w.nextSymbol = WSymbol::SKIPBACK;
+  w.setScreenPos(screenX + 85, screenY + 385);
+  w.draw();
+
+  w.nextSymbol = WSymbol::SKIPFORWARD;
+  w.setScreenPos(screenX + 115, screenY + 385);
+  w.draw();
+
+  w.nextSymbol = WSymbol::PLAY;
+  w.setScreenPos(screenX + 150, screenY + 385);
+  w.draw();
+
+  doShowingBar();
+}
+
+void VChannelList::doShowingBar()
+{
+  int topOption = sl.getTopOption() + 1;
+  if (sl.getNumOptions() == 0) topOption = 0;
+
+  char showing[200];
+  sprintf(showing, "%i to %i of %i", topOption, sl.getBottomOption(), sl.getNumOptions());
+  Box b;
+  b.setScreenPos(screenX + 220, screenY + 385);
+  b.setDimensions(25, 160);
+  b.fillColour(0, 0, 100, 255);
+  b.drawText(showing, 0, 0, 255, 255, 255);
+}
+
+int VChannelList::handleCommand(int command)
+{
+  if (command == Remote::UP)
+  {
+    sl.up();
+    sl.draw();
+
+    doShowingBar();
+    show();
+    return 2;
+  }
+  else if (command == Remote::DOWN)
+  {
+    sl.down();
+    sl.draw();
+
+    doShowingBar();
+    show();
+    return 2;
+  }
+  else if (command == Remote::SKIPBACK)
+  {
+    sl.pageUp();
+    sl.draw();
+
+    doShowingBar();
+    show();
+    return 2;
+  }
+  else if (command == Remote::SKIPFORWARD)
+  {
+    sl.pageDown();
+    sl.draw();
+
+    doShowingBar();
+    show();
+    return 2;
+  }
+  else if (command == Remote::OK)
+  {
+    Channel* chan = NULL;
+    if (chanList)
+    {
+      int currentOption = sl.getCurrentOption();
+      chanList->reset();
+
+      while((chan = (Channel*)chanList->getCurrent()))
+      {
+        if (currentOption == chan->index) break;
+        chanList->next();
+      }
+    }
+
+    if (chan == NULL) return 2;
+
+    View* v = NULL;
+
+// stop radio
+//    if (chan->type == VDR::RADIO) return 2;
+
+    if (chan->type == VDR::VIDEO)
+    {
+      v = new VVideoLive(chanList);
+      ((VVideoLive*)v)->setChannel(chan->number);
+    }
+    else if (chan->type == VDR::RADIO)
+    {
+      v = new VRadioLive(chanList);
+      ((VRadioLive*)v)->setChannel(chan->number);
+    }
+
+    ViewMan::getInstance()->addNoLock(v);
+    v->draw();
+    v->show();
+
+    return 2;
+  }
+  else if (command == Remote::BACK)
+  {
+    return 4;
+  }
+  // stop command getting to any more views
+  return 1;
+}
diff --git a/vchannellist.h b/vchannellist.h
new file mode 100644 (file)
index 0000000..d45196c
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VCHANNELLIST_H
+#define VCHANNELLIST_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "view.h"
+#include "list.h"
+#include "wselectlist.h"
+#include "remote.h"
+#include "wsymbol.h"
+#include "viewman.h"
+#include "vdr.h"
+#include "channel.h"
+#include "vvideolive.h"
+#include "vradiolive.h"
+
+class VChannelList : public View
+{
+  public:
+    VChannelList(ULONG type);
+    ~VChannelList();
+
+    void setList(List* chanList);
+
+    int handleCommand(int command);
+    void draw();
+
+  private:
+    List* chanList;
+    ULONG type;
+
+    WSelectList sl;
+
+    void doShowingBar();
+};
+
+#endif
diff --git a/vchannelselect.cc b/vchannelselect.cc
new file mode 100644 (file)
index 0000000..b9e3c17
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vchannelselect.h"
+
+// this class only works as it does because the remote command
+// values for the numbers are the numbers themselves !
+
+VChannelSelect::VChannelSelect(VVideoLive* v, int command)
+{
+  setDimensions(30, 53);
+  setScreenPos(80, 60);
+
+  setBackgroundColour(0, 0, 100, 255);
+
+  first = -1;
+  second = -1;
+  third = command;
+  pos = 0;
+
+  videoLive = v;
+}
+
+void VChannelSelect::draw()
+{
+  View::draw();
+
+  // draw numbers
+
+  char text[2];
+
+  switch(first)
+  {
+    case 0 ... 9:
+    {
+      sprintf(text, "%i", first);
+      drawText(text, 7, 5, 255, 255, 255);
+      break;
+    }
+    case -1:
+    {
+      drawText("_", 7, 5, 255, 255, 255);
+      break;
+    }
+  }
+
+  switch(second)
+  {
+    case 0 ... 9:
+    {
+      sprintf(text, "%i", second);
+      drawText(text, 20, 5, 255, 255, 255);
+      break;
+    }
+    case -1:
+    {
+      drawText("_", 20, 5, 255, 255, 255);
+      break;
+    }
+  }
+
+  switch(third)
+  {
+    case 0 ... 9:
+    {
+      sprintf(text, "%i", third);
+      drawText(text, 33, 5, 255, 255, 255);
+      break;
+    }
+    case -1:
+    {
+      drawText("_", 33, 5, 255, 255, 255);
+      break;
+    }
+  }
+}
+
+int VChannelSelect::handleCommand(int command)
+{
+  switch(command)
+  {
+    case Remote::ZERO ... Remote::NINE:
+    {
+      if (pos == 1) first = second;
+      second = third;
+      third = command;
+      draw();
+      show();
+      if (pos == 1)
+      {
+        Message* m = new Message();
+        m->from = this;
+        m->to = ViewMan::getInstance();
+        m->message = Message::CLOSE_ME;
+        ViewMan::getInstance()->postMessage(m);
+
+        m = new Message();
+        m->from = this;
+        m->to = videoLive;
+        m->message = Message::CHANNEL_CHANGE;
+        m->parameter = (first * 100) + (second * 10) + third;
+        ViewMan::getInstance()->postMessage(m);
+      }
+      pos = 1;
+
+      return 2;
+    }
+  }
+
+  // allow command to drop through to other views
+  return 0;
+}
diff --git a/vchannelselect.h b/vchannelselect.h
new file mode 100644 (file)
index 0000000..0c0461b
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VCHANNELSELECT_H
+#define VCHANNELSELECT_H
+
+#include <stdio.h>
+
+#include "view.h"
+#include "remote.h"
+#include "vvideolive.h"
+#include "message.h"
+#include "viewman.h"
+
+class VVideoLive;
+
+class VChannelSelect : public View
+{
+  public:
+    VChannelSelect(VVideoLive* v, int command);
+    void draw();
+    int handleCommand(int command);
+
+  private:
+    int first;
+    int second;
+    int third;
+
+    int pos;
+
+    VVideoLive* videoLive;
+};
+
+#endif
+
diff --git a/vdr.cc b/vdr.cc
new file mode 100644 (file)
index 0000000..6600856
--- /dev/null
+++ b/vdr.cc
@@ -0,0 +1,608 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vdr.h"
+
+VDR* VDR::instance = NULL;
+
+VDR::VDR()
+{
+  if (instance) return;
+  instance = this;
+  initted = 0;
+  findingServer = 0;
+  tcp = NULL;
+  pthread_mutex_init(&mutex, NULL);
+}
+
+VDR::~VDR()
+{
+  instance = NULL;
+  if (initted) shutdown();
+}
+
+VDR* VDR::getInstance()
+{
+  return instance;
+}
+
+int VDR::init(int tport)
+{
+  if (initted) return 0;
+  initted = 1;
+  port = tport;
+  logger = Log::getInstance();
+  return 1;
+}
+
+int VDR::shutdown()
+{
+  if (!initted) return 0;
+  initted = 0;
+  disconnect();
+  return 1;
+}
+
+void VDR::findServers(std::vector<char*>& serverIPs)
+{
+  findingServer = 1;
+  char* message = "VOMP CLIENT";
+  DatagramSocket ds(port);
+
+  int haveAtLeastOne = 0;
+  char* newIP;
+  int retval;
+  int waitType = 1;
+  while(findingServer)
+  {
+    if (waitType == 1)
+    {
+      logger->log("Core", Log::NOTICE, "Broadcasting for server");
+      ds.send("255.255.255.255", 3024, message, strlen(message));
+    }
+    retval = ds.waitforMessage(waitType);
+
+    if (retval == 2) // we got a reply
+    {
+      if (strcmp(ds.getData(), "VOMP SERVER")) // echo.....
+      {
+        waitType = 2;
+      }
+      else
+      {
+        newIP = new char[16];
+        strcpy(newIP, ds.getFromIPA());
+        serverIPs.push_back(newIP);
+        waitType = 2;
+        haveAtLeastOne = 1;
+      }
+    }
+    else
+    {
+      if (haveAtLeastOne) break;
+      waitType = 1;
+    }
+  }
+}
+
+void VDR::cancelFindingServer()
+{
+  findingServer = 0;
+}
+
+void VDR::setServerIP(char* newIP)
+{
+  strcpy(serverIP, newIP);
+}
+
+int VDR::connect()
+{
+  if (tcp) delete tcp;
+  tcp = new TCP();
+  return tcp->connectTo(serverIP, 3024);
+}
+
+void VDR::disconnect()
+{
+  if (tcp) delete tcp;
+  tcp = NULL;
+}
+
+long VDR::getSimpleReply()
+{
+  unsigned char* p = (unsigned char*)tcp->receivePacket();
+  if (!p) return -1;
+
+  Log::getInstance()->log("VDR", Log::DEBUG, "tcp data length = %i", tcp->getDataLength());
+
+  if (tcp->getDataLength() != 4)
+  {
+    free(p);
+    return -1;
+  }
+
+  ULONG reply = ntohl(*(ULONG*)p);
+
+  Log::getInstance()->log("VDR", Log::DEBUG, "VDR said %li", reply);
+
+  free(p);
+
+  return reply;
+}
+
+char* VDR::getStringReply()
+{
+  unsigned char* p = (unsigned char*)tcp->receivePacket();
+  if (!p) return NULL;
+
+  int dataLength = tcp->getDataLength();
+
+  Log::getInstance()->log("VDR", Log::DEBUG, "Data length %u", dataLength);
+
+  int count = 0;
+
+  char* returnText;
+  int tLength;
+
+  tLength = strlen((char*)&p[count]);
+  returnText = new char[tLength + 1];
+  strcpy(returnText, (char*)&p[count]);
+  count += tLength + 1;
+
+  free(p);
+
+  return returnText;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int VDR::doLogin()
+{
+  UCHAR buffer[8];
+
+  *(unsigned long*)&buffer[0] = htonl(4);
+  *(unsigned long*)&buffer[4] = htonl(VDR_LOGIN);
+
+  pthread_mutex_lock(&mutex);
+  int a = tcp->sendPacket(buffer, 8);
+  if (a != 8)
+  {
+    pthread_mutex_unlock(&mutex);
+    return 0;
+  }
+
+  // reply
+
+  UCHAR* p = tcp->receivePacket();
+  pthread_mutex_unlock(&mutex);
+  if (!p) return 0;
+
+  unsigned long vdrTime = ntohl(*(unsigned long*)p);
+  Log::getInstance()->log("VDR", Log::DEBUG, "vdrtime = %lu", vdrTime);
+
+  struct timespec currentTime;
+  currentTime.tv_sec = vdrTime;
+  currentTime.tv_nsec = 0;
+  int b = clock_settime(CLOCK_REALTIME, &currentTime);
+
+  Log::getInstance()->log("VDR", Log::DEBUG, "set clock = %u", b);
+
+  free(p);
+  return 1;
+}
+
+Directory* VDR::getRecordingsList()
+{
+  UCHAR buffer[8];
+
+  *(unsigned long*)&buffer[0] = htonl(4);
+  *(unsigned long*)&buffer[4] = htonl(VDR_GETRECORDINGLIST);
+
+  pthread_mutex_lock(&mutex);
+  int a = tcp->sendPacket(buffer, 8);
+  if (a != 8)
+  {
+    pthread_mutex_unlock(&mutex);
+    return NULL;
+  }
+
+  // reply
+
+  unsigned char* p = (unsigned char*)tcp->receivePacket();
+  pthread_mutex_unlock(&mutex);
+  if (!p) return 0;
+
+  Directory* recDir = new Directory();
+  recDir->setName("/");
+  recDir->isRoot = 1;
+
+  int dataLength = tcp->getDataLength();
+
+  Log::getInstance()->log("VDR", Log::DEBUG, "Data length %u", dataLength);
+
+  int count = 0;
+
+  Directory::totalSpace = (*(ULONG*)&p[count]);
+  count += sizeof(ULONG);
+  Directory::freeSpace = (*(ULONG*)&p[count]);
+  count += sizeof(ULONG);
+  Directory::usedPercent = (*(ULONG*)&p[count]);
+  count += sizeof(ULONG);
+
+  int tLength;
+
+  while (count < dataLength)
+  {
+    Recording* rec = new Recording();
+    rec->start = ntohl(*(unsigned long*)&p[count]);
+    count += 4;
+
+    tLength = strlen((char*)&p[count]);
+    rec->setName((char*)&p[count]);
+
+//    rec->name = new char[tLength + 1];
+//    strcpy(rec->name, (char*)&p[count]);
+    count += tLength + 1;
+
+    tLength = strlen((char*)&p[count]);
+    rec->fileName = new char[tLength + 1];
+    strcpy(rec->fileName, (char*)&p[count]);
+    count += tLength + 1;
+
+    if(rec->isInDir())
+    {
+      char* dirName = rec->getDirName();
+
+      Directory* d = recDir->getDirByName(dirName);
+      if (!d)
+      {
+        d = new Directory();
+        d->setName(dirName);
+        Log::getInstance()->log("VDR", Log::DEBUG, "Added a new directory = %s", d->name);
+        recDir->dirList->add(d);
+      }
+
+      d->recList->add(rec);
+      d->recList->next();
+    }
+    else
+    {
+      recDir->recList->add(rec);
+      recDir->recList->next();
+    }
+
+    Log::getInstance()->log("VDR", Log::DEBUG, "Have added a recording to list. %lu %s", rec->start, rec->getProgName());
+  }
+
+  free(p);
+
+  return recDir;
+}
+
+int VDR::deleteRecording(char* fileName)
+{
+  unsigned long totalLength = 8 + strlen(fileName) + 1;
+  UCHAR buffer[totalLength];
+
+  *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
+  *(unsigned long*)&buffer[4] = htonl(VDR_DELETERECORDING);
+  strcpy((char*)&buffer[8], fileName);
+
+  pthread_mutex_lock(&mutex);
+  unsigned int a = tcp->sendPacket(buffer, totalLength);
+  if (a != totalLength)
+  {
+    pthread_mutex_unlock(&mutex);
+    return 0;
+  }
+
+  int toReturn = getSimpleReply();
+  pthread_mutex_unlock(&mutex);
+  return toReturn;
+}
+
+char* VDR::getRecordingSummary(char* fileName)
+{
+  unsigned long totalLength = 8 + strlen(fileName) + 1;
+  UCHAR buffer[totalLength];
+
+  *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
+  *(unsigned long*)&buffer[4] = htonl(VDR_GETSUMMARY);
+  strcpy((char*)&buffer[8], fileName);
+
+  pthread_mutex_lock(&mutex);
+  unsigned int a = tcp->sendPacket(buffer, totalLength);
+  if (a != totalLength)
+  {
+    pthread_mutex_unlock(&mutex);
+    return NULL;
+  }
+
+  char* toReturn = getStringReply();
+  pthread_mutex_unlock(&mutex);
+  return toReturn;
+}
+
+List* VDR::getChannelsList(ULONG type)
+{
+  UCHAR buffer[8];
+
+  *(unsigned long*)&buffer[0] = htonl(4);
+  *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELLIST);
+
+  pthread_mutex_lock(&mutex);
+  int a = tcp->sendPacket(buffer, 8);
+  if (a != 8)
+  {
+    pthread_mutex_unlock(&mutex);
+    return NULL;
+  }
+
+  // reply
+
+  unsigned char* p = (unsigned char*)tcp->receivePacket();
+  pthread_mutex_unlock(&mutex);
+  if (!p) return NULL;
+
+  List* chanList = new List();
+
+  int dataLength = tcp->getDataLength();
+
+  Log::getInstance()->log("VDR", Log::DEBUG, "Data length %u", dataLength);
+
+  int count = 0;
+
+  int tLength;
+
+  while (count < dataLength)
+  {
+    Channel* chan = new Channel();
+    chan->number = ntohl(*(unsigned long*)&p[count]);
+    count += 4;
+    chan->type = ntohl(*(unsigned long*)&p[count]);
+    count += 4;
+
+    tLength = strlen((char*)&p[count]);
+    chan->name = new char[tLength + 1];
+    strcpy(chan->name, (char*)&p[count]);
+    count += tLength + 1;
+
+    if (chan->type == type)
+    {
+      chanList->add(chan);
+      chanList->next();
+      Log::getInstance()->log("VDR", Log::DEBUG, "Have added a channel to list. %lu %lu %s", chan->number, chan->type, chan->name);
+    }
+    else
+    {
+      delete chan;
+    }
+  }
+
+  free(p);
+
+  return chanList;
+}
+
+int VDR::streamChannel(ULONG number)
+{
+  UCHAR buffer[12];
+
+  *(unsigned long*)&buffer[0] = htonl(8);
+  *(unsigned long*)&buffer[4] = htonl(VDR_STREAMCHANNEL);
+  *(unsigned long*)&buffer[8] = htonl(number);
+
+  pthread_mutex_lock(&mutex);
+  int a = tcp->sendPacket(buffer, 12);
+
+  if (a != 12)
+  {
+    pthread_mutex_unlock(&mutex);
+    return 0;
+  }
+
+  int toReturn = getSimpleReply();
+  pthread_mutex_unlock(&mutex);
+  return toReturn;
+}
+
+int VDR::stopStreaming()
+{
+  UCHAR buffer[8];
+
+  *(unsigned long*)&buffer[0] = htonl(4);
+  *(unsigned long*)&buffer[4] = htonl(VDR_STOPSTREAMING);
+
+  pthread_mutex_lock(&mutex);
+  int a = tcp->sendPacket(buffer, 8);
+
+  if (a != 8)
+  {
+    pthread_mutex_unlock(&mutex);
+    return 0;
+  }
+
+  int toReturn = getSimpleReply();
+  pthread_mutex_unlock(&mutex);
+  return toReturn;
+}
+
+int VDR::getBlock(UCHAR* buf, ULLONG position, int amount)
+{
+  UCHAR buffer[20];
+
+  *(unsigned long*)&buffer[0] = htonl(16);
+  *(unsigned long*)&buffer[4] = htonl(VDR_GETBLOCK);
+  *(ULLONG*)&buffer[8]        = htonll(position);
+  *(unsigned long*)&buffer[16] = htonl(amount);
+
+  pthread_mutex_lock(&mutex);
+  int a = tcp->sendPacket(buffer, 20);
+  if (a != 20)
+  {
+    pthread_mutex_unlock(&mutex);
+    return 0;
+  }
+
+  unsigned char* p = (unsigned char*)tcp->receivePacket();
+  pthread_mutex_unlock(&mutex);
+  if (!p) return 0;
+  int dataLength = tcp->getDataLength();
+
+  memcpy(buf, p, dataLength);
+  free(p);
+  return dataLength;
+}
+
+ULLONG VDR::streamRecording(Recording* rec)
+{
+  unsigned long totalLength = 8 + strlen(rec->fileName) + 1;
+  UCHAR buffer[totalLength];
+
+  *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
+  *(unsigned long*)&buffer[4] = htonl(VDR_STREAMRECORDING);
+  strcpy((char*)&buffer[8], rec->fileName);
+
+  pthread_mutex_lock(&mutex);
+  unsigned int a = tcp->sendPacket(buffer, totalLength);
+  if (a != totalLength)
+  {
+    pthread_mutex_unlock(&mutex);
+    return 0;
+  }
+
+  unsigned char* p = (unsigned char*)tcp->receivePacket();
+  pthread_mutex_unlock(&mutex);
+  if (!p) return 0;
+
+  if (tcp->getDataLength() != 8)
+  {
+    free(p);
+    return 0;
+  }
+
+  ULLONG recordingLength = ntohll(*(ULLONG*)p);
+
+  Log::getInstance()->log("VDR", Log::DEBUG, "VDR said length is: %llu", recordingLength);
+  free(p);
+
+  return recordingLength;
+}
+
+int VDR::getChannelSchedule(ULONG number)
+{
+  UCHAR buffer[12];
+
+  *(unsigned long*)&buffer[0] = htonl(8);
+  *(unsigned long*)&buffer[4] = htonl(VDR_GETCHANNELSCHEDULE);
+  *(unsigned long*)&buffer[8] = htonl(number);
+
+  pthread_mutex_lock(&mutex);
+  int a = tcp->sendPacket(buffer, 12);
+
+  if (a != 12)
+  {
+    pthread_mutex_unlock(&mutex);
+    return -1;
+  }
+
+  unsigned char* p = (unsigned char*)tcp->receivePacket();
+  pthread_mutex_unlock(&mutex);
+  if (!p) return -1;
+
+  int dataLength = tcp->getDataLength();
+
+  if (dataLength != 4)
+  {
+    free(p);
+    return -1;
+  }
+
+  ULONG data = ntohl(*(ULONG*)p);
+  free(p);
+
+  Log::getInstance()->log("VDR", Log::DEBUG, "Success got to end of getChannelSchedule %lu", data);
+
+  return data;
+}
+
+ULLONG VDR::getResumePoint(char* fileName)
+{
+  char* resumeString = configLoad("ResumeData", fileName);
+  if (!resumeString) return 0;
+
+  ULLONG toReturn = strtoull(resumeString, NULL, 10);
+  delete[] resumeString;
+  return toReturn;
+}
+
+int VDR::configSave(char* section, char* key, char* value)
+{
+  ULONG totalLength = 8 + strlen(section) + strlen(key) + strlen(value) + 3; // 8 for headers, 3 for nulls
+  UCHAR buffer[totalLength];
+
+  *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
+  *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGSAVE);
+
+  int position = 8;
+  strcpy((char*)&buffer[position], section);
+  position += strlen(section) + 1;
+  strcpy((char*)&buffer[position], key);
+  position += strlen(key) + 1;
+  strcpy((char*)&buffer[position], value);
+
+  pthread_mutex_lock(&mutex);
+  unsigned int a = tcp->sendPacket(buffer, totalLength);
+  if (a != totalLength)
+  {
+    pthread_mutex_unlock(&mutex);
+    return 0;
+  }
+
+  int toReturn = getSimpleReply();
+  pthread_mutex_unlock(&mutex);
+  return toReturn;
+}
+
+char* VDR::configLoad(char* section, char* key)
+{
+  ULONG totalLength = 8 + strlen(section) + strlen(key) + 2; // 8 for headers, 2 for nulls
+  UCHAR buffer[totalLength];
+
+  *(unsigned long*)&buffer[0] = htonl(totalLength - 4);
+  *(unsigned long*)&buffer[4] = htonl(VDR_CONFIGLOAD);
+
+  int position = 8;
+  strcpy((char*)&buffer[position], section);
+  position += strlen(section) + 1;
+  strcpy((char*)&buffer[position], key);
+
+  pthread_mutex_lock(&mutex);
+  unsigned int a = tcp->sendPacket(buffer, totalLength);
+  if (a != totalLength)
+  {
+    pthread_mutex_unlock(&mutex);
+    return NULL;
+  }
+
+  char* toReturn = getStringReply();
+  pthread_mutex_unlock(&mutex);
+  return toReturn;
+}
diff --git a/vdr.h b/vdr.h
new file mode 100644 (file)
index 0000000..9144a15
--- /dev/null
+++ b/vdr.h
@@ -0,0 +1,107 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VDR_H
+#define VDR_H
+
+#include <stdio.h>
+#include <time.h>
+#include <pthread.h>
+#include <vector>
+
+#include "defines.h"
+#include "log.h"
+#include "dsock.h"
+#include "tcp.h"
+#include "list.h"
+#include "directory.h"
+#include "recording.h"
+#include "channel.h"
+
+ // FIXME do some tcp connection error checking and kill it!
+
+class VDR
+{
+  public:
+    VDR();
+    ~VDR();
+    static VDR* getInstance();
+
+    int init(int port);
+    int shutdown();
+
+    void findServers(std::vector<char*>& serverIPs);
+    void cancelFindingServer();
+    void setServerIP(char*);
+    int connect();
+    void disconnect();
+    ULLONG getResumePoint(char* fileName);  // uses configLoad
+
+    // protocol functions
+
+    int doLogin();
+
+    Directory* getRecordingsList();
+    char*      getRecordingSummary(char* fileName);
+    int        deleteRecording(char* fileName);
+    ULLONG     streamRecording(Recording* rec);
+
+    List*      getChannelsList(ULONG type);
+    int        streamChannel(ULONG number);
+
+    int        getBlock(UCHAR* buf, ULLONG position, int maxAmount);
+    int        stopStreaming();
+    int        getChannelSchedule(ULONG number);
+    int        configSave(char* section, char* key, char* value);
+    char*      configLoad(char* section, char* key);
+
+    // end
+
+    const static ULONG VIDEO = 1;
+    const static ULONG RADIO = 2;
+
+  private:
+    static VDR* instance;
+    Log* logger;
+    int initted;
+    int findingServer;
+    TCP* tcp;
+    int port;
+    char serverIP[16];
+    pthread_mutex_t mutex;
+
+    const static ULONG VDR_LOGIN               = 1;
+    const static ULONG VDR_GETRECORDINGLIST    = 2;
+    const static ULONG VDR_DELETERECORDING     = 3;
+    const static ULONG VDR_GETSUMMARY          = 4;
+    const static ULONG VDR_GETCHANNELLIST      = 5;
+    const static ULONG VDR_STREAMCHANNEL       = 6;
+    const static ULONG VDR_GETBLOCK            = 7;
+    const static ULONG VDR_STOPSTREAMING       = 8;
+    const static ULONG VDR_STREAMRECORDING     = 9;
+    const static ULONG VDR_GETCHANNELSCHEDULE  = 10;
+    const static ULONG VDR_CONFIGSAVE          = 11;
+    const static ULONG VDR_CONFIGLOAD          = 12;
+
+    long getSimpleReply();
+    char* getStringReply();
+};
+
+#endif
diff --git a/vfeed.cc b/vfeed.cc
new file mode 100644 (file)
index 0000000..7dc9a1b
--- /dev/null
+++ b/vfeed.cc
@@ -0,0 +1,72 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vfeed.h"
+
+VFeed::VFeed(Callback* tcb)
+: cb(*tcb)
+{
+  delayTime.tv_sec = 0;
+  delayTime.tv_nsec = 100000000;
+}
+
+int VFeed::init(int tfd)
+{
+  fd = tfd;
+  return 1;
+}
+
+int VFeed::shutdown()
+{
+  // FIXME
+  return 1;
+}
+
+int VFeed::start()
+{
+  return threadStart();
+}
+
+void VFeed::stop()
+{
+  threadCancel();
+}
+
+void VFeed::threadMethod()
+{
+  Log::getInstance()->log("VFeed", Log::DEBUG, "Started");
+
+  int vlen;
+
+  while(1)
+  {
+    vlen = Demuxer::getInstance()->writeVideo(fd); // FIXME
+    if (vlen)
+    {
+      Log::getInstance()->log("VFeed", Log::DEBUG, "Written %i", vlen);
+      cb.call();
+    }
+    else
+    {
+      nanosleep(&delayTime, NULL);
+    }
+  }
+}
+
diff --git a/vfeed.h b/vfeed.h
new file mode 100644 (file)
index 0000000..2e7019b
--- /dev/null
+++ b/vfeed.h
@@ -0,0 +1,51 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VFEED_H
+#define VFEED_H
+
+#include <stdio.h>
+#include <time.h>
+
+#include "log.h"
+#include "thread.h"
+#include "demuxer.h"
+#include "callback.h"
+
+class VFeed : public Thread
+{
+  public:
+    VFeed(Callback* tcb);
+
+    int init(int fd);
+    int shutdown();
+
+    int start();
+    void stop();
+
+  private:
+    void threadMethod();
+    int fd;
+    Callback& cb;
+    struct timespec delayTime;
+
+};
+
+#endif
diff --git a/video.cc b/video.cc
new file mode 100644 (file)
index 0000000..608f7b3
--- /dev/null
+++ b/video.cc
@@ -0,0 +1,304 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "video.h"
+
+Video* Video::instance = NULL;
+
+Video::Video()
+{
+  if (instance) return;
+  instance = this;
+  initted = 0;
+
+  fdVideo = 0;
+
+  format = 0;
+  connection = 0;
+  aspectRatio = 0;
+  mode = 0;
+}
+
+Video::~Video()
+{
+  instance = NULL;
+}
+
+Video* Video::getInstance()
+{
+  return instance;
+}
+
+int Video::init(UCHAR format, UCHAR connection, UCHAR aspectRatio, UCHAR mode)
+{
+  if (initted) return 0;
+  initted = 1;
+
+//  if ((fdVideo = open("/dev/vdec_dev", O_RDWR | O_NONBLOCK)) < 0) return 0;
+  if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
+
+  this->format = format;
+  this->connection = connection;
+  this->aspectRatio = aspectRatio;
+  this->mode = mode;
+
+  if (!initAllParams())
+  {
+    shutdown();
+    return 0;
+  }
+
+  attachFrameBuffer();
+  stop();
+
+  return 1;
+}
+
+int Video::initAllParams()
+{
+  return (setFormat(format) && setConnection(connection) &&
+          setAspectRatio(aspectRatio) && setMode(mode) && setSource());
+}
+
+int Video::shutdown()
+{
+  if (!initted) return 0;
+  initted = 0;
+  close(fdVideo);
+  return 1;
+}
+
+int Video::write(char *buf, int len)
+{
+  return 1;//write(fdVideo, buf, len);
+}
+
+int Video::setFormat(UCHAR format)
+{
+  if (!initted) return 0;
+  if ((format != PAL) && (format != NTSC)) return 0;
+
+  if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
+  this->format = format;
+  return 1;
+}
+
+int Video::setConnection(UCHAR connection)
+{
+  if (!initted) return 0;
+  if ((connection != SCART) && (connection != COMPOSITE) && (connection != SVIDEO)) return 0;
+
+  if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
+  this->connection = connection;
+  return 1;
+}
+
+int Video::setAspectRatio(UCHAR aspectRatio)
+{
+  if (!initted) return 0;
+  if ((aspectRatio != ASPECT4X3) && (aspectRatio != ASPECT16X9)) return 0;
+
+  if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
+  this->aspectRatio = aspectRatio;
+  return 1;
+}
+
+int Video::setMode(UCHAR mode)
+{
+  if (!initted) return 0;
+
+  if ((mode != NORMAL) && (mode != LETTERBOX) && (mode != UNKNOWN2) && (mode != QUARTER) && (mode != EIGHTH)
+      && (mode != ZOOM) && (mode != UNKNOWN6)) return 0;
+
+//  mode = LETTERBOX;
+
+  if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
+  this->mode = mode;
+  return 1;
+}
+
+int Video::test()
+{
+  return 0;
+
+//  ULLONG stc = 0;
+//  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
+/*
+ // reset();
+  return 1;
+*/
+}
+
+int Video::test2()
+{
+  return 0;
+}
+
+
+
+int Video::signalOff()
+{
+  if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
+  return 1;
+}
+
+int Video::signalOn()
+{
+  if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
+  return 1;
+}
+
+int Video::setSource()
+{
+  if (!initted) return 0;
+
+  // What does this do...
+  if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
+  return 1;
+}
+
+int Video::setPosition(int x, int y)
+{
+  if (!initted) return 0;
+
+  vid_pos_regs_t pos_d;
+  pos_d.x = x;
+  pos_d.y = y;
+
+/*
+typedef struct {
+  int w;
+  int h;
+  int scale;
+  int x1;
+  int y;
+  int x;
+  int y2;
+  int x3;
+  int y3;
+  int x4;
+  int y4;
+} vid_pos_regs_t;
+*/
+
+/*
+  pos_d.w = 100;
+  pos_d.h = 30;
+  pos_d.scale = 2;
+  pos_d.x1 = 0;
+  pos_d.y = 100;            // Top left X
+  pos_d.x = 50;            // Top left Y
+  pos_d.y2 = 30;
+  pos_d.x3 = 60;
+  pos_d.y3 = 90;
+  pos_d.x4 = 120;
+  pos_d.y4 = 150;
+*/
+
+  if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
+  return 1;
+}
+
+int Video::sync()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
+  return 1;
+}
+
+int Video::play()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
+  return 1;
+}
+
+int Video::stop()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
+  return 1;
+}
+
+int Video::reset()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
+  return 1;
+}
+
+int Video::pause()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
+  return 1;
+}
+
+int Video::unPause()
+{
+  if (!initted) return 0;
+  if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
+  return 1;
+}
+
+int Video::fastForward()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdVideo, AV_SET_VID_FFWD, 1) != 0) return 0;
+  return 1;
+}
+
+int Video::unFastForward()
+{
+  if (!initted) return 0;
+
+//  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
+
+  if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
+  return 1;
+}
+
+int Video::attachFrameBuffer()
+{
+  if (!initted) return 0;
+
+  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
+  return 1;
+}
+
+int Video::blank(void)
+{
+  if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
+  if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
+  return 1;
+}
+
+int Video::getFD()
+{
+  if (!initted) return 0;
+
+  return fdVideo;
+}
diff --git a/video.h b/video.h
new file mode 100644 (file)
index 0000000..ba6ff77
--- /dev/null
+++ b/video.h
@@ -0,0 +1,111 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+// Thanks to Jon Gettler and BtB of the MVPMC project for all the hardware information
+
+
+#ifndef VIDEO_H
+#define VIDEO_H
+
+// FIXME - check why so many things include unistd
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include "defines.h"
+#include "stb.h"
+
+class Video
+{
+  public:
+    Video();
+    ~Video();
+    static Video* getInstance();
+
+    int init(UCHAR format, UCHAR connection, UCHAR aspectRatio, UCHAR mode);
+    int shutdown();
+
+    // Video formats - AV_SET_VID_DISP_FMT
+    const static UCHAR NTSC = 0;
+    const static UCHAR PAL = 1;
+
+    // Video connections - AV_SET_VID_OUTPUT
+    const static UCHAR SCART = 0;
+    const static UCHAR COMPOSITE = 1;
+    const static UCHAR SVIDEO = 2;
+
+    // Video aspect ratios - AV_SET_VID_RATIO
+    const static UCHAR ASPECT4X3 = 0;
+    const static UCHAR ASPECT16X9 = 1;
+
+    // Video modes - AV_SET_VID_MODE
+    const static UCHAR NORMAL = 0; // If aspect==4:3, 4:3 unknown / 16:9 chop sides
+                                   // If aspect==16:9, 4:3 unknown / 16:9 stretch middle over all screen
+    const static UCHAR LETTERBOX = 1; // If aspect==4:3, 4:3 unknown / 16:9 letterbox at top of screen (!!)
+                                      // If aspect==16:9, 4:3 unknown / 16:9 proper 16:9 mode
+    const static UCHAR UNKNOWN2 = 2;
+    const static UCHAR QUARTER = 3;
+    const static UCHAR EIGHTH = 4;
+    const static UCHAR ZOOM = 5;
+    const static UCHAR UNKNOWN6 = 6;
+
+    int setFormat(UCHAR format);
+    int setConnection(UCHAR connection);
+    int setAspectRatio(UCHAR aspectRatio);
+    int setMode(UCHAR mode);
+    int test();
+    int test2();
+    int setSource();
+    int setPosition(int x, int y);
+    int sync();
+    int play();
+    int stop();
+    int pause();
+    int unPause();
+    int fastForward();
+    int unFastForward();
+    int reset();
+    int blank();
+    int signalOn();
+    int signalOff();
+
+    int attachFrameBuffer(); // What does this do?
+
+    int write(char *buf, int len);
+
+    int getFD();
+
+  private:
+    static Video* instance;
+    int initted;
+
+    int initAllParams();
+
+    int fdVideo;
+
+    UCHAR format;
+    UCHAR connection;
+    UCHAR aspectRatio;
+    UCHAR mode;
+};
+
+#endif
diff --git a/view.cc b/view.cc
new file mode 100644 (file)
index 0000000..e39115f
--- /dev/null
+++ b/view.cc
@@ -0,0 +1,123 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "view.h"
+
+char View::numViews = 0;
+
+View::View()
+{
+  height = 0;
+  width = 0;
+  screenX = 0;
+  screenY = 0;
+
+  delSec = 0;
+  delNSec = 0;
+  seconds = 0;
+
+  backgroundR = 0;
+  backgroundG = 0;
+  backgroundB = 0;
+  backgroundA = 0;
+
+  titleBarR = 0;
+  titleBarG = 0;
+  titleBarB = 0;
+  titleBarA = 0;
+
+  titleBarOn = 0;
+  borderOn = 0;
+
+  titleText = NULL;
+
+  numViews++;
+  Log::getInstance()->log("View", Log::DEBUG, "Construct %p, now %u", this, numViews);
+}
+
+View::~View()
+{
+  if (titleText) delete[] titleText;
+
+  numViews--;
+  Log::getInstance()->log("View", Log::DEBUG, "Destruct, now %u", numViews);
+}
+
+void View::setTitleText(char* takeText)
+{
+  int length = strlen(takeText);
+  titleText = new char[length + 1];
+  strcpy(titleText, takeText);
+}
+
+void View::draw()
+{
+
+  if (borderOn)
+  {
+    rectangle(0, 0, width, height, titleBarR, titleBarG, titleBarB, titleBarA);
+    rectangle(5, 5, width-10, height-10, backgroundR, backgroundG, backgroundB, backgroundA);
+  }
+  else
+  {
+    fillColour(backgroundR, backgroundG, backgroundB, backgroundA);
+  }
+
+  if (titleBarOn)
+  {
+    rectangle(0, 0, width, 30, titleBarR, titleBarG, titleBarB, titleBarA);
+    if (titleText) drawText(titleText, 5, 5, 255, 255, 255);
+  }
+}
+
+int View::handleCommand(int command)
+{
+  return 0;
+}
+
+void View::processMessage(Message* m)
+{
+}
+
+void View::setBackgroundColour(UCHAR r, UCHAR g, UCHAR b, UCHAR a)
+{
+  backgroundR = r;
+  backgroundG = g;
+  backgroundB = b;
+  backgroundA = a;
+}
+
+void View::setTitleBarColour(UCHAR r, UCHAR g, UCHAR b, UCHAR a)
+{
+  titleBarR = r;
+  titleBarG = g;
+  titleBarB = b;
+  titleBarA = a;
+}
+
+void View::setTitleBarOn(UCHAR on)
+{
+  titleBarOn = on;
+}
+
+void View::setBorderOn(UCHAR on)
+{
+  borderOn = on;
+}
diff --git a/view.h b/view.h
new file mode 100644 (file)
index 0000000..d70d566
--- /dev/null
+++ b/view.h
@@ -0,0 +1,74 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VIEW_H
+#define VIEW_H
+
+#include <stdio.h>
+
+#include "log.h"
+#include "box.h"
+#include "defines.h"
+#include "message.h"
+
+class View : public Box
+{
+  public:
+    View();
+    virtual ~View();
+
+    virtual void draw();
+    virtual int handleCommand(int command);
+
+    void setBorderOn(UCHAR on);
+    void setTitleBarOn(UCHAR on);
+    void setTitleText(char* title);
+    void setBackgroundColour(UCHAR r, UCHAR g, UCHAR b, UCHAR a);
+    void setTitleBarColour(UCHAR r, UCHAR g, UCHAR b, UCHAR a);
+
+    // For use by ViewMan
+    long delSec;
+    long delNSec;
+    int seconds;
+    //
+
+    virtual void processMessage(Message* m);
+
+  private:
+    static char numViews;
+
+    UCHAR backgroundR;
+    UCHAR backgroundG;
+    UCHAR backgroundB;
+    UCHAR backgroundA;
+
+    UCHAR titleBarOn;
+    UCHAR borderOn;
+
+    char* titleText;
+
+  protected:
+    UCHAR titleBarR;
+    UCHAR titleBarG;
+    UCHAR titleBarB;
+    UCHAR titleBarA;
+};
+
+#endif
diff --git a/viewman.cc b/viewman.cc
new file mode 100644 (file)
index 0000000..4ab9ad4
--- /dev/null
@@ -0,0 +1,540 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "viewman.h"
+
+ViewMan* ViewMan::instance = NULL;
+
+ViewMan::ViewMan()
+{
+  if (instance) return;
+  instance = this;
+  initted = 0;
+  topView = 0;
+  resetThreadFlag = 0;
+  autoDeleteThreadRun = 0;
+  callFromThread = 0;
+}
+
+ViewMan::~ViewMan()
+{
+  instance = NULL;
+}
+
+ViewMan* ViewMan::getInstance()
+{
+  return instance;
+}
+
+int ViewMan::init()
+{
+  if (initted) return 0;
+  pthread_mutex_init(&viewManLock, NULL);
+  pthread_cond_init(&autoDeleteThreadSignal, NULL);
+  if (!startAutoDeleteThread()) return 0;
+  initted = 1;
+  return 1;
+}
+
+int ViewMan::shutdown()
+{
+  if (!initted) return 0;
+
+  removeAll();
+
+  // get the lock here to ensure that the thread is waiting on the cond
+  pthread_mutex_lock(&viewManLock);
+  autoDeleteThreadRun = 0;
+  pthread_cond_signal(&autoDeleteThreadSignal);
+  pthread_mutex_unlock(&viewManLock);
+  pthread_join(autoDeleteThread, NULL);
+  initted = 0;
+  return 1;
+}
+
+int ViewMan::add(View* v)
+{
+  if (!initted) return 0;
+  if (topView == 10) return 0;
+
+  pthread_mutex_lock(&viewManLock);
+
+  topView++;
+  views[topView] = v;
+
+  resetThread();
+  pthread_mutex_unlock(&viewManLock);
+
+  return 1;
+}
+
+int ViewMan::addNoLock(View* v)
+{
+  if (!initted) return 0;
+  if (topView == 10) return 0;
+
+  topView++;
+  views[topView] = v;
+
+  resetThread();
+
+  return 1;
+}
+
+
+// ---------------------------------------------------- REMOVE CODE
+
+int ViewMan::removeView(View* toDelete, int noLock, int noShow)
+{
+  if (!initted) return 0;
+  if (topView == 0) return 0;
+
+  if (!noLock) pthread_mutex_lock(&viewManLock);
+
+  Log::getInstance()->log("ViewMan", Log::DEBUG, "entering remove, %u topview", topView);
+
+  int i;
+  int wasTopView = 0;
+  int slotTakenFrom = 0;
+
+  if (toDelete == NULL)
+  {
+    toDelete = views[topView];
+    i = topView;
+    wasTopView = 1;
+  }
+  else
+  {
+    // to be deleted view is more likely to be at the top
+
+
+    for (i = topView; i > 0; i--)
+    {
+      if (views[i] == toDelete)
+      {
+        if (i == topView) wasTopView = 1;
+        break;
+      }
+    }
+
+    if (i == 0)
+    {
+      // not a View we have!
+      pthread_mutex_unlock(&viewManLock);
+      return 0;
+    }
+  }
+
+  // Save the position we are deleting the view from
+  slotTakenFrom = i;
+
+  // Shift the views on top down one
+  for(; i < topView; i++)
+  {
+    views[i] = views[i + 1];
+  }
+  topView--;
+
+  // Done. Now on to drawing.
+
+  View* newTopBox = views[topView]; // just to make second optimisation easier
+
+  // First optimisation. If there are no views left, don't do anything!
+  if (topView == 0)
+  {
+    Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using optimisation 1");
+  }
+
+  // second optimisation. if view being deleted is entirely within the view underneath it,
+  // and was the top most box,
+  // only need to redraw the one underneath
+  else if (   wasTopView
+           && (toDelete->getScreenX() >= newTopBox->getScreenX())
+           && (toDelete->getScreenY() >= newTopBox->getScreenY())
+           && ((toDelete->getScreenX() + toDelete->getWidth()) <= (newTopBox->getScreenX() + newTopBox->getWidth()))
+           && ((toDelete->getScreenY() + toDelete->getHeight()) <= (newTopBox->getScreenY() + newTopBox->getHeight()))
+          )
+  {
+    newTopBox->draw();
+    newTopBox->show();
+    Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using optimisation 2");
+  }
+
+  // third optimisation. if the box being deleted is totally within one above it, don't do anything
+  else if ((slotTakenFrom <= topView) && isTotallyCovered(toDelete, slotTakenFrom))
+  {
+    Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using optimisation 3");
+  }
+
+  // no optimisations left, redo everything.
+  else
+  {
+    redrawAll(noShow);
+    Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using no optimisation");
+  }
+
+  // Delete the view
+  delete toDelete;
+
+  resetThread();
+  if (!noLock) pthread_mutex_unlock(&viewManLock);
+
+  return 1;
+}
+
+int ViewMan::isTotallyCovered(View* toDelete, int slotTakenFrom)
+{
+  int todelx1 = toDelete->getScreenX();
+  int todelx2 = toDelete->getScreenX() + toDelete->getWidth();
+  int todely1 = toDelete->getScreenY();
+  int todely2 = toDelete->getScreenY() + toDelete->getHeight();
+
+  int x1 = 999999;
+  int x2 = 0;
+  int y1 = 999999;
+  int y2 = 0;
+
+  int currentx1;
+  int currentx2;
+  int currenty1;
+  int currenty2;
+
+  for (int i = slotTakenFrom; i <= topView; i++)
+  {
+    currentx1 = views[i]->getScreenX();
+    currentx2 = currentx1 + views[i]->getWidth();
+    currenty1 = views[i]->getScreenY();
+    currenty2 = currenty1 + views[i]->getHeight();
+
+//    printf("Iteration in tc before. i=%i x1=%i x2=%i y1=%i y2=%i cx1=%i cx2=%i cy1=%i cy2=%i\n", i, x1, x2, y1, y2, currentx1, currentx2, currenty1, currenty2);
+
+    if (currentx1 < x1) x1 = currentx1;
+    if (currentx2 > x2) x2 = currentx2;
+    if (currenty1 < y1) y1 = currenty1;
+    if (currenty2 > y2) y2 = currenty2;
+
+//    printf("Iteration in tc after . i=%i x1=%i x2=%i y1=%i y2=%i\n", i, x1, x2, y1, y2);
+  }
+
+  // k, now x1 x2 y1 y2 contain the dimensions of the biggest box over the deleted slot
+
+  if (   (x1 <= todelx1)
+      && (x2 >= todelx2)
+      && (y1 <= todely1)
+      && (y2 >= todely2)
+     )
+  {
+    return 1;
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+void ViewMan::redrawAll(int noShow)
+{
+  for (int i = 1; i <= topView; i++)
+  {
+    views[i]->draw();
+  }
+
+  if (!noShow) Box::showAll();
+}
+
+// ---------------------------------------------------- END OF REMOVE CODE
+
+
+void ViewMan::removeAll()
+{
+  pthread_mutex_lock(&viewManLock);
+
+  // FIXME for don't delete wallpaper cos surface destroy doesn't work
+
+  for (; topView > 1; topView--)
+  {
+    delete views[topView];
+  }
+
+  resetThread();
+  pthread_mutex_unlock(&viewManLock);
+}
+
+int ViewMan::handleCommand(UCHAR command)
+{
+  pthread_mutex_lock(&viewManLock);
+
+  int retVal;
+  int retVal2 = 0;
+  int i;
+
+  // handle command return values
+  // 0 - drop through to next view
+  // 1 - dont drop to next view, but not handled
+  // 2 - handled - stop command here
+  // 4 - handled - delete this view
+
+  for (i=topView; i>0; i--)
+  {
+    retVal = views[i]->handleCommand(command);
+    if (retVal == 1)
+    {
+      // not handled but don't give to any more views
+      pthread_mutex_unlock(&viewManLock);
+      return 0;
+    }
+
+    if (retVal == 2)
+    {
+      // command handled
+      if (views[i]->seconds)
+      {
+        struct timespec currentTime;
+        clock_gettime(CLOCK_REALTIME, &currentTime);
+        views[i]->delSec = currentTime.tv_sec + views[i]->seconds;
+        views[i]->delNSec = currentTime.tv_nsec;
+        resetThread();
+      }
+      pthread_mutex_unlock(&viewManLock);
+      retVal2 = 1;
+      break;
+    }
+    else if (retVal == 4)
+    {
+//      removeNoLock(views[i]);
+//      Box::showAll();
+//      resetThread();
+      removeView(views[i], 1);
+      pthread_mutex_unlock(&viewManLock);
+      retVal2 = 1;
+      break;
+    }
+  }
+
+  Log::getInstance()->log("ViewMan", Log::DEBUG, "out of handlecommand code, now on to messages");
+
+  processMessageQueue();
+
+  pthread_mutex_unlock(&viewManLock);
+  return retVal2;
+}
+
+void ViewMan::processMessage(Message* m)
+{
+  if (m->to != this)
+  {
+    for (int i = topView; i > 0; i--)
+    {
+      if (views[i] == m->to)
+      {
+        Log::getInstance()->log("ViewMan", Log::DEBUG, "sending message to view");
+        Log::getInstance()->log("ViewMan", Log::DEBUG, "%p %p %lu", m->from, m->to, m->message);
+        views[i]->processMessage(m);
+        return;
+      }
+    }
+  }
+
+  Log::getInstance()->log("ViewMan", Log::DEBUG, "it's for meeee!");
+
+  switch(m->message)
+  {
+    case Message::CLOSE_ME:
+    {
+      removeView((View*)m->from, 1, 1);
+      break;
+    }
+    case Message::UPDATE_SCREEN:
+    {
+      Box::showAll();
+      break;
+    }
+    case Message::SWAP_ME_FOR:
+    {
+      View* toReplace = (View*) m->parameter;
+
+      removeView((View*)m->from, 1, 1);
+
+      topView++;
+      views[topView] = toReplace;
+      if (toReplace->seconds)
+      {
+        struct timespec currentTime;
+        clock_gettime(CLOCK_REALTIME, &currentTime);
+        toReplace->delSec = currentTime.tv_sec + toReplace->seconds;
+        toReplace->delNSec = currentTime.tv_nsec;
+      }
+      toReplace->draw();
+      Box::showAll();
+      resetThread();
+      break;
+    }
+  }
+}
+
+int ViewMan::timedDelete(View* v, int seconds, int lock)
+{
+  int success;
+
+  if (lock) pthread_mutex_lock(&viewManLock);
+
+  struct timespec currentTime;
+  clock_gettime(CLOCK_REALTIME, &currentTime);
+
+  if (v)
+  {
+    if (seconds)
+    {
+      v->seconds = seconds;
+      v->delSec = currentTime.tv_sec + seconds;
+      v->delNSec = currentTime.tv_nsec;
+    }
+    else
+    {
+      // for cancelling the delete
+      v->seconds = 0;
+      v->delSec = 0;
+      v->delNSec = 0;
+    }
+    success = 1;
+  }
+  else
+  {
+    success = 0;
+  }
+
+  resetThread();
+  if (lock) pthread_mutex_unlock(&viewManLock);
+
+  return success;
+}
+
+
+// THE THREAD CODE STARTS HERE /////////////////////////////////////////////////////////////
+
+void ViewMan::resetThread()
+{
+  // must be called with mutex already locked
+  resetThreadFlag = 1;
+  pthread_cond_signal(&autoDeleteThreadSignal);
+}
+
+// undeclared function
+void startAutoDeleteThread2(void *arg)
+{
+  ViewMan *v = (ViewMan *)arg;
+  v->startAutoDeleteThread3();
+}
+int ViewMan::startAutoDeleteThread()
+{
+  pthread_mutex_lock(&viewManLock);
+  resetThreadFlag = 1;
+  autoDeleteThreadRun = 1;
+  if (pthread_create(&autoDeleteThread, NULL, (void*(*)(void*))startAutoDeleteThread2, (void *)this) == -1) return 0;
+  return 1;
+}
+
+void ViewMan::startAutoDeleteThread3()
+{
+  struct timespec nextTime;
+  View* nextToDelete = NULL;
+
+  // I don't want signals
+  sigset_t sigset;
+  sigfillset(&sigset);
+  pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+
+  // locked here
+
+  while(1)
+  {
+    if (resetThreadFlag)
+    {
+      resetThreadFlag = 0;
+
+      // Work out the next View to be deleted
+
+      nextTime.tv_sec = 0;
+      nextTime.tv_nsec = 0;
+      nextToDelete = NULL;
+
+      for(int i = 1; i <= topView; i++)
+      {
+        if ((views[i]->delSec > 0) && (views[i]->delNSec > 0))
+        {
+          if ((nextTime.tv_sec == 0) && (nextTime.tv_nsec == 0))
+          {
+            nextTime.tv_sec = views[i]->delSec;
+            nextTime.tv_nsec = views[i]->delNSec;
+            nextToDelete = views[i];
+          }
+          else
+          {
+            if (views[i]->delSec < nextTime.tv_sec)
+            {
+              nextTime.tv_sec = views[i]->delSec;
+              nextTime.tv_nsec = views[i]->delNSec;
+              nextToDelete = views[i];
+            }
+            else if (views[i]->delSec == nextTime.tv_sec)
+            {
+              if (views[i]->delNSec < nextTime.tv_nsec)
+              {
+                nextTime.tv_sec = views[i]->delNSec;
+                nextTime.tv_nsec = views[i]->delNSec;
+                nextToDelete = views[i];
+              }
+            }
+          }
+        }
+        // no case
+      }
+      // end
+    }
+
+    if (nextTime.tv_sec == 0)
+    {
+      pthread_cond_wait(&autoDeleteThreadSignal, &viewManLock);
+    }
+    else
+    {
+      pthread_cond_timedwait(&autoDeleteThreadSignal, &viewManLock, &nextTime);
+    }
+
+    // ok. we have been signalled or the time has run out
+
+    // see if we have been signalled. we only get signalled if we
+    // are to reset the timer or if we are to die completely
+    if (!autoDeleteThreadRun)
+    {
+      pthread_exit(NULL);
+      // exiting thread with mutex locked
+    }
+
+    if (resetThreadFlag) continue;
+
+    // timer ran out
+    Log::getInstance()->log("ViewMan", Log::DEBUG, "About to remove %p", nextToDelete);
+    removeView(nextToDelete, 1);  // enter this method with mutex locked
+
+    resetThreadFlag = 1;
+  }
+}
+
diff --git a/viewman.h b/viewman.h
new file mode 100644 (file)
index 0000000..a742d51
--- /dev/null
+++ b/viewman.h
@@ -0,0 +1,82 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VIEWMAN_H
+#define VIEWMAN_H
+
+#include <stdio.h>
+#include <time.h>
+#include <signal.h>
+#include <pthread.h>
+
+#include "defines.h"
+#include "view.h"
+#include "message.h"
+#include "messagequeue.h"
+
+class ViewMan : public MessageQueue
+{
+  public:
+    ViewMan();
+    ~ViewMan();
+    static ViewMan* getInstance();
+
+    int init();
+    int shutdown();
+
+    // All these reset the thread
+    int add(View* v);
+    int addNoLock(View* v);
+    int removeView(View* toRemove = NULL, int noLock = 0, int noShow = 0);
+    void removeAll();
+    void redrawAll(int noShow = 0);
+
+    int handleCommand(UCHAR command);
+    int timedDelete(View* v, int seconds, int lock);
+    //
+
+    // not for external use
+    void startAutoDeleteThread3();
+
+  private:
+    int isTotallyCovered(View* toDelete, int slotTakenFrom);
+
+    static ViewMan* instance;
+    int initted;
+
+    View* views[11];
+    UCHAR topView;
+
+    // Threading stuff
+
+    int startAutoDeleteThread();
+    pthread_mutex_t viewManLock;
+    pthread_t autoDeleteThread;
+    pthread_cond_t autoDeleteThreadSignal;
+    int resetThreadFlag;
+    int autoDeleteThreadRun;
+    int callFromThread;
+    void resetThread();
+
+    void processMessage(Message* m);
+
+};
+
+#endif
diff --git a/vinfo.cc b/vinfo.cc
new file mode 100644 (file)
index 0000000..eb8a057
--- /dev/null
+++ b/vinfo.cc
@@ -0,0 +1,69 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vinfo.h"
+
+VInfo::VInfo()
+{
+  mainText = NULL;
+  exitable = 0;
+
+  setBackgroundColour(0, 0, 100, 255);
+  setTitleBarOn(1);
+  setTitleBarColour(0, 0, 200, 255);
+}
+
+VInfo::~VInfo()
+{
+  if (mainText) delete[] mainText;
+}
+
+void VInfo::setExitable()
+{
+  exitable = 1;
+}
+
+void VInfo::setMainText(char* takeText)
+{
+  int length = strlen(takeText);
+  mainText = new char[length + 1];
+  strcpy(mainText, takeText);
+}
+
+void VInfo::draw()
+{
+  View::draw();
+
+  if (mainText) drawPara(mainText, 10, 45, 255, 255, 255);
+}
+
+int VInfo::handleCommand(int command)
+{
+  switch(command)
+  {
+    case Remote::OK:
+    case Remote::BACK:
+    {
+      if (exitable) return 4;
+    }
+  }
+
+  return 1;
+}
diff --git a/vinfo.h b/vinfo.h
new file mode 100644 (file)
index 0000000..4c9ae37
--- /dev/null
+++ b/vinfo.h
@@ -0,0 +1,48 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VINFO_H
+#define VINFO_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "defines.h"
+#include "view.h"
+#include "remote.h"
+
+class VInfo : public View
+{
+  public:
+    VInfo();
+    ~VInfo();
+
+    void setMainText(char* title);
+    void setExitable();
+
+    int handleCommand(int command);
+    void draw();
+
+  private:
+    char* mainText;
+    UCHAR exitable;
+};
+
+#endif
diff --git a/vlivebanner.cc b/vlivebanner.cc
new file mode 100644 (file)
index 0000000..155b34a
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vlivebanner.h"
+
+VLiveBanner::VLiveBanner()
+{
+  setScreenPos(130, 370);
+  setDimensions(120, 500);
+
+  setBackgroundColour(0, 0, 100, 255);
+  setTitleBarOn(1);
+  setTitleText("The channel name");
+  setTitleBarColour(0, 0, 200, 255);
+
+  sl.setScreenPos(screenX, screenY + 30);
+  sl.setDimensions(height - 60, width);
+}
+
+VLiveBanner::~VLiveBanner()
+{
+}
+
+void VLiveBanner::draw()
+{
+  int success = VDR::getInstance()->getChannelSchedule(1);
+
+  if (!success)
+  {
+    sl.addOption("No channel data available", 1);
+  }
+  else
+  {
+    sl.addOption("This Programme", 1);
+    sl.addOption("The Next Programme", 0);
+    sl.addOption("The Programme after that", 0);
+  }
+
+  View::draw();
+  sl.draw();
+  rectangle(0, height - 30, width, 30, titleBarR, titleBarG, titleBarB, titleBarA);
+}
+
+int VLiveBanner::handleCommand(int command)
+{
+  switch (command)
+  {
+    case Remote::OK:
+    case Remote::BACK:
+    {
+      return 4;
+    }
+    case Remote::UP:
+    {
+      sl.up();
+      sl.draw();
+
+      show();
+      return 2;
+    }
+    case Remote::DOWN:
+    {
+      sl.down();
+      sl.draw();
+
+      show();
+      return 2;
+    }
+  }
+
+  return 1;
+}
diff --git a/vlivebanner.h b/vlivebanner.h
new file mode 100644 (file)
index 0000000..03267d5
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VLIVEBANNER_H
+#define VLIVEBANNER_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "view.h"
+#include "remote.h"
+#include "vdr.h"
+#include "wselectlist.h"
+
+class VLiveBanner : public View
+{
+  public:
+    VLiveBanner();
+    ~VLiveBanner();
+
+    int handleCommand(int command);
+    void draw();
+
+  private:
+    WSelectList sl;
+
+};
+
+#endif
diff --git a/vmute.cc b/vmute.cc
new file mode 100644 (file)
index 0000000..00d6e24
--- /dev/null
+++ b/vmute.cc
@@ -0,0 +1,62 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vmute.h"
+
+VMute::VMute()
+{
+  isMuted = Audio::getInstance()->toggleUserMute();
+
+  setDimensions(40, 40);
+  setScreenPos(600, 500);
+
+  setBackgroundColour(0, 0, 100, 255);
+}
+
+void VMute::draw()
+{
+  View::draw();
+
+  WSymbol* w = new WSymbol;
+  if (isMuted) w->nextSymbol = WSymbol::MUTE;
+  else w->nextSymbol = WSymbol::UNMUTE;
+  w->setScreenPos(screenX + 5, screenY + 5);
+  w->draw();
+
+  delete w;
+}
+
+int VMute::handleCommand(int command)
+{
+  switch(command)
+  {
+    case Remote::MUTE:
+    {
+      isMuted = Audio::getInstance()->toggleUserMute();
+      draw();
+      show();
+      // handled
+      return 2;
+    }
+  }
+
+  // allow command to drop through to other views
+  return 0;
+}
diff --git a/vmute.h b/vmute.h
new file mode 100644 (file)
index 0000000..b3d1f0c
--- /dev/null
+++ b/vmute.h
@@ -0,0 +1,43 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VMUTE_H
+#define VMUTE_H
+
+#include <stdio.h>
+
+#include "view.h"
+#include "remote.h"
+#include "audio.h"
+#include "wsymbol.h"
+
+class VMute : public View
+{
+  public:
+    VMute();
+    void draw();
+    int handleCommand(int command);
+
+  private:
+    int isMuted;
+};
+
+#endif
+
diff --git a/vquestion.cc b/vquestion.cc
new file mode 100644 (file)
index 0000000..075ff25
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vquestion.h"
+
+VQuestion::VQuestion()
+{
+  mainText = NULL;
+  selectedOption = NO;
+
+  buttonYes.setText("Yes");
+  buttonNo.setText("No");
+  buttonNo.setActive(1);
+
+}
+
+VQuestion::~VQuestion()
+{
+  if (mainText) delete[] mainText;
+}
+
+void VQuestion::setMainText(char* takeText)
+{
+  int length = strlen(takeText);
+  mainText = new char[length + 1];
+  strcpy(mainText, takeText);
+}
+
+void VQuestion::draw()
+{
+  View::draw();
+
+  buttonYes.setScreenPos(screenX + 40, screenY + 120);
+  buttonNo.setScreenPos(screenX + 140, screenY + 120);
+
+  if (mainText) drawPara(mainText, 10, 45, 255, 255, 255);
+  buttonYes.draw();
+  buttonNo.draw();
+}
+
+void VQuestion::swap()
+{
+  if (selectedOption == NO)
+  {
+    selectedOption = YES;
+    buttonYes.setActive(1);
+    buttonNo.setActive(0);
+  }
+  else if (selectedOption == YES)
+  {
+    selectedOption = NO;
+    buttonYes.setActive(0);
+    buttonNo.setActive(1);
+  }
+}
+
+int VQuestion::handleCommand(int command)
+{
+  if (command == Remote::LEFT)
+  {
+    swap();
+    draw();
+    show();
+    return 2;
+  }
+  else if (command == Remote::RIGHT)
+  {
+    swap();
+    draw();
+    show();
+    return 2;
+  }
+  else if (command == Remote::BACK)
+  {
+    return 4;
+  }
+  else if (command == Remote::OK)
+  {
+    if (selectedOption != YES) return 4;
+
+    Message* m = new Message();
+    m->from = this;
+    m->to = questionReceiver;
+    m->message = Message::QUESTION_YES;
+    ViewMan::getInstance()->postMessage(m);
+
+    return 4;
+  }
+
+  return 1;
+}
+
+void VQuestion::setParent(View* tquestionReceiver)
+{
+  questionReceiver = tquestionReceiver;
+}
+
+void VQuestion::setDefault(UCHAR option)
+{
+  selectedOption = option;
+}
diff --git a/vquestion.h b/vquestion.h
new file mode 100644 (file)
index 0000000..7a0b857
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VQUESTION_H
+#define VQUESTION_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "view.h"
+#include "wbutton.h"
+#include "remote.h"
+#include "viewman.h"
+
+class VQuestion : public View
+{
+  public:
+    VQuestion();
+    ~VQuestion();
+    void setParent(View* tquestionReceiver);
+    void setDefault(UCHAR option);
+    void setMainText(char* title);
+
+    int handleCommand(int command);
+    void draw();
+
+    const static UCHAR NO = 0;
+    const static UCHAR YES = 1;
+
+  private:
+    char* mainText;
+
+    void swap();
+
+    View* questionReceiver;
+    UCHAR selectedOption;
+
+    WButton buttonYes;
+    WButton buttonNo;
+};
+
+#endif
diff --git a/vradiolive.cc b/vradiolive.cc
new file mode 100644 (file)
index 0000000..e941cff
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vradiolive.h"
+
+VRadioLive::VRadioLive(List* tchanList)
+{
+  player = new PlayerRadio();
+  player->init();
+  vdr = VDR::getInstance();
+  chanList = tchanList;
+  currentChannel = 0;
+
+  setDimensions(100, 100);
+  setBackgroundColour(0, 0, 0, 255);
+}
+
+VRadioLive::~VRadioLive()
+{
+  delete player;
+}
+
+void VRadioLive::draw()
+{
+  View::draw();
+}
+
+int VRadioLive::handleCommand(int command)
+{
+  switch(command)
+  {
+    case Remote::STOP:
+    case Remote::BACK:
+    case Remote::MENU:
+    {
+      player->stop();
+      vdr->stopStreaming();
+      return 4;
+    }
+    case Remote::UP:
+    {
+      player->stop();
+      vdr->stopStreaming();
+      upChannel();
+      vdr->streamChannel(currentChannel);
+      player->play();
+      return 2;
+    }
+    case Remote::DOWN:
+    {
+      player->stop();
+      vdr->stopStreaming();
+      downChannel();
+      vdr->streamChannel(currentChannel);
+      player->play();
+      return 2;
+    }
+  }
+
+  return 1;
+}
+
+void VRadioLive::setChannel(int number)
+{
+  currentChannel = number;
+  vdr->streamChannel(currentChannel);
+  player->play();
+}
+
+void VRadioLive::upChannel()
+{
+  Channel* channel;
+  for(chanList->reset(); (channel = (Channel*)chanList->getCurrent()); chanList->next())
+  {
+    if (channel->number == currentChannel)
+    {
+      chanList->next();
+      channel = (Channel*)chanList->getCurrent();
+      if (!channel) return;
+      currentChannel = channel->number;
+    }
+  }
+}
+
+void VRadioLive::downChannel()
+{
+  Channel* channel;
+  Channel* prevChannel = NULL;
+  for(chanList->reset(); (channel = (Channel*)chanList->getCurrent()); chanList->next())
+  {
+    if (channel->number == currentChannel)
+    {
+      if (!prevChannel) return;
+      currentChannel = prevChannel->number;
+    }
+    prevChannel = channel;
+  }
+}
diff --git a/vradiolive.h b/vradiolive.h
new file mode 100644 (file)
index 0000000..00dc743
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VRADIOLIVE_H
+#define VRADIOLIVE_H
+
+#include <stdio.h>
+
+#include "view.h"
+#include "playerradio.h"
+#include "vdr.h"
+#include "list.h"
+#include "channel.h"
+#include "viewman.h"
+#include "remote.h"
+
+class VRadioLive : public View
+{
+  public:
+    VRadioLive(List* chanList);
+    ~VRadioLive();
+    void draw();
+    int handleCommand(int command);
+
+    void setChannel(int number);
+
+  private:
+    VDR* vdr;
+    PlayerRadio* player;
+    List* chanList;
+    ULONG currentChannel;
+
+    void upChannel();
+    void downChannel();
+};
+
+#endif
diff --git a/vrecordinglist.cc b/vrecordinglist.cc
new file mode 100644 (file)
index 0000000..91979a2
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vrecordinglist.h"
+
+VRecordingList::VRecordingList()
+{
+  setScreenPos(80, 70);
+  setDimensions(420, 570);
+
+  setBackgroundColour(0, 0, 100, 255);
+  setTitleBarOn(1);
+  setTitleBarColour(0, 0, 200, 255);
+
+  sl.setScreenPos(screenX + 10, screenY + 30 + 5);
+  sl.setDimensions(height - 30 - 15 - 30, width - 20);
+}
+
+VRecordingList::~VRecordingList()
+{
+  // only delete the list if this is not a sub dir window
+  if (recDir->isRoot) delete recDir;
+}
+
+void VRecordingList::setDir(Directory* tdir)
+{
+  recDir = tdir;
+  int first = 1;
+
+  char tempA[300]; // FIXME  this is guesswork!
+  char tempB[300]; // FIXME
+  struct tm* btime;
+
+  char spaces[13];
+  char theNumber[10];
+  int theNumberLength;
+
+  Directory* dir;
+  recDir->dirList->reset();
+  while((dir = (Directory*)recDir->dirList->getCurrent()))
+  {
+    strcpy(spaces, "            ");
+    theNumberLength = snprintf(theNumber, 9, "%lu", dir->getNumRecordings());
+
+    spaces[11 - theNumberLength] = '\0';
+
+    //snprintf(tempA, 299, "<dir>            %s", dir->name);
+    snprintf(tempA, 299, "<dir> %s%s%s", theNumber, spaces, dir->name);
+    //int numSize = snprintf(tempA
+
+    dir->index = sl.addOption(tempA, first);
+    first = 0;
+    recDir->dirList->next();
+  }
+
+  // temp FIXME
+  List* recList = recDir->recList;
+
+  // FIXME convert the whole program to time_t's
+
+
+  Recording* rec;
+  recList->reset();
+  while((rec = (Recording*)recList->getCurrent()))
+  {
+    btime = localtime((time_t*)&rec->start);
+    strftime(tempA, 299, "%0d/%0m %0H:%0M ", btime);
+    sprintf(tempB, "%s %s", tempA, rec->getProgName());
+    rec->index = sl.addOption(tempB, first);
+    first = 0;
+    recList->next();
+  }
+
+  if (!recDir->isRoot)
+  {
+    snprintf(tempA, 299, "Recordings - %s", recDir->name);
+    setTitleText(tempA);
+  }
+  else
+  {
+    setTitleText("Recordings");
+  }
+}
+
+void VRecordingList::draw()
+{
+  View::draw();
+  sl.draw();
+
+  // Put the status stuff at the bottom
+
+  WSymbol w;
+
+  w.nextSymbol = WSymbol::UP;
+  w.setScreenPos(screenX + 20, screenY + 385);
+  w.draw();
+
+  w.nextSymbol = WSymbol::DOWN;
+  w.setScreenPos(screenX + 50, screenY + 385);
+  w.draw();
+
+  w.nextSymbol = WSymbol::SKIPBACK;
+  w.setScreenPos(screenX + 85, screenY + 385);
+  w.draw();
+
+  w.nextSymbol = WSymbol::SKIPFORWARD;
+  w.setScreenPos(screenX + 115, screenY + 385);
+  w.draw();
+
+  w.nextSymbol = WSymbol::PLAY;
+  w.setScreenPos(screenX + 150, screenY + 385);
+  w.draw();
+
+  // FIXME Right justify this!
+  drawText("[ok] = menu", 450, 385, 255, 255, 255);
+
+  doShowingBar();
+
+  char freeSpace[50];
+  int gigFree = Directory::freeSpace / 1024;
+  snprintf(freeSpace, 49, "%lu%%, %iGB free", Directory::usedPercent, gigFree);
+  drawTextRJ(freeSpace, 560, 5, 255, 255, 255);
+}
+
+void VRecordingList::doShowingBar()
+{
+  int topOption = sl.getTopOption() + 1;
+  if (sl.getNumOptions() == 0) topOption = 0;
+
+  char showing[200];
+  sprintf(showing, "%i to %i of %i", topOption, sl.getBottomOption(), sl.getNumOptions());
+  Box b;
+  b.setScreenPos(screenX + 220, screenY + 385);
+  b.setDimensions(25, 160);
+  b.fillColour(0, 0, 100, 255);
+  b.drawText(showing, 0, 0, 255, 255, 255);
+}
+
+
+
+void VRecordingList::processMessage(Message* m)
+{
+  Log::getInstance()->log("VRecordingList", Log::DEBUG, "Got message value %lu", m->message);
+  if (m->message == Message::DELETE_SELECTED_RECORDING)
+  {
+    Log::getInstance()->log("VRecordingList", Log::DEBUG, "Doing delete selected");
+    doDeleteSelected();
+    return;
+  }
+
+  if (m->message == Message::PLAY_SELECTED_RECORDING)
+  {
+    doPlay();
+    return;
+  }
+
+  if (m->message == Message::RESUME_SELECTED_RECORDING)
+  {
+    doResume();
+    return;
+  }
+}
+
+void VRecordingList::doDeleteSelected()
+{
+  Recording* toDelete = getCurrentOptionRecording();
+
+  int saveIndex;
+  int saveTop;
+
+  if (toDelete)
+  {
+    saveIndex = toDelete->index;
+    saveTop = sl.getTopOption();
+    Log::getInstance()->log("VRecordingList", Log::DEBUG, "FOUND: %i %s %s\n", toDelete->index, toDelete->getProgName(), toDelete->fileName);
+    recDir->recList->remove(toDelete);
+    Log::getInstance()->log("VRecordingList", Log::DEBUG, "I have removed: %s %s\n", toDelete->getProgName(), toDelete->fileName);
+
+    VDR* vdr = VDR::getInstance();
+    vdr->deleteRecording(toDelete->fileName);
+
+    delete toDelete;
+
+    sl.clear();
+    setDir(recDir);
+    sl.hintSetCurrent(saveIndex);
+    sl.hintSetTop(saveTop);
+    draw();
+  }
+
+  Message* m2 = new Message();
+  m2->from = this;
+  m2->to = ViewMan::getInstance();
+  m2->message = Message::UPDATE_SCREEN;
+  ViewMan::getInstance()->postMessage(m2);
+}
+
+int VRecordingList::doPlay()
+{
+  Recording* toPlay = getCurrentOptionRecording();
+  if (toPlay)
+  {
+    VVideoRec* vidrec = new VVideoRec(toPlay);
+    ViewMan::getInstance()->addNoLock(vidrec);
+    vidrec->draw();
+    vidrec->show();
+    vidrec->go(0);
+    return 1;
+  }
+  // should not get to here
+  return 0;
+}
+
+int VRecordingList::doResume()
+{
+  Recording* toResume = getCurrentOptionRecording();
+  if (toResume)
+  {
+    ULLONG position = VDR::getInstance()->getResumePoint(toResume->fileName);
+
+    VVideoRec* vidrec = new VVideoRec(toResume);
+    ViewMan::getInstance()->addNoLock(vidrec);
+    vidrec->draw();
+    vidrec->show();
+    vidrec->go(position);
+    return 1;
+  }
+  // should not get to here
+  return 0;
+}
+
+Recording* VRecordingList::getCurrentOptionRecording()
+{
+  Recording* current;
+  for(recDir->recList->reset(); (current = (Recording*)recDir->recList->getCurrent()); recDir->recList->next())
+  {
+    if (current->index == sl.getCurrentOption()) return current;
+  }
+  return NULL;
+}
+
+int VRecordingList::handleCommand(int command)
+{
+  if (command == Remote::UP)
+  {
+    sl.up();
+    sl.draw();
+
+    doShowingBar();
+    show();
+    return 2;
+  }
+  else if (command == Remote::DOWN)
+  {
+    sl.down();
+    sl.draw();
+
+    doShowingBar();
+    show();
+    return 2;
+  }
+  else if (command == Remote::SKIPBACK)
+  {
+    sl.pageUp();
+    sl.draw();
+
+    doShowingBar();
+    show();
+    return 2;
+  }
+  else if (command == Remote::SKIPFORWARD)
+  {
+    sl.pageDown();
+    sl.draw();
+
+    doShowingBar();
+    show();
+    return 2;
+  }
+  else if (command == Remote::OK)
+  {
+    if (sl.getNumOptions() == 0) return 2;
+
+    // Check to see if it is a sub directory
+    Directory* curDir;
+    for(recDir->dirList->reset(); (curDir = (Directory*)recDir->dirList->getCurrent()); recDir->dirList->next())
+    {
+      if (curDir->index == sl.getCurrentOption())
+      {
+        VRecordingList* sub = new VRecordingList();
+        sub->setDir(curDir);
+        ViewMan::getInstance()->addNoLock(sub);
+
+        sub->draw();
+        sub->show();
+
+        return 2;
+      }
+    }
+
+    // check to see if it's a recording
+    Recording* current;
+    for(recDir->recList->reset(); (current = (Recording*)recDir->recList->getCurrent()); recDir->recList->next())
+    {
+      if (current->index == sl.getCurrentOption())
+      {
+        Log::getInstance()->log("VRecordingList", Log::DEBUG, "Found the option you pointed at. %s %s", current->getProgName(), current->fileName);
+
+        VRecordingMenu* v = new VRecordingMenu();
+        v->setParent(this);
+        v->setRecording(current);
+        ViewMan::getInstance()->addNoLock(v);
+        v->draw();
+        v->show();
+        return 2;
+      }
+    }
+    // should not get to here
+    return 1;
+  }
+  else if (command == Remote::BACK)
+  {
+    return 4;
+  }
+  else if (command == Remote::PLAY)
+  {
+    if (doPlay()) return 2;
+    return 1;
+  }
+
+  // stop command getting to any more views
+  return 1;
+}
diff --git a/vrecordinglist.h b/vrecordinglist.h
new file mode 100644 (file)
index 0000000..1d5425c
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VRECORDINGLIST_H
+#define VRECORDINGLIST_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "view.h"
+#include "list.h"
+#include "directory.h"
+#include "recording.h"
+#include "wselectlist.h"
+#include "remote.h"
+#include "wsymbol.h"
+#include "viewman.h"
+#include "vrecordingmenu.h"
+#include "vdr.h"
+#include "vvideorec.h"
+
+class VRecordingList : public View
+{
+  public:
+    VRecordingList();
+    ~VRecordingList();
+
+    void setDir(Directory* dir);
+
+    int handleCommand(int command);
+    void processMessage(Message* m);
+    void draw();
+
+  private:
+    Directory* recDir;
+
+    WSelectList sl;
+
+    void doShowingBar();
+    void doDeleteSelected();
+    int doPlay();
+    int doResume();
+    Recording* getCurrentOptionRecording();
+};
+
+#endif
diff --git a/vrecordingmenu.cc b/vrecordingmenu.cc
new file mode 100644 (file)
index 0000000..fc434e3
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vrecordingmenu.h"
+
+VRecordingMenu::VRecordingMenu()
+{
+  rec = NULL;
+
+  setScreenPos(260, 190);
+  setDimensions(140, 200);
+
+  setBackgroundColour(0, 0, 100, 255);
+  setTitleBarOn(1);
+  setBorderOn(1);
+  setTitleText("Programme menu");
+  setTitleBarColour(0, 0, 200, 255);
+
+  sl.setScreenPos(screenX + 10, screenY + 30 + 5);
+  sl.setDimensions(height - 30 - 15, width - 20);
+  sl.addOption("Play", 1);
+  sl.addOption("Resume", 0);
+  sl.addOption("Summary", 0);
+  sl.addOption("Delete", 0);
+}
+
+VRecordingMenu::~VRecordingMenu()
+{
+}
+
+void VRecordingMenu::setParent(VRecordingList* tvRecList)
+{
+  vRecList = tvRecList;
+}
+
+void VRecordingMenu::setRecording(Recording* trec)
+{
+  rec = trec;
+}
+
+void VRecordingMenu::draw()
+{
+  View::draw();
+  sl.draw();
+}
+
+int VRecordingMenu::handleCommand(int command)
+{
+  if (command == Remote::UP)
+  {
+    sl.up();
+    sl.draw();
+    show();
+    return 2;
+  }
+  else if (command == Remote::DOWN)
+  {
+    sl.down();
+    sl.draw();
+    show();
+    return 2;
+  }
+  else if (command == Remote::OK)
+  {
+    if (sl.getCurrentOption() == 0)
+    {
+      Message* m = new Message();
+      m->from = this;
+      m->to = vRecList;
+      m->message = Message::PLAY_SELECTED_RECORDING;
+      ViewMan::getInstance()->postMessage(m);
+      return 4;
+    }
+
+    if (sl.getCurrentOption() == 1)
+    {
+      Message* m = new Message();
+      m->from = this;
+      m->to = vRecList;
+      m->message = Message::RESUME_SELECTED_RECORDING;
+      ViewMan::getInstance()->postMessage(m);
+      return 4;
+    }
+
+    if (sl.getCurrentOption() == 2)
+    {
+      char* summary = VDR::getInstance()->getRecordingSummary(rec->fileName);
+
+      VInfo* vi = new VInfo();
+      vi->setTitleText("Programme summary");
+      vi->setBorderOn(1);
+      vi->setExitable();
+      if (summary) vi->setMainText(summary);
+      else vi->setMainText("Summary unavailable");
+      vi->setScreenPos(120, 130);
+      vi->setDimensions(300, 490);
+
+      ViewMan::getInstance()->addNoLock(vi);
+      vi->draw();
+      vi->show();
+
+      if (summary) delete[] summary;
+
+      return 2;
+    }
+    else if (sl.getCurrentOption() == 3)
+    {
+      VQuestion* v = new VQuestion();
+      v->setParent(this);
+      v->setBackgroundColour(0, 0, 100, 255);
+      v->setTitleBarColour(200, 0, 0, 255);
+      v->setTitleBarOn(1);
+      v->setBorderOn(1);
+      v->setTitleText("Delete recording");
+      v->setMainText("Are you sure you want to delete this recording?");
+      v->setDefault(VQuestion::NO);
+      v->setScreenPos(230, 160);
+      v->setDimensions(180, 260);
+
+      ViewMan::getInstance()->addNoLock(v);
+      v->draw();
+      v->show();
+      return 2;
+    }
+  }
+  else if (command == Remote::BACK)
+  {
+    return 4;
+  }
+
+  // stop command getting to any more views
+  return 1;
+}
+
+void VRecordingMenu::processMessage(Message* m)
+{
+  if (m->message == Message::QUESTION_YES)
+  {
+    if (sl.getCurrentOption() == 3)
+    {
+      Message* m = new Message();
+      m->from = this;
+      m->to = ViewMan::getInstance();
+      m->message = Message::CLOSE_ME;
+      ViewMan::getInstance()->postMessage(m);
+
+      m = new Message();
+      m->from = this;
+      m->to = vRecList;
+      m->message = Message::DELETE_SELECTED_RECORDING;
+      ViewMan::getInstance()->postMessage(m);
+    }
+  }
+}
diff --git a/vrecordingmenu.h b/vrecordingmenu.h
new file mode 100644 (file)
index 0000000..6fe269e
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VRECORDINGMENU_H
+#define VRECORDINGMENU_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "view.h"
+#include "recording.h"
+#include "wselectlist.h"
+#include "remote.h"
+#include "vrecordinglist.h"
+#include "vquestion.h"
+#include "message.h"
+#include "vinfo.h"
+#include "vdr.h"
+
+class VRecordingList;
+
+class VRecordingMenu : public View
+{
+  public:
+    VRecordingMenu();
+    ~VRecordingMenu();
+    void setParent(VRecordingList* tvRecList);
+    void setRecording(Recording* rec);
+
+    int handleCommand(int command);
+    void processMessage(Message* m);
+    void draw();
+
+  private:
+
+    WSelectList sl;
+    VRecordingList* vRecList;
+    Recording* rec;
+};
+
+#endif
diff --git a/vserverselect.cc b/vserverselect.cc
new file mode 100644 (file)
index 0000000..8a96bdc
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vserverselect.h"
+
+VServerSelect::VServerSelect(std::vector<char*>* serverIPs, int* tselectServer)
+{
+  // I tried the whole passing using a reference here, but
+  // the program segfaulted when settitletext tried to new
+  // a char array. so now we have the messy dereferencing...
+  // anyway, now it doesn't use a object wide reference.
+  selectServer = tselectServer;
+
+  setDimensions(200, 300);
+  setScreenPos(220, 200);
+  setBackgroundColour(0, 0, 100, 255);
+  setTitleBarOn(1);
+  setTitleBarColour(0, 0, 200, 255);
+  setTitleText("Choose a VDR server");
+
+  sl.setScreenPos(screenX + 10, screenY + 30 + 5);
+  sl.setDimensions(height - 30 - 15, width - 20);
+
+  sl.addOption((*serverIPs)[0], 1);
+  for(UINT k = 1; k < serverIPs->size(); k++)
+  {
+    sl.addOption((*serverIPs)[k], 0);
+  }
+}
+
+VServerSelect::~VServerSelect()
+{
+}
+
+void VServerSelect::draw()
+{
+  View::draw();
+  sl.draw();
+}
+
+int VServerSelect::handleCommand(int command)
+{
+  if (command == Remote::UP)
+  {
+    sl.up();
+    sl.draw();
+    show();
+    return 2;
+  }
+  else if (command == Remote::DOWN)
+  {
+    sl.down();
+    sl.draw();
+    show();
+    return 2;
+  }
+  else if (command == Remote::OK)
+  {
+    *selectServer = sl.getCurrentOption();
+    return 4;
+  }
+
+  return 1;
+}
diff --git a/vserverselect.h b/vserverselect.h
new file mode 100644 (file)
index 0000000..c00b9ff
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VSERVERSELECT_H
+#define VSERVERSELECT_H
+
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+
+#include "defines.h"
+#include "view.h"
+#include "remote.h"
+#include "wselectlist.h"
+
+class VServerSelect : public View
+{
+  public:
+    VServerSelect(std::vector<char*>* tserverIPs, int* tselectServer);
+    ~VServerSelect();
+
+    int handleCommand(int command);
+    void draw();
+
+  private:
+    WSelectList sl;
+    int* selectServer;
+};
+
+#endif
diff --git a/vvideolive.cc b/vvideolive.cc
new file mode 100644 (file)
index 0000000..c6da0eb
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vvideolive.h"
+
+VVideoLive::VVideoLive(List* tchanList)
+{
+  player = new Player(NULL);
+  player->init();
+  vdr = VDR::getInstance();
+  chanList = tchanList;
+  currentChannel = 0;
+
+  setDimensions(SCREENHEIGHT, SCREENWIDTH);
+  setBackgroundColour(0, 0, 0, 0);
+}
+
+VVideoLive::~VVideoLive()
+{
+  delete player;
+}
+
+void VVideoLive::draw()
+{
+  View::draw();
+}
+
+int VVideoLive::handleCommand(int command)
+{
+  switch(command)
+  {
+    case Remote::PLAY:
+    {
+      player->play(); // do resync
+      return 2;
+    }
+
+    case Remote::STOP:
+    case Remote::BACK:
+    case Remote::MENU:
+    {
+      player->stop();
+      vdr->stopStreaming();
+      return 4;
+    }
+    case Remote::UP:
+    {
+      player->stop();
+      vdr->stopStreaming();
+      upChannel();
+      doBanner();
+      vdr->streamChannel(currentChannel);
+      player->play();
+      return 2;
+    }
+    case Remote::DOWN:
+    {
+      player->stop();
+      vdr->stopStreaming();
+      downChannel();
+      doBanner();
+      vdr->streamChannel(currentChannel);
+      player->play();
+      return 2;
+    }
+    case Remote::OK:
+    {
+      doBanner();
+      return 2;
+    }
+
+    case Remote::ZERO ... Remote::NINE:
+    {
+      VChannelSelect* v = new VChannelSelect(this, command);
+      ViewMan::getInstance()->addNoLock(v);
+//      ViewMan::getInstance()->timedDelete(v, 4, 0);
+      v->draw();
+      v->show();
+    }
+  }
+
+  return 1;
+}
+
+void VVideoLive::processMessage(Message* m)
+{
+  if (m->message == Message::CHANNEL_CHANGE)
+  {
+    // check channel number is valid
+    Channel* channel;
+    for(chanList->reset(); (channel = (Channel*)chanList->getCurrent()); chanList->next())
+    {
+      if (channel->number == m->parameter)
+      {
+        player->stop();
+        vdr->stopStreaming();
+        setChannel(channel->number);
+      }
+    }
+  }
+}
+
+void VVideoLive::doBanner()
+{
+  VLiveBanner* v = new VLiveBanner();
+  ViewMan::getInstance()->addNoLock(v);
+  ViewMan::getInstance()->timedDelete(v, 4, 0);
+  v->draw();
+  v->show();
+}
+
+void VVideoLive::setChannel(int number)
+{
+  currentChannel = number;
+//  doBanner();
+  vdr->streamChannel(currentChannel);
+  player->play();
+}
+
+void VVideoLive::upChannel()
+{
+  Channel* channel;
+  for(chanList->reset(); (channel = (Channel*)chanList->getCurrent()); chanList->next())
+  {
+    if (channel->number == currentChannel)
+    {
+      chanList->next();
+      channel = (Channel*)chanList->getCurrent();
+      if (!channel) return;
+      currentChannel = channel->number;
+    }
+  }
+}
+
+void VVideoLive::downChannel()
+{
+  Channel* channel;
+  Channel* prevChannel = NULL;
+  for(chanList->reset(); (channel = (Channel*)chanList->getCurrent()); chanList->next())
+  {
+    if (channel->number == currentChannel)
+    {
+      if (!prevChannel) return;
+      currentChannel = prevChannel->number;
+    }
+    prevChannel = channel;
+  }
+}
diff --git a/vvideolive.h b/vvideolive.h
new file mode 100644 (file)
index 0000000..5664871
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VVIDEOLIVE_H
+#define VVIDEOLIVE_H
+
+#include <stdio.h>
+
+#include "view.h"
+#include "player.h"
+#include "vdr.h"
+#include "list.h"
+#include "channel.h"
+#include "vlivebanner.h"
+#include "viewman.h"
+#include "vchannelselect.h"
+
+class VVideoLive : public View
+{
+  public:
+    VVideoLive(List* chanList);
+    ~VVideoLive();
+    void draw();
+    int handleCommand(int command);
+    void processMessage(Message* m);
+
+    void setChannel(int number);
+
+  private:
+    VDR* vdr;
+    Player* player;
+    List* chanList;
+    ULONG currentChannel;
+
+    void upChannel();
+    void downChannel();
+    void doBanner();
+};
+
+#endif
diff --git a/vvideorec.cc b/vvideorec.cc
new file mode 100644 (file)
index 0000000..a1e8af0
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vvideorec.h"
+
+VVideoRec::VVideoRec(Recording* rec)
+{
+  player = new Player(Command::getInstance());
+  player->init();
+  vdr = VDR::getInstance();
+
+  myRec = rec;
+
+  setDimensions(SCREENHEIGHT, SCREENWIDTH);
+  setBackgroundColour(0, 0, 0, 0);
+}
+
+VVideoRec::~VVideoRec()
+{
+  delete player;
+}
+
+void VVideoRec::draw()
+{
+  View::draw();
+}
+
+void VVideoRec::go(ULLONG startPosition)
+{
+  ULLONG recLength = vdr->streamRecording(myRec);
+
+  player->setLength(recLength);
+  player->setPosition(startPosition);
+  player->play();
+}
+
+int VVideoRec::handleCommand(int command)
+{
+  switch(command)
+  {
+    case Remote::PLAY:
+    {
+      player->play(); // do resync
+      return 2;
+    }
+
+    case Remote::STOP:
+    case Remote::BACK:
+    case Remote::MENU:
+    {
+      player->stop();
+      vdr->stopStreaming();
+      return 4;
+    }
+    case Remote::PAUSE:
+    {
+      player->togglePause();
+      return 2;
+    }
+    case Remote::SKIPFORWARD:
+    {
+      player->skipForward(60);
+      return 2;
+    }
+    case Remote::SKIPBACK:
+    {
+      player->skipBackward(60);
+      return 2;
+    }
+    case Remote::FORWARD:
+    {
+      player->toggleFastForward();
+      return 2;
+    }
+    case Remote::YELLOW:
+    {
+      player->skipBackward(10);
+      return 2;
+    }
+    case Remote::BLUE:
+    {
+      player->skipForward(10);
+      return 2;
+    }
+//    case Remote::REVERSE:
+//    {
+//      player->toggleFastBackward();
+//      return 2;
+//    }
+
+    case Remote::ZERO: player->jumpToPercent(0); return 2;
+    case Remote::ONE: player->jumpToPercent(10); return 2;
+    case Remote::TWO: player->jumpToPercent(20); return 2;
+    case Remote::THREE: player->jumpToPercent(30); return 2;
+    case Remote::FOUR: player->jumpToPercent(40); return 2;
+    case Remote::FIVE: player->jumpToPercent(50); return 2;
+    case Remote::SIX: player->jumpToPercent(60); return 2;
+    case Remote::SEVEN: player->jumpToPercent(70); return 2;
+    case Remote::EIGHT: player->jumpToPercent(80); return 2;
+    case Remote::NINE: player->jumpToPercent(90); return 2;
+
+  }
+
+  return 1;
+}
diff --git a/vvideorec.h b/vvideorec.h
new file mode 100644 (file)
index 0000000..42ac6ad
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VVIDEOREC_H
+#define VVIDEOREC_H
+
+#include <stdio.h>
+
+#include "view.h"
+#include "player.h"
+#include "vdr.h"
+#include "recording.h"
+#include "command.h"
+
+class VVideoRec : public View
+{
+  public:
+    VVideoRec(Recording* rec);
+    ~VVideoRec();
+    void draw();
+    int handleCommand(int command);
+    void go(ULLONG startPosition);
+
+  private:
+    VDR* vdr;
+    Player* player;
+    Recording* myRec;
+};
+
+#endif
diff --git a/vvolume.cc b/vvolume.cc
new file mode 100644 (file)
index 0000000..d8cd838
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vvolume.h"
+
+VVolume::VVolume()
+{
+  displayVolume = Audio::getInstance()->getVolume();
+
+  setDimensions(31, 227);
+  setScreenPos(100, 499);
+
+  setBackgroundColour(0, 0, 100, 255);
+}
+
+void VVolume::draw()
+{
+  View::draw();
+
+  WSymbol* w = new WSymbol;
+  w->nextSymbol = WSymbol::VOLUME2;
+  w->setScreenPos(103, 509);
+  w->draw();
+
+  int i = 0;
+
+  for(; i < displayVolume; i++)
+  {
+    w->nextSymbol = WSymbol::VOLBAR;
+    w->setScreenPos(140 + (i * 9), 502);
+    w->draw();
+  }
+
+  for(; i < 20; i++)
+  {
+    w->nextSymbol = WSymbol::VOLDOT;
+    w->setScreenPos(140 + (i * 9), 512);
+    w->draw();
+  }
+
+  delete w;
+}
+
+int VVolume::handleCommand(int command)
+{
+  switch(command)
+  {
+    case Remote::LEFT:
+    {
+      displayVolume = Audio::getInstance()->volumeDown();
+      draw();
+      show();
+      // handled
+      return 2;
+    }
+    case Remote::RIGHT:
+    {
+      displayVolume = Audio::getInstance()->volumeUp();
+      draw();
+      show();
+      // handled
+      return 2;
+    }
+  }
+
+  // allow command to drop through to other views
+  return 0;
+}
diff --git a/vvolume.h b/vvolume.h
new file mode 100644 (file)
index 0000000..a5ea0b7
--- /dev/null
+++ b/vvolume.h
@@ -0,0 +1,45 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VVOLUME_H
+#define VVOLUME_H
+
+#include <stdio.h>
+
+#include "view.h"
+#include "remote.h"
+#include "audio.h"
+#include "wsymbol.h"
+
+class VVolume : public View
+{
+  public:
+    VVolume();
+    void draw();
+    int handleCommand(int command);
+
+  private:
+    int displayCommand;
+    int displayVolume;
+
+};
+
+#endif
+
diff --git a/vwallpaper.cc b/vwallpaper.cc
new file mode 100644 (file)
index 0000000..6b149f3
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vwallpaper.h"
+
+VWallpaper::VWallpaper()
+{
+
+}
+
+VWallpaper::~VWallpaper()
+{
+  delete surface;
+}
+
+void VWallpaper::init(char* name)
+{
+  jpeg.init(name);
+
+  Osd* o = Osd::getInstance();
+  setDimensions(o->getScreenHeight(), o->getScreenWidth());
+
+  // Now override the surface pointer found in Box to a seperate wallpaper surface
+  // but only for the wjpeg, not for this object
+  wallpaperSurface = new Surface(o->getFD(), 0);
+  wallpaperSurface->create(height, width);
+
+  jpeg.overrideSurface(wallpaperSurface);
+  jpeg.draw();
+}
+
+void VWallpaper::draw()
+{
+  // we want to blit from wallpaperSurface to buffer (or screen if !doubleBuffer)
+  Surface::blt(Osd::getInstance()->getFD(), wallpaperSurface->getSurfaceHandle(), 0, 0, width, height, surface->getSurfaceHandle(), 0, 0);
+  // and the fd business here is terrible, but what can you do.
+}
diff --git a/vwallpaper.h b/vwallpaper.h
new file mode 100644 (file)
index 0000000..0154ff3
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VWALLPAPER_H
+#define VWALLPAPER_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "view.h"
+#include "wjpeg.h"
+
+#include "osd.h"
+#include "surface.h"
+
+class VWallpaper : public View
+{
+  public:
+    VWallpaper();
+    ~VWallpaper();
+
+    void init(char* file);
+
+    void draw();
+
+  private:
+    Surface* wallpaperSurface;
+    WJpeg jpeg;
+};
+
+#endif
diff --git a/vwelcome.cc b/vwelcome.cc
new file mode 100644 (file)
index 0000000..1fb335e
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "vwelcome.h"
+
+VWelcome::VWelcome()
+{
+  setDimensions(190, 460);
+  setScreenPos(140, 170);
+
+  setBackgroundColour(0, 0, 100, 255);
+  setTitleBarOn(1);
+  setTitleBarColour(0, 0, 200, 255);
+  setTitleText("Welcome");
+
+  sl.setScreenPos(screenX + 20, screenY + 40);
+  sl.setDimensions(130, 170);
+
+  sl.addOption("1. Live TV", 1);
+  sl.addOption("2. Radio", 0);
+  sl.addOption("3. Recordings", 0);
+  sl.addOption("4. Stand by", 0);
+  sl.addOption("5. Reboot", 0);
+
+  jpeg.setScreenPos(screenX + 240, screenY + 50);
+}
+
+VWelcome::~VWelcome()
+{
+}
+
+void VWelcome::draw()
+{
+
+  View::draw();
+  sl.draw();
+
+  char timeString[20];
+  time_t t;
+  time(&t);
+  struct tm* tm = localtime(&t);
+  strftime(timeString, 19, "%H:%M", tm);
+
+  drawTextRJ(timeString, 450, 5, 255, 255, 255);
+
+  jpeg.init("/vdr.jpg");
+  jpeg.draw();
+}
+
+int VWelcome::handleCommand(int command)
+{
+  if (command == Remote::UP)
+  {
+    sl.up();
+    sl.draw();
+    show();
+    return 2;
+  }
+  else if (command == Remote::DOWN)
+  {
+    sl.down();
+    sl.draw();
+    show();
+    return 2;
+  }
+  else if (command == Remote::ONE)
+  {
+    doChannelsList();
+    return 2;
+  }
+  else if (command == Remote::TWO)
+  {
+    doRadioList();
+    return 2;
+  }
+  else if (command == Remote::THREE)
+  {
+    doRecordingsList();
+    return 2;
+  }
+  else if (command == Remote::FOUR)
+  {
+    Message* m = new Message();
+    m->message = Message::STANDBY;
+    Command::getInstance()->postMessage(m);
+    return 4;
+  }
+  else if (command == Remote::FIVE)
+  {
+    Command::getInstance()->doReboot();
+  }
+  else if (command == Remote::OK)
+  {
+    int option = sl.getCurrentOption();
+    if (option == 0)
+    {
+      doChannelsList();
+      return 2;
+    }
+    else if (option == 1)
+    {
+      doRadioList();
+      return 2;
+    }
+    else if (option == 2)
+    {
+      doRecordingsList();
+      return 2;
+    }
+    else if (option == 3)
+    {
+      Message* m = new Message();
+      m->message = Message::STANDBY;
+      Command::getInstance()->postMessage(m);
+      return 4;
+    }
+    else if (option == 4)
+    {
+      Command::getInstance()->doReboot();
+      return 2;
+    }
+  }
+
+  return 1;
+}
+
+
+void VWelcome::doChannelsList()
+{
+  List* chanList = VDR::getInstance()->getChannelsList(VDR::VIDEO);
+
+  if (chanList)
+  {
+    VChannelList* vchan = new VChannelList(VDR::VIDEO);
+    vchan->setList(chanList);
+
+    ViewMan::getInstance()->addNoLock(vchan);
+    vchan->draw();
+    vchan->show();
+
+//        Message* m = new Message();
+//        m->from = this;
+//        m->to = ViewMan::getInstance();
+//        m->message = Message::SWAP_ME_FOR;
+//        m->parameter = (ULONG)vchan;
+//        ViewMan::getInstance()->postMessage(m);
+  }
+}
+
+void VWelcome::doRadioList()
+{
+  List* chanList = VDR::getInstance()->getChannelsList(VDR::RADIO);
+
+  if (chanList)
+  {
+    VChannelList* vchan = new VChannelList(VDR::RADIO);
+    vchan->setList(chanList);
+
+    ViewMan::getInstance()->addNoLock(vchan);
+    vchan->draw();
+    vchan->show();
+  }
+}
+
+void VWelcome::doRecordingsList()
+{
+  ViewMan* viewman = ViewMan::getInstance();
+
+  VInfo* viewWait = new VInfo();
+  viewWait->setDimensions(190, 460);
+  viewWait->setScreenPos(140, 170);
+  viewWait->setMainText("\n                  Downloading recordings list");
+  viewWait->draw();
+  viewWait->show();
+  viewman->addNoLock(viewWait);
+
+
+  VDR* vdr = VDR::getInstance();
+  Directory* recDir = vdr->getRecordingsList();
+
+  if (recDir)
+  {
+    VRecordingList* vrec = new VRecordingList();
+    vrec->setDir(recDir);
+
+    ViewMan::getInstance()->addNoLock(vrec);
+
+    vrec->draw();
+    vrec->show();
+  }
+
+  Log::getInstance()->log("VWelcome", Log::DEBUG, "possible delay start");
+  viewman->removeView(viewWait, 1, 1);
+  Log::getInstance()->log("VWelcome", Log::DEBUG, "possible delay end");
+}
diff --git a/vwelcome.h b/vwelcome.h
new file mode 100644 (file)
index 0000000..fe5a52b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VWELCOME_H
+#define VWELCOME_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "view.h"
+#include "remote.h"
+#include "wselectlist.h"
+#include "wjpeg.h"
+#include "viewman.h"
+#include "vdr.h"
+#include "directory.h"
+#include "vchannellist.h"
+#include "vrecordinglist.h"
+#include "command.h"
+#include "message.h"
+
+class VWelcome : public View
+{
+  public:
+    VWelcome();
+    ~VWelcome();
+
+    int handleCommand(int command);
+    void draw();
+
+  private:
+
+    WSelectList sl;
+    WJpeg jpeg;
+
+    void doChannelsList();
+    void doRadioList();
+    void doRecordingsList();
+};
+
+#endif
diff --git a/wbutton.cc b/wbutton.cc
new file mode 100644 (file)
index 0000000..ccf322f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "wbutton.h"
+
+WButton::WButton()
+{
+  int fontHeight = surface->getFontHeight();
+  setDimensions(fontHeight, 70);
+
+  mytext = NULL;
+  active = 0;
+}
+
+WButton::~WButton()
+{
+  if (mytext) delete[] mytext;
+}
+
+void WButton::setText(char* takeText)
+{
+  int length = strlen(takeText);
+  mytext = new char[length + 1];
+  strcpy(mytext, takeText);
+}
+
+void WButton::setActive(UCHAR tactive)
+{
+  active = tactive;
+}
+
+void WButton::draw()
+{
+  UCHAR r1, g1, b1, r2, g2, b2;
+
+  if (active)
+  {
+    r1 = 0;
+    g1 = 0;
+    b1 = 100;
+    r2 = 240;
+    g2 = 250;
+    b2 = 80;
+  }
+  else
+  {
+    r1 = 255;
+    g1 = 255;
+    b1 = 255;
+    r2 = 0;
+    g2 = 0;
+    b2 = 150;
+  }
+
+  fillColour(r2, g2, b2, 255);
+  drawText(mytext, 0, 0, r1, g1, b1);
+
+
+}
diff --git a/wbutton.h b/wbutton.h
new file mode 100644 (file)
index 0000000..f93c5c3
--- /dev/null
+++ b/wbutton.h
@@ -0,0 +1,45 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef WBUTTON_H
+#define WBUTTON_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "defines.h"
+#include "box.h"
+
+class WButton : public Box
+{
+  public:
+    WButton();
+    ~WButton();
+    void setText(char* text);
+    void setActive(UCHAR tactive);
+    void draw();
+
+  private:
+    UCHAR active;
+
+    char* mytext;
+};
+
+#endif
diff --git a/wjpeg.cc b/wjpeg.cc
new file mode 100644 (file)
index 0000000..6379c4e
--- /dev/null
+++ b/wjpeg.cc
@@ -0,0 +1,112 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "wjpeg.h"
+
+int WJpeg::init(char* fileName)
+{
+  this->fileName = fileName;
+  return 1;
+}
+
+void WJpeg::overrideSurface(Surface* newSurface)
+{
+  surface = newSurface;
+}
+
+void WJpeg::draw()
+{
+  Log* logger = Log::getInstance();
+
+  logger->log("BJpeg", Log::DEBUG, "Here1");
+
+  FILE* infile = fopen(fileName, "r");
+  if (infile == NULL)
+  {
+    logger->log("BJpeg", Log::ERR, "Can't open JPEG");
+    return;
+  }
+  logger->log("BJpeg", Log::DEBUG, "File opened");
+
+  struct jpeg_decompress_struct cinfo;
+  struct jpeg_error_mgr jerr;
+  cinfo.err = jpeg_std_error(&jerr);
+  jpeg_create_decompress(&cinfo);
+  jpeg_stdio_src(&cinfo, infile);
+  jpeg_read_header(&cinfo, TRUE);
+  jpeg_start_decompress(&cinfo);
+
+  logger->log("BJpeg", Log::DEBUG, "JPEG startup done");
+
+  // Init the surface
+  setDimensions(cinfo.output_height, cinfo.output_width);
+
+
+  // MAKE THE 2D ARRAY
+
+  unsigned char* buffer = (unsigned char*)malloc(height * width * 3);
+  logger->log("BJpeg", Log::DEBUG, "Buffer allocated at %p", buffer);
+
+  unsigned char* bufferPointers[height];
+  for(int ps = 0; ps < height; ps++) bufferPointers[ps] = buffer + (ps * width * 3);
+
+  logger->log("BJpeg", Log::DEBUG, "done array check");
+
+  int rowsread = 0;
+  while (cinfo.output_scanline < cinfo.output_height)
+  {
+    rowsread += jpeg_read_scanlines(&cinfo, &bufferPointers[rowsread], height);
+  }
+
+  logger->log("BJpeg", Log::DEBUG, "Done all jpeg_read");
+
+  jpeg_finish_decompress(&cinfo);
+  jpeg_destroy_decompress(&cinfo);
+
+  fclose(infile);
+
+  logger->log("BJpeg", Log::DEBUG, "jpeg shutdown done, x, y %u %u", width, height);
+
+  unsigned int c;
+  int x, y, xoff;
+  unsigned char* p;
+
+  for (y = 0; y < height; y++)
+  {
+    p = bufferPointers[y];
+
+    for (x = 0; x < width; x++)
+    {
+      xoff = x * 3;
+
+      c = (  (0xFF000000        )
+           | (p[xoff    ]  << 16)
+           | (p[xoff + 1]  <<  8)
+           | (p[xoff + 2]       ) );
+
+      surface->drawPixel(screenX + x, screenY + y, c);
+    }
+  }
+
+  free(buffer);
+  logger->log("BJpeg", Log::DEBUG, "deleted buffer");
+
+}
+
diff --git a/wjpeg.h b/wjpeg.h
new file mode 100644 (file)
index 0000000..2b43df7
--- /dev/null
+++ b/wjpeg.h
@@ -0,0 +1,48 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef WJPEG_H
+#define WJPEG_H
+
+#include <stdio.h>
+#include <malloc.h>
+extern "C"
+{
+  #include <jpeglib.h>
+}
+
+#include "log.h"
+#include "box.h"
+#include "surface.h"
+
+class WJpeg : public Box
+{
+  public:
+
+    int init(char* fileName);
+    void draw();
+
+    void overrideSurface(Surface *newSurface);
+
+  private:
+    char* fileName;
+};
+
+#endif
diff --git a/wselectlist.cc b/wselectlist.cc
new file mode 100644 (file)
index 0000000..de93a2e
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "wselectlist.h"
+
+WSelectList::WSelectList()
+{
+  numOptions = 0;
+  selectedOption = 0;
+  topOption = 0;
+  numOptionsDisplayable = 0;
+}
+
+WSelectList::~WSelectList()
+{
+  clear();
+}
+
+void WSelectList::clear()
+{
+  for (int i = 0; i < numOptions; i++)
+  {
+    delete[] options[i];
+  }
+
+  numOptions = 0;
+  selectedOption = 0;
+  topOption = 0;
+  numOptionsDisplayable = 0;
+}
+
+void WSelectList::hintSetCurrent(int index)
+{
+  selectedOption = index;
+  if (selectedOption >= numOptions) selectedOption = numOptions - 1;
+}
+
+void WSelectList::hintSetTop(int index)
+{
+  topOption = index;
+}
+
+int WSelectList::addOption(char* text, int selected)
+{
+  int thisNewOption = numOptions;
+  int length = strlen(text);
+  options[thisNewOption] = new char[length + 1];
+  strcpy(options[thisNewOption], text);
+  if (selected) selectedOption = thisNewOption;
+  numOptions++;
+  return thisNewOption;
+}
+
+void WSelectList::draw()
+{
+  int fontHeight = surface->getFontHeight();
+  int ySeperation = fontHeight + 1;
+
+  numOptionsDisplayable = (height - 5) / ySeperation;
+
+  if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
+  if (selectedOption == (topOption - 1)) topOption--;
+  // if still not visible...
+  if ((selectedOption < topOption) || (selectedOption > (topOption + numOptionsDisplayable)))
+  {
+    topOption = selectedOption - (numOptionsDisplayable / 2);
+  }
+
+  if (topOption < 0) topOption = 0;
+
+
+
+  fillColour(0, 0, 100, 255);
+
+  int ypos = 5;
+  for (int i = topOption; i < (topOption + numOptionsDisplayable); i++)
+  {
+    if (i == numOptions) return;
+    if ((ypos + ySeperation) > height) break;
+
+    if (i == selectedOption)
+    {
+      rectangle(0, ypos, width, fontHeight, 240, 250, 80, 255);
+      drawText(options[i], 5, ypos, 0, 0, 0);
+    }
+    else
+    {
+      drawText(options[i], 5, ypos, 255, 255, 255);
+    }
+    ypos += ySeperation;
+  }
+}
+
+void WSelectList::up()
+{
+  if (selectedOption > 0)
+  {
+    selectedOption--;
+  }
+  else
+  {
+    selectedOption = numOptions - 1;
+  }
+}
+
+void WSelectList::down()
+{
+  if (selectedOption < numOptions - 1)
+  {
+    selectedOption++;
+  }
+  else
+  {
+    selectedOption = 0;
+  }
+}
+
+void WSelectList::pageUp()
+{
+  topOption -= numOptionsDisplayable;
+  if (topOption < 0) topOption = 0;
+
+  selectedOption = topOption;
+}
+
+void WSelectList::pageDown()
+{
+  if ((topOption + numOptionsDisplayable) >= numOptions) return;
+
+  topOption += numOptionsDisplayable;
+  selectedOption = topOption;
+}
+
+int WSelectList::getTopOption()
+{
+  return topOption;
+}
+
+int WSelectList::getNumOptions()
+{
+  return numOptions;
+}
+
+int WSelectList::getBottomOption()
+{
+  int retval = topOption + numOptionsDisplayable;
+  if (retval > numOptions) return numOptions;
+  else return retval;
+}
+
+int WSelectList::getCurrentOption()
+{
+  return selectedOption;
+}
diff --git a/wselectlist.h b/wselectlist.h
new file mode 100644 (file)
index 0000000..3dca0b7
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef WSELECTLIST_H
+#define WSELECTLIST_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "box.h"
+
+class WSelectList : public Box
+{
+  public:
+    WSelectList();
+    ~WSelectList();
+    void clear();
+
+    int addOption(char* text, int selected);
+    void draw();
+
+    void down();
+    void up();
+    void pageUp();
+    void pageDown();
+
+    int getTopOption();
+    int getNumOptions();
+    int getBottomOption();
+    int getCurrentOption();
+
+    void hintSetCurrent(int index);
+    void hintSetTop(int index);
+
+  private:
+    char* options[500];
+    int numOptions;
+    int selectedOption;
+    int topOption;
+    int numOptionsDisplayable;
+};
+
+#endif
diff --git a/wsymbol.cc b/wsymbol.cc
new file mode 100644 (file)
index 0000000..4315f98
--- /dev/null
@@ -0,0 +1,563 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "wsymbol.h"
+
+UCHAR WSymbol::widths[] = { 2, 2, 4, 4, 1, 1, 3, 3, 3, 3, 3, 4, 4 };
+UCHAR WSymbol::heights[] = { 8, 8, 12, 12, 24, 4, 18, 18, 18, 18, 18, 30, 30 };
+
+UCHAR WSymbol::symbols[] = {
+
+/*
+00000000 00000011
+00000000 00001111
+00000000 00111111
+00000000 11111111
+00000011 11111111
+00001111 11111111
+00111111 11111111
+11111111 11111111
+*/
+
+0x00, 0x03,
+0x00, 0x0F,
+0x00, 0x3F,
+0x00, 0xFF,
+0x03, 0xFF,
+0x0F, 0xFF,
+0x3F, 0xFF,
+0xFF, 0xFF,
+
+/*
+11111111 00000011
+00000000 00001111
+00000000 00111111
+00000000 11111111
+00000011 11111111
+00001111 11111111
+00111111 11111111
+11111111 11111111
+*/
+
+0xFF, 0x03,
+0x00, 0x0F,
+0x00, 0x3F,
+0x00, 0xFF,
+0x03, 0xFF,
+0x0F, 0xFF,
+0x3F, 0xFF,
+0xFF, 0xFF,
+
+/*
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+*/
+
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+
+/*
+00000000 00000000 00000000 00000011
+00000000 00000000 00000000 00011111
+00000000 00000000 00000000 11111111
+00000000 00000000 00000011 11111111
+00000000 00000000 00011111 11111111
+00000000 00000000 11111111 11111111
+00000000 00000011 11111111 11111111
+00000000 00011111 11111111 11111111
+00000000 11111111 11111111 11111111
+00000011 11111111 11111111 11111111
+00011111 11111111 11111111 11111111
+11111111 11111111 11111111 11111111
+*/
+
+0x00, 0x00, 0x00, 0x03,
+0x00, 0x00, 0x00, 0x1F,
+0x00, 0x00, 0x00, 0xFF,
+0x00, 0x00, 0x03, 0xFF,
+0x00, 0x00, 0x1F, 0xFF,
+0x00, 0x00, 0xFF, 0xFF,
+0x00, 0x03, 0xFF, 0xFF,
+0x00, 0x1F, 0xFF, 0xFF,
+0x00, 0xFF, 0xFF, 0xFF,
+0x03, 0xFF, 0xFF, 0xFF,
+0x1F, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF,
+
+/*
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+00001111
+*/
+
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+
+/*
+00001111
+00001111
+00001111
+00001111
+*/
+
+0x0F,
+0x0F,
+0x0F,
+0x0F,
+
+/*
+11000000 00000000 00110000
+11000000 00000000 11110000
+11000000 00000011 11110000
+11000000 00001111 11110000
+11000000 00111111 11110000
+11000000 11111111 11110000
+11000011 11111111 11110000
+11001111 11111111 11110000
+11111111 11111111 11110000
+
+11111111 11111111 11110000
+11001111 11111111 11110000
+11000011 11111111 11110000
+11000000 11111111 11110000
+11000000 00111111 11110000
+11000000 00001111 11110000
+11000000 00000011 11110000
+11000000 00000000 11110000
+11000000 00000000 00110000
+*/
+
+0xC0, 0x00, 0x30,
+0xC0, 0x00, 0xF0,
+0xC0, 0x03, 0xF0,
+0xC0, 0x0F, 0xF0,
+0xC0, 0x3F, 0xF0,
+0xC0, 0xFF, 0xF0,
+0xC3, 0xFF, 0xF0,
+0xCF, 0xFF, 0xF0,
+0xFF, 0xFF, 0xF0,
+
+0xFF, 0xFF, 0xF0,
+0xCF, 0xFF, 0xF0,
+0xC3, 0xFF, 0xF0,
+0xC0, 0xFF, 0xF0,
+0xC0, 0x3F, 0xF0,
+0xC0, 0x0F, 0xF0,
+0xC0, 0x03, 0xF0,
+0xC0, 0x00, 0xF0,
+0xC0, 0x00, 0x30,
+
+/*
+11000000 00000000 00110000
+11110000 00000000 00110000
+11111100 00000000 00110000
+11111111 00000000 00110000
+11111111 11000000 00110000
+11111111 11110000 00110000
+11111111 11111100 00110000
+11111111 11111111 00110000
+11111111 11111111 11110000
+
+11111111 11111111 11110000
+11111111 11111111 00110000
+11111111 11111100 00110000
+11111111 11110000 00110000
+11111111 11000000 00110000
+11111111 00000000 00110000
+11111100 00000000 00110000
+11110000 00000000 00110000
+11000000 00000000 00110000
+*/
+
+0xC0, 0x00, 0x30,
+0xF0, 0x00, 0x30,
+0xFC, 0x00, 0x30,
+0xFF, 0x00, 0x30,
+0xFF, 0xC0, 0x30,
+0xFF, 0xF0, 0x30,
+0xFF, 0xFC, 0x30,
+0xFF, 0xFF, 0x30,
+0xFF, 0xFF, 0xF0,
+
+0xFF, 0xFF, 0xF0,
+0xFF, 0xFF, 0x30,
+0xFF, 0xFC, 0x30,
+0xFF, 0xF0, 0x30,
+0xFF, 0xC0, 0x30,
+0xFF, 0x00, 0x30,
+0xFC, 0x00, 0x30,
+0xF0, 0x00, 0x30,
+0xC0, 0x00, 0x30,
+
+/*
+00000000 00000000 00000000
+00000000 00000000 00000000
+00000000 00000000 00000000
+00000000 00000000 00000000
+00000000 01100000 00000000
+00000000 11110000 00000000
+00000001 11111000 00000000
+00000001 11111000 00000000
+00000011 11111100 00000000
+
+00000111 11111110 00000000
+00001111 11111111 00000000
+00011111 11111111 10000000
+00011111 11111111 10000000
+00111111 11111111 11000000
+01111111 11111111 11100000
+11111111 11111111 11110000
+00000000 00000000 00000000
+00000000 00000000 00000000
+*/
+
+0x00, 0x00, 0x00,
+0x00, 0x00, 0x00,
+0x00, 0x00, 0x00,
+0x00, 0x00, 0x00,
+0x00, 0x60, 0x00,
+0x00, 0xF0, 0x00,
+0x01, 0xF8, 0x00,
+0x01, 0xF8, 0x00,
+0x03, 0xFC, 0x00,
+
+0x07, 0xFE, 0x00,
+0x0F, 0xFF, 0x00,
+0x1F, 0xFF, 0x80,
+0x1F, 0xFF, 0x80,
+0x3F, 0xFF, 0xC0,
+0x7F, 0xFF, 0xE0,
+0xFF, 0xFF, 0xF0,
+0x00, 0x00, 0x00,
+0x00, 0x00, 0x00,
+
+/*
+00000000 00000000 00000000
+00000000 00000000 00000000
+00000000 00000000 00000000
+00000000 00000000 00000000
+11111111 11111111 11110000
+01111111 11111111 11100000
+00111111 11111111 11000000
+00011111 11111111 10000000
+00011111 11111111 10000000
+
+00001111 11111111 00000000
+00000111 11111110 00000000
+00000011 11111100 00000000
+00000001 11111000 00000000
+00000001 11111000 00000000
+00000000 11110000 00000000
+00000000 01100000 00000000
+00000000 00000000 00000000
+00000000 00000000 00000000
+*/
+
+0x00, 0x00, 0x00,
+0x00, 0x00, 0x00,
+0x00, 0x00, 0x00,
+0x00, 0x00, 0x00,
+0xFF, 0xFF, 0xF0,
+0x7F, 0xFF, 0xE0,
+0x3F, 0xFF, 0xC0,
+0x1F, 0xFF, 0x80,
+0x1F, 0xFF, 0x80,
+
+0x0F, 0xFF, 0x00,
+0x07, 0xFE, 0x00,
+0x03, 0xFC, 0x00,
+0x01, 0xF8, 0x00,
+0x01, 0xF8, 0x00,
+0x00, 0xF0, 0x00,
+0x00, 0x60, 0x00,
+0x00, 0x00, 0x00,
+0x00, 0x00, 0x00,
+
+
+/*
+11000000 00000000 00000000
+11110000 00000000 00000000
+11111100 00000000 00000000
+11111111 00000000 00000000
+11111111 11000000 00000000
+11111111 11110000 00000000
+11111111 11111100 00000000
+11111111 11111111 00000000
+11111111 11111111 11000000
+
+11111111 11111111 11000000
+11111111 11111111 00000000
+11111111 11111100 00000000
+11111111 11110000 00000000
+11111111 11000000 00000000
+11111111 00000000 00000000
+11111100 00000000 00000000
+11110000 00000000 00000000
+11000000 00000000 00000000
+*/
+
+0xC0, 0x00, 0x00,
+0xF0, 0x00, 0x00,
+0xFC, 0x00, 0x00,
+0xFF, 0x00, 0x00,
+0xFF, 0xC0, 0x00,
+0xFF, 0xF0, 0x00,
+0xFF, 0xFC, 0x00,
+0xFF, 0xFF, 0x00,
+0xFF, 0xFF, 0xC0,
+
+0xFF, 0xFF, 0xC0,
+0xFF, 0xFF, 0x00,
+0xFF, 0xFC, 0x00,
+0xFF, 0xF0, 0x00,
+0xFF, 0xC0, 0x00,
+0xFF, 0x00, 0x00,
+0xFC, 0x00, 0x00,
+0xF0, 0x00, 0x00,
+0xC0, 0x00, 0x00,
+
+/*
+11000000 00000000 00000000 00001100
+01100000 00000000 11000000 00011000
+00110000 00000001 11000000 00110000
+00011000 00000011 11000000 01100000
+00001100 00000111 11000000 11000000
+00000110 00001111 11000001 10000000
+00000011 00011111 11000011 00000000
+00000001 10111111 11000110 00000000
+00000000 11111111 11001100 00000000
+00000000 11111111 11011000 00000000
+00001111 11111111 11110000 00000000
+00001111 11111111 11100000 00000000
+00001111 11111111 11000000 00000000
+00001111 11111111 11000000 00000000
+00001111 11111111 11000000 00000000
+00001111 11111111 11000000 00000000
+00001111 11111111 11000000 00000000
+00001111 11111111 11100000 00000000
+00001111 11111111 11110000 00000000
+00000000 11111111 11011000 00000000
+00000000 11111111 11001100 00000000
+00000001 10111111 11000110 00000000
+00000011 00011111 11000011 00000000
+00000110 00001111 11000001 10000000
+00001100 00000111 11000000 11000000
+00011000 00000011 11000000 01100000
+00110000 00000001 11000000 00110000
+01100000 00000000 11000000 00011000
+11000000 00000000 00000000 00001100
+00000000 00000000 00000000 00000000
+*/
+
+0xC0, 0x00, 0x00, 0x0C,
+0x60, 0x00, 0xC0, 0x18,
+0x30, 0x01, 0xC0, 0x30,
+0x18, 0x03, 0xC0, 0x60,
+0x0C, 0x07, 0xC0, 0xC0,
+0x06, 0x0F, 0xC1, 0x80,
+0x03, 0x1F, 0xC3, 0x00,
+0x01, 0xBF, 0xC6, 0x00,
+0x00, 0xFF, 0xCC, 0x00,
+0x00, 0xFF, 0xD8, 0x00,
+0x0F, 0xFF, 0xF0, 0x00,
+0x0F, 0xFF, 0xE0, 0x00,
+0x0F, 0xFF, 0xC0, 0x00,
+0x0F, 0xFF, 0xC0, 0x00,
+0x0F, 0xFF, 0xC0, 0x00,
+0x0F, 0xFF, 0xC0, 0x00,
+0x0F, 0xFF, 0xC0, 0x00,
+0x0F, 0xFF, 0xE0, 0x00,
+0x0F, 0xFF, 0xF0, 0x00,
+0x00, 0xFF, 0xD8, 0x00,
+0x00, 0xFF, 0xCC, 0x00,
+0x01, 0xBF, 0xC6, 0x00,
+0x03, 0x1F, 0xC3, 0x00,
+0x06, 0x0F, 0xC1, 0x80,
+0x0C, 0x07, 0xC0, 0xC0,
+0x18, 0x03, 0xC0, 0x60,
+0x30, 0x01, 0xC0, 0x30,
+0x60, 0x00, 0xC0, 0x18,
+0xC0, 0x00, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00,
+
+/*
+00000000 00000000 00000000 00000000
+00000000 00000000 11000000 00000000
+00000000 00000001 11000000 00000000
+00000000 00000011 11011111 10000000
+00000000 00000111 11011111 10000000
+00000000 00001111 11000000 00000000
+00000000 00011111 11000000 00000000
+00000000 00111111 11000000 00000000
+00000000 01111111 11011111 10000000
+00000000 11111111 11011111 10000000
+00001111 11111111 11000000 00000000
+00001111 11111111 11000000 00000000
+00001111 11111111 11000000 00000000
+00001111 11111111 11011111 10000000
+00001111 11111111 11011111 10000000
+00001111 11111111 11000000 00000000
+00001111 11111111 11000000 00000000
+00001111 11111111 11000000 00000000
+00001111 11111111 11011111 10000000
+00000000 11111111 11011111 10000000
+00000000 01111111 11000000 00000000
+00000000 00111111 11000000 00000000
+00000000 00011111 11000000 00000000
+00000000 00001111 11011111 10000000
+00000000 00000111 11011111 10000000
+00000000 00000011 11000000 00000000
+00000000 00000001 11000000 00000000
+00000000 00000000 11000000 00000000
+00000000 00000000 00000000 00000000
+00000000 00000000 00000000 00000000
+*/
+
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xC0, 0x00,
+0x00, 0x01, 0xC0, 0x00,
+0x00, 0x03, 0xDF, 0x80,
+0x00, 0x07, 0xDF, 0x80,
+0x00, 0x0F, 0xC0, 0x00,
+0x00, 0x1F, 0xC0, 0x00,
+0x00, 0x3F, 0xC0, 0x00,
+0x00, 0x7F, 0xDF, 0x80,
+0x00, 0xFF, 0xDF, 0x80,
+0x0F, 0xFF, 0xC0, 0x00,
+0x0F, 0xFF, 0xC0, 0x00,
+0x0F, 0xFF, 0xC0, 0x00,
+0x0F, 0xFF, 0xDF, 0x80,
+0x0F, 0xFF, 0xDF, 0x80,
+0x0F, 0xFF, 0xC0, 0x00,
+0x0F, 0xFF, 0xC0, 0x00,
+0x0F, 0xFF, 0xC0, 0x00,
+0x0F, 0xFF, 0xDF, 0x80,
+0x00, 0xFF, 0xDF, 0x80,
+0x00, 0x7F, 0xC0, 0x00,
+0x00, 0x3F, 0xC0, 0x00,
+0x00, 0x1F, 0xC0, 0x00,
+0x00, 0x0F, 0xDF, 0x80,
+0x00, 0x07, 0xDF, 0x80,
+0x00, 0x03, 0xC0, 0x00,
+0x00, 0x01, 0xC0, 0x00,
+0x00, 0x00, 0xC0, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00
+
+
+};
+
+WSymbol::WSymbol()
+{
+  nextSymbol = 0;
+}
+
+void WSymbol::draw()
+{
+  int offset = 0;
+  for(int i = 0; i < nextSymbol; i++)
+  {
+    offset += (widths[i]) * heights[i];
+  }
+
+  UCHAR* base = symbols + offset;
+  int widthBytes = widths[nextSymbol];
+  int widthBits = widthBytes * 8;
+  int height = heights[nextSymbol];
+
+  int x, y, bytesIn, bitsIn;
+
+  for (y = 0; y < height; y++)
+  {
+    for (x = 0; x < widthBits; x++)
+    {
+      bytesIn = (y * widthBytes) + (int)(x / 8);
+      bitsIn = x % 8;
+
+      if ((base[bytesIn] >> (7 - bitsIn)) & 0x01)
+      {
+        drawPixel(x, y, 0xFFFFFFFF);
+      }
+    }
+  }
+}
diff --git a/wsymbol.h b/wsymbol.h
new file mode 100644 (file)
index 0000000..c7e66ea
--- /dev/null
+++ b/wsymbol.h
@@ -0,0 +1,55 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP 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.
+
+    VOMP 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 VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef WSYMBOL_H
+#define WSYMBOL_H
+
+#include "defines.h"
+#include "box.h"
+
+class WSymbol : public Box
+{
+  public:
+    WSymbol();
+
+    void draw();
+    UCHAR nextSymbol;
+
+    const static UCHAR VOLUME = 0;
+    const static UCHAR TEST = 1;
+    const static UCHAR TEST2 = 2;
+    const static UCHAR VOLUME2 = 3;
+    const static UCHAR VOLBAR = 4;
+    const static UCHAR VOLDOT = 5;
+    const static UCHAR SKIPBACK = 6;
+    const static UCHAR SKIPFORWARD = 7;
+    const static UCHAR UP = 8;
+    const static UCHAR DOWN = 9;
+    const static UCHAR PLAY = 10;
+    const static UCHAR MUTE = 11;
+    const static UCHAR UNMUTE = 12;
+
+  private:
+    static UCHAR symbols[];
+    static UCHAR widths[];
+    static UCHAR heights[];
+};
+
+#endif