[Pkg-wmaker-commits] [wmtv] 06/48: Imported Upstream version 0.6.5
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Mon Feb 1 20:13:20 UTC 2016
This is an automated email from the git hooks/post-receive script.
dtorrance-guest pushed a commit to branch master
in repository wmtv.
commit 5a9d5e7fe717055f237e7ec058c9d5d3e2319237
Author: Doug Torrance <dtorrance at piedmont.edu>
Date: Sat Jan 30 21:27:56 2016 -0500
Imported Upstream version 0.6.5
---
CHANGES | 59 ++
COPYING | 339 ++++++++++
CREDITS | 4 +
Makefile | 26 +
README | 185 ++++++
src/channels.h | 333 ++++++++++
src/wmgeneral/list.c | 169 +++++
src/wmgeneral/list.h | 59 ++
src/wmgeneral/misc.c | 164 +++++
src/wmgeneral/misc.h | 9 +
src/wmgeneral/wmgeneral.c | 419 ++++++++++++
src/wmgeneral/wmgeneral.h | 62 ++
src/wmtv-master.xpm | 143 ++++
src/wmtv.c | 1580 +++++++++++++++++++++++++++++++++++++++++++++
wmtvrc.sample | 13 +
15 files changed, 3564 insertions(+)
diff --git a/CHANGES b/CHANGES
new file mode 100644
index 0000000..a0bb53b
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,59 @@
+Version 0.6.5
+-------------
+Date - 25/4/99
+ - Fixed fullscreen freeze bug
+ - Change mouse button assignments for launch of external application
+ - Settings for fullscreen mode in config file
+
+Version 0.6.3b
+--------------
+Date - 22/4/99
+ - Releases video device when TV is turned off
+ - Support for both external TV application and inbuilt fullscreen
+ - Auto edit of config file for finetune offsets.
+ - Other bug fixes
+
+Version 0.6.2b
+--------------
+Date - 25/3/99
+ - Added support for fine tune parameters in config file
+ - Some keyboard bindings in fullscreen
+ - Mute feature
+ - Misc bug fixes
+
+Version 0.6.1b
+--------------
+Date - 17/3/99
+Changes - Fixed CPU utilisation hog bug.
+ - Should now take up less than 1% CPU
+ - Fixed hanging state for executables
+ - Other minor bugfixes
+
+Version 0.6b
+------------
+Date - 15/3/99
+Changes - Full Screen Support!
+ - Changed preset displays for Composite and S-Video
+ - Changed command line parsing format
+ - Miscellaneous minor bug fixes
+
+Version 0.5.2b
+--------------
+Date - 3/3/99
+Changes - TV Source bug fixed - Composite and S-Video inputs should work
+ properly now.
+ - Now supports editing of config file after startup of wmtv.
+ (ie. wmtv's config file will be reread when the TV is turned On)
+ - Fixed TV Off mode. Clicking and holding down more than 3 seconds
+ during TV On mode or Set Tuner mode would turn wmtv off.
+
+Version 0.5.1b
+--------------
+Date - 26/2/99
+Changes - Supports 8/16/24/32 depths as opposed to the first version
+ which only runs on 16 bit displays.
+
+Version 0.5b
+------------
+Date - 25/2/99
+Changes - Initial Public Beta Release
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: 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) 19yy <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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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/CREDITS b/CREDITS
new file mode 100644
index 0000000..097d4d6
--- /dev/null
+++ b/CREDITS
@@ -0,0 +1,4 @@
+Contributors to wmtv:
+
+John Cavan <john.cavan at sympatico.ca>
+Daniel Kollar <kollar at heaven.riednet.wh.tu-darmstadt.de>
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..0e8407b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,26 @@
+#
+# Makefile for wmtv
+#
+INCDIR = -I/usr/X11R6/include
+LIBDIR = -L/usr/X11R6/lib
+LIBS = -lXpm -lXext -lX11 -lXxf86dga -lXxf86vm
+OBJS = src/wmtv.o \
+ src/wmgeneral/wmgeneral.o \
+
+.c.o:
+ cc -c -O2 -Wall -D$(shell echo `uname -s`) $< -o $*.o $(INCDIR)
+
+all: wmtv
+
+wmtv: $(OBJS)
+ cc -o wmtv $^ $(LIBDIR) $(LIBS)
+
+install:: all
+ install -s -m 4755 -o root wmtv /usr/X11R6/bin
+ install -m 0644 -o root -g root wmtvrc.sample /etc/wmtvrc
+
+clean:
+ for i in $(OBJS) ; do \
+ rm -f $$i; \
+ done
+ rm -f wmtv
diff --git a/README b/README
new file mode 100644
index 0000000..ce7f8c6
--- /dev/null
+++ b/README
@@ -0,0 +1,185 @@
+=========================================================
+ WMTV - WindowMaker TV
+ <wliang at tartarus.uwa.edu.au>
+=========================================================
+
+Version : 0.6.5
+Release Date : 25th April 1999
+
+
+Description
+===========
+WMTV is a WindowMaker dock.app that controls TV Cards which are supported under the Linux Kernel 2.2.x series (mainly for cards based on BrookTree BT848/848a/849a/878/879 chipsets: There are lots of cards out there which uses these chipsets such as the Hauppauge WinTV, Aimslab VideoExtreme, miroVIDEO PCTV, AverMedia TVPhone, Spirit TV, MagicXPress TView, Teppro TEV, etc).
+
+
+Installation
+============
+root/setuid root required to run this program.
+
+2) su
+2) make install
+3) copy wmtvrc.sample to ~/.wmtvrc
+4) configure wmtv by editing ~/.wmtvrc or /etc/wmtvrc ( the former takes precedence)
+
+Note: Dock the application before switching the TV On.
+
+
+Features
+========
+WMTV is "Just another gadget(tm)". A miniature sized television screen which sits on your WindowMaker dock. However, it'll become a full featured television application in future major releases.
+
+Currently supported:
+ - Channel Presets
+ - TV Modes - PAL/Secam/NTSC
+ - FineTuning (Television source) - writes to config file now
+ - Scanning of TV Stations (Television source)
+ - External TV application support
+ - All video sources (Television/S-Video/CompositeX) depending on your card
+ - 8/16/24/32 bit displays
+ - Modification of config file after WMTV is executed
+ (Turn Off and Turn On again to reinitialise config file)
+ - Full Screen display!
+ - Icon should be of size 64x64
+
+Button map:
+
+ [ < ] [ > ] [ 0 ]
+
+ <1> <2> <3>
+
+Tips:
+There are 3 modes of operation on this applications.
+You can cycle through the 3 modes by clicking on the right most button <3> repeatedly.
+The 3 modes are described below:
+
+ On mode
+ ---------
+ Clicking on the rightmost button <3> for the first time (after the start of WMTV) would turn TV on. During this mode, the left <1> and right <2> buttons are used to change preset channels which has been defined in your config file. Left button to move down 1 channel and Right button to move up one
+ channel.
+
+ Tune mode
+ ---------
+ Clicking again on button <3> after On mode would bring WMTV into tune mode. During this mode, the left <1> and right <2> buttons have two purposes
+ individually. Left clicking on the left <1> or right <2> buttons would
+ perform scans of channels. Scanning will stop when there is a strong signal strength. Right clicking on the left <1> or right <2> button would fine
+ tune the current frequency. After tuning, clicking on button <3> would set the fine tuned offset into your config file and bring you back into "On mode".
+
+ Off mode
+ --------
+ Holding down button <3> for about 3 seconds from any of the two modes
+ described above, would turn the TV off.
+
+Right clicking once on the TV Screen would mute/unmute the audio.
+
+Double clicking LEFT mouse button on the TV Screen would launch your favorite TV application when specified with --exe <filename> option in the command line.
+If the external application is not set, It'll automatically switch to the build in full screen mode.
+Double clicking the MIDDLE mouse button on the TV Screen would bring you into the built in full screen mode.
+
+To launch an external application:
+
+foo at bar > wmtv --exe /usr/X11R6/bin/xawtv # example.
+or
+foo at bar > wmtv -e /usr/X11R6/bin/xawtv
+
+If you do not specify any program to be launched during startup of WMTV,
+double clicking on the TV Screen would launch the inbuilt full screen feature.
+Make sure you have a 640x480 Modeline defined in your XF86Config file.
+
+Full Screen Mode:
+ Single click on any mouse button will return to initial screen.
+
+ Keyboard functions
+ ------------------
+ Up - Switch preset channels up.
+ Down - Switch preset channels down.
+ Right - Volume up.
+ Left - Volume down.
+ Escape - Return to initial screen.
+ m - mute/unmute audio.
+
+Configuration file
+==================
+This section describes on how to configure WMTV's configuration file.
+Your configuration file is located in your home directory as ".wmtvrc".
+
+Excerpt from a sample config file:
+/*-----------------------
+
+source = Television
+freqnorm = pal-australia
+maxpreset = 7
+mode = pal
+fullscreen = 640x480
+
+[channel]
+2
+7
+9
+10
+32 (50)
+SE11
+S21
+
+-------------------------*/
+
+Settings
+--------
+source = {Television|CompositeX|S-Video} (X is an integer)
+
+freqnorm = {ntsc-bcast|ntsc-cable|ntsc-cable-hrc|ntsc-bcast-jp|ntsc-cable-jp|pal-europe|pal-europe-east|pal-italy|pal-newzealand|pal-australia|pal-ireland}
+
+maxpreset = integer (maximum channel presets)
+
+mode = {pal|ntsc|secam}
+
+fullscreen = {widthxheight}
+
+[channel]
+choose a total of <maxpreset> from the below channels.
+separate it with a new line as in the sample config file above.
+{
+ E2|E3|E4|
+ S01|S02|S03|
+ R1|R2|R3|R4|R5|
+ SE1|SE2|SE3|SE4|SE5|SE6|SE7|SE8|SE9|SE10|
+ E5|E6|E7|E8|E9|E10|E11|E12|
+ R6|R7|R8|R9|R10|R11|R12|
+ SE11|SE12|SE13|SE14|SE15|SE16|SE17|SE18|SE19|SE20|
+ S21|S22|S23|S24|S25|S26|S27|S28|S29|S30|S31|S32|S33|S34|S35|S36|S37|S38|S39|S40|S41
+ T7|T8|T9|T10|T11|T12|T13|T14|
+ 1 - 125
+}
+finetune parameters could be added spaced after the channel name above in a bracket.
+for example:
+ 32 (50) # channel 32 plus 50
+
+ or
+
+ SE11 (-10) # channel SE11 minus 10
+
+
+TODO
+====
+
+- Image Capture
+- On Screen Display (OSD)
+- Other controls
+- Advance image clippings
+- Video Capture
+- Other misc features
+
+
+BUGS
+====
+Ask flik. Bug me if you've found any.
+
+
+NOTE
+====
+Please refer to COPYING for licensing info.
+This program might not work on your system and there is no way I will be held
+responsible for anything.
+This does to your system including loss of data, loss of uptime, loss of hair and etc.
+
+Please report any bugs/comments/feedbacks to <wliang at tartarus.uwa.edu.au>
+Please visit http://www.student.uwa.edu.au/~wliang for updates on WMTV.
diff --git a/src/channels.h b/src/channels.h
new file mode 100644
index 0000000..72af0fd
--- /dev/null
+++ b/src/channels.h
@@ -0,0 +1,333 @@
+/*
+ * Worldwide channel/frequency list
+ *
+ * Nathan Laredo (laredo at broked.net)
+ * Minor additions by Wee Liang (wliang at tartarus.uwa.edu.au)
+ *
+ * Frequencies are given in kHz
+ */
+#define NTSC_AUDIO_CARRIER 4500
+#define PAL_AUDIO_CARRIER_I 6000
+#define PAL_AUDIO_CARRIER_BGHN 5500
+#define PAL_AUDIO_CARRIER_MN 4500
+#define PAL_AUDIO_CARRIER_D 6500
+#define SEACAM_AUDIO_DKK1L 6500
+#define SEACAM_AUDIO_BG 5500
+/* NICAM 728 32-kHz, 14-bit digital stereo audio is transmitted in 1ms frames
+ containing 8 bits frame sync, 5 bits control, 11 bits additional data, and
+ 704 bits audio data. The bit rate is reduced by transmitting only 10 bits
+ plus parity of each 14 bit sample, the largest sample in a frame determines
+ which 10 bits are transmitted. The parity bits for audio samples also
+ specify the scaling factor used for that channel during that frame. The
+ companeded audio data is interleaved to reduce the influence of dropouts
+ and the whole frame except for sync bits is scrambled for spectrum shaping.
+ Data is modulated using QPSK, at below following subcarrier freqs */
+#define NICAM728_PAL_BGH 5850
+#define NICAM728_PAL_I 6552
+
+/* COMPREHENSIVE LIST OF FORMAT BY COUNTRY
+ (M) NTSC used in:
+ Antigua, Aruba, Bahamas, Barbados, Belize, Bermuda, Bolivia, Burma,
+ Canada, Chile, Colombia, Costa Rica, Cuba, Curacao, Dominican Republic,
+ Ecuador, El Salvador, Guam Guatemala, Honduras, Jamaica, Japan,
+ South Korea, Mexico, Montserrat, Myanmar, Nicaragua, Panama, Peru,
+ Philippines, Puerto Rico, St Christopher and Nevis, Samoa, Suriname,
+ Taiwan, Trinidad/Tobago, United States, Venezuela, Virgin Islands
+ (B) PAL used in:
+ Albania, Algeria, Australia, Austria, Bahrain, Bangladesh, Belgium,
+ Bosnia-Herzegovinia, Brunei Darussalam, Cambodia, Cameroon, Croatia,
+ Cyprus, Denmark, Egypt, Ethiopia, Equatorial Guinea, Finland, Germany,
+ Ghana, Gibraltar, Greenland, Iceland, India, Indonesia, Israel, Italy,
+ Jordan, Kenya, Kuwait, Liberia, Libya, Luxembourg, Malaysa, Maldives,
+ Malta, Nepal, Netherlands, New Zeland, Nigeria, Norway, Oman, Pakistan,
+ Papua New Guinea, Portugal, Qatar, Sao Tome and Principe, Saudi Arabia,
+ Seychelles, Sierra Leone, Singapore, Slovenia, Somali, Spain,
+ Sri Lanka, Sudan, Swaziland, Sweden, Switzeland, Syria, Thailand,
+ Tunisia, Turkey, Uganda, United Arab Emirates, Yemen
+ (N) PAL used in: (Combination N = 4.5MHz audio carrier, 3.58MHz burst)
+ Argentina (Combination N), Paraguay, Uruguay
+ (M) PAL (525/60, 3.57MHz burst) used in:
+ Brazil
+ (G) PAL used in:
+ Albania, Algeria, Austria, Bahrain, Bosnia/Herzegovinia, Cambodia,
+ Cameroon, Croatia, Cyprus, Denmark, Egypt, Ethiopia, Equatorial Guinea,
+ Finland, Germany, Gibraltar, Greenland, Iceland, Israel, Italy, Jordan,
+ Kenya, Kuwait, Liberia, Libya, Luxembourg, Malaysia, Monaco,
+ Mozambique, Netherlands, New Zealand, Norway, Oman, Pakistan,
+ Papa New Guinea, Portugal, Qatar, Romania, Sierra Leone, Singapore,
+ Slovenia, Somalia, Spain, Sri Lanka, Sudan, Swaziland, Sweeden,
+ Switzerland, Syria, Thailand, Tunisia, Turkey, United Arab Emirates,
+ Yemen, Zambia, Zimbabwe
+ (D) PAL used in:
+ China, North Korea, Romania, Czech Republic
+ (H) PAL used in:
+ Belgium
+ (I) PAL used in:
+ Angola, Botswana, Gambia, Guinea-Bissau, Hong Kong, Ireland, Lesotho,
+ Malawi, Nambia, Nigeria, South Africa, Tanzania, United Kingdom,
+ Zanzibar
+ (B) SECAM used in:
+ Djibouti, Greece, Iran, Iraq, Lebanon, Mali, Mauritania, Mauritus,
+ Morocco
+ (D) SECAM used in:
+ Afghanistan, Armenia, Azerbaijan, Belarus, Bulgaria,
+ Estonia, Georgia, Hungary, Zazakhstan, Lithuania, Mongolia, Moldova,
+ Poland, Russia, Slovak Republic, Ukraine, Vietnam
+ (G) SECAM used in:
+ Greecem Iran, Iraq, Mali, Mauritus, Morocco, Saudi Arabia
+ (K) SECAM used in:
+ Armenia, Azerbaijan, Bulgaria, Estonia, Georgia,
+ Hungary, Kazakhstan, Lithuania, Madagascar, Moldova, Poland, Russia,
+ Slovak Republic, Ukraine, Vietnam
+ (K1) SECAM used in:
+ Benin, Burkina Faso, Burundi, Chad, Cape Verde, Central African
+ Republic, Comoros, Congo, Gabon, Madagascar, Niger, Rwanda, Senegal,
+ Togo, Zaire
+ (L) SECAM used in:
+ France
+*/
+struct gentab {
+ int cind;
+ char *cname;
+};
+
+struct freqlist {
+ char name[4];
+ int freq[12];
+};
+
+struct freqlist tvtuner[] = {
+/* CH US-TV US-CATV US-HRC JP-TV JP-CATV EUROPE EUR-E ITALY NZ AU UHF_GHI */
+{"E2", { 0, 0, 0, 0, 0, 48250, 0, 0, 0, 0, 0}},
+{"E3", { 0, 0, 0, 0, 0, 55250, 0, 0, 0, 0, 0}},
+{"E4", { 0, 0, 0, 0, 0, 62250, 0, 0, 0, 0, 0}},
+
+{"S01", { 0, 0, 0, 0, 0, 69250, 0, 0, 0, 0, 0}},
+{"S02", { 0, 0, 0, 0, 0, 76250, 0, 0, 0, 0, 0}},
+{"S03", { 0, 0, 0, 0, 0, 83250, 0, 0, 0, 0, 0}},
+
+{"R1", { 0, 0, 0, 0, 0, 0, 49750, 0, 0, 0, 0}},
+{"R2", { 0, 0, 0, 0, 0, 0, 59250, 0, 0, 0, 0}},
+{"R3", { 0, 0, 0, 0, 0, 0, 77250, 0, 0, 0, 0}},
+{"R4", { 0, 0, 0, 0, 0, 0, 84250, 0, 0, 0, 0}},
+{"R5", { 0, 0, 0, 0, 0, 0, 93250, 0, 0, 0, 0}},
+
+{"SE1", { 0, 0, 0, 0, 0, 105250, 105250, 0, 0, 0, 0}},
+{"SE2", { 0, 0, 0, 0, 0, 112250, 112250, 0, 0, 0, 0}},
+{"SE3", { 0, 0, 0, 0, 0, 119250, 119250, 0, 0, 0, 0}},
+{"SE4", { 0, 0, 0, 0, 0, 126250, 126250, 0, 0, 0, 0}},
+{"SE5", { 0, 0, 0, 0, 0, 133250, 133250, 0, 0, 0, 0}},
+{"SE6", { 0, 0, 0, 0, 0, 140250, 140250, 0, 0, 0, 0}},
+{"SE7", { 0, 0, 0, 0, 0, 147250, 147250, 0, 0, 0, 0}},
+{"SE8", { 0, 0, 0, 0, 0, 154250, 154250, 0, 0, 0, 0}},
+{"SE9", { 0, 0, 0, 0, 0, 161250, 161250, 0, 0, 0, 0}},
+{"SE10",{ 0, 0, 0, 0, 0, 168250, 168250, 0, 0, 0, 0}},
+
+{"E5", { 0, 0, 0, 0, 0, 175250, 0, 0, 0, 0, 0}},
+{"E6", { 0, 0, 0, 0, 0, 182250, 0, 0, 0, 0, 0}},
+{"E7", { 0, 0, 0, 0, 0, 189250, 0, 0, 0, 0, 0}},
+{"E8", { 0, 0, 0, 0, 0, 196250, 0, 0, 0, 0, 0}},
+{"E9", { 0, 0, 0, 0, 0, 203250, 0, 0, 0, 0, 0}},
+{"E10", { 0, 0, 0, 0, 0, 210250, 0, 0, 0, 0, 0}},
+{"E11", { 0, 0, 0, 0, 0, 217250, 0, 0, 0, 0, 0}},
+{"E12", { 0, 0, 0, 0, 0, 224250, 0, 0, 0, 0, 0}},
+
+{"R6", { 0, 0, 0, 0, 0, 0, 175250, 0, 0, 0, 0}},
+{"R7", { 0, 0, 0, 0, 0, 0, 183250, 0, 0, 0, 0}},
+{"R8", { 0, 0, 0, 0, 0, 0, 191250, 0, 0, 0, 0}},
+{"R9", { 0, 0, 0, 0, 0, 0, 199250, 0, 0, 0, 0}},
+{"R10", { 0, 0, 0, 0, 0, 0, 207250, 0, 0, 0, 0}},
+{"R11", { 0, 0, 0, 0, 0, 0, 215250, 0, 0, 0, 0}},
+{"R12", { 0, 0, 0, 0, 0, 0, 223250, 0, 0, 0, 0}},
+
+{"SE11",{ 0, 0, 0, 0, 0, 231250, 231250, 0, 0, 0, 0}},
+{"SE12",{ 0, 0, 0, 0, 0, 238250, 238250, 0, 0, 0, 0}},
+{"SE13",{ 0, 0, 0, 0, 0, 245250, 245250, 0, 0, 0, 0}},
+{"SE14",{ 0, 0, 0, 0, 0, 252250, 252250, 0, 0, 0, 0}},
+{"SE15",{ 0, 0, 0, 0, 0, 259250, 259250, 0, 0, 0, 0}},
+{"SE16",{ 0, 0, 0, 0, 0, 266250, 266250, 0, 0, 0, 0}},
+{"SE17",{ 0, 0, 0, 0, 0, 273250, 273250, 0, 0, 0, 0}},
+{"SE18",{ 0, 0, 0, 0, 0, 280250, 280250, 0, 0, 0, 0}},
+{"SE19",{ 0, 0, 0, 0, 0, 287250, 287250, 0, 0, 0, 0}},
+{"SE20",{ 0, 0, 0, 0, 0, 294250, 294250, 0, 0, 0, 0}},
+
+{"S21", { 0, 0, 0, 0, 0, 303250, 303250, 0, 0, 0, 0}},
+{"S22", { 0, 0, 0, 0, 0, 311250, 311250, 0, 0, 0, 0}},
+{"S23", { 0, 0, 0, 0, 0, 319250, 319250, 0, 0, 0, 0}},
+{"S24", { 0, 0, 0, 0, 0, 327250, 327250, 0, 0, 0, 0}},
+{"S25", { 0, 0, 0, 0, 0, 335250, 335250, 0, 0, 0, 0}},
+{"S26", { 0, 0, 0, 0, 0, 343250, 343250, 0, 0, 0, 0}},
+{"S27", { 0, 0, 0, 0, 0, 351250, 351250, 0, 0, 0, 0}},
+{"S28", { 0, 0, 0, 0, 0, 359250, 359250, 0, 0, 0, 0}},
+{"S29", { 0, 0, 0, 0, 0, 367250, 367250, 0, 0, 0, 0}},
+{"S30", { 0, 0, 0, 0, 0, 375250, 375250, 0, 0, 0, 0}},
+{"S31", { 0, 0, 0, 0, 0, 383250, 383250, 0, 0, 0, 0}},
+{"S32", { 0, 0, 0, 0, 0, 391250, 391250, 0, 0, 0, 0}},
+{"S33", { 0, 0, 0, 0, 0, 399250, 399250, 0, 0, 0, 0}},
+{"S34", { 0, 0, 0, 0, 0, 407250, 407250, 0, 0, 0, 0}},
+{"S35", { 0, 0, 0, 0, 0, 415250, 415250, 0, 0, 0, 0}},
+{"S36", { 0, 0, 0, 0, 0, 423250, 423250, 0, 0, 0, 0}},
+{"S37", { 0, 0, 0, 0, 0, 431250, 431250, 0, 0, 0, 0}},
+{"S38", { 0, 0, 0, 0, 0, 439250, 439250, 0, 0, 0, 0}},
+{"S39", { 0, 0, 0, 0, 0, 447250, 447250, 0, 0, 0, 0}},
+{"S40", { 0, 0, 0, 0, 0, 455250, 455250, 0, 0, 0, 0}},
+{"S41", { 0, 0, 0, 0, 0, 463250, 463250, 0, 0, 0, 0}},
+
+{"0", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 46250, 45750}},
+{"1", { 0, 73250, 72000, 91250, 0, 0, 0, 0, 45250, 57250, 53750}},
+{"2", { 55250, 55250, 54000, 97250, 0, 0, 0, 53750, 55250, 64250, 61750}},
+{"3", { 61250, 61250, 60000, 103250, 0, 0, 0, 62250, 62250, 86250, 175250}},
+{"4", { 67250, 67250, 66000, 171250, 0, 0, 0, 82250, 175250, 95250, 183250}},
+{"5", { 77250, 77250, 78000, 177250, 0, 0, 0, 175250, 182250, 102250, 191250}},
+{"5A", { 0, 0, 138250, 0, 0, 0, 0, 0, 138250, 0}},
+{"6", { 83250, 83250, 84000, 183250, 0, 0, 0, 183750, 189250, 175250, 199250}},
+{"7", {175250, 175250, 174000, 189250, 0, 0, 0, 192250, 196250, 182250, 207250}},
+{"8", {181250, 181250, 180000, 193250, 0, 0, 0, 201250, 203250, 189250, 215250}},
+{"9", {187250, 187250, 186000, 199250, 0, 0, 0, 210250, 210250, 196250, 0}},
+{"10", {193250, 193250, 192000, 205250, 0, 0, 0, 210250, 217250, 209250, 0}},
+{"11", {199250, 199250, 198000, 211250, 0, 0, 0, 217250, 0, 216250, 0}},
+{"12", {205250, 205250, 204000, 217250, 0, 0, 0, 224250, 0, 0, 0}},
+
+{"13", {211250, 211250, 210000, 0, 109250, 0, 0, 0, 0, 0, 0}},
+{"14", {471250, 121250, 120000, 0, 115250, 0, 0, 0, 0, 0, 0}},
+{"15", {477250, 127250, 126000, 0, 121250, 0, 0, 0, 0, 0, 0}},
+{"16", {483250, 133250, 132000, 0, 127250, 0, 0, 0, 0, 0, 0}},
+{"17", {489250, 139250, 138000, 0, 133250, 0, 0, 0, 0, 0, 0}},
+{"18", {495250, 145250, 144000, 0, 139250, 0, 0, 0, 0, 0, 0}},
+{"19", {501250, 151250, 150000, 0, 145250, 0, 0, 0, 0, 0, 0}},
+{"20", {507250, 157250, 156000, 0, 151250, 0, 0, 0, 0, 0, 0}},
+
+{"21", {513250, 163250, 162000, 0, 157250, 471250, 471250, 0, 0, 0, 471250}},
+{"22", {519250, 169250, 168000, 0, 165250, 479250, 479250, 0, 0, 0, 479250}},
+{"23", {525250, 217250, 216000, 0, 223250, 487250, 487250, 0, 0, 0, 487250}},
+{"24", {531250, 223250, 222000, 0, 231250, 495250, 495250, 0, 0, 0, 495250}},
+{"25", {537250, 229250, 228000, 0, 237250, 503250, 503250, 0, 0, 0, 503250}},
+{"26", {543250, 235250, 234000, 0, 243250, 511250, 511250, 0, 0, 0, 511250}},
+{"27", {549250, 241250, 240000, 0, 249250, 519250, 519250, 0, 0, 0, 519250}},
+{"28", {555250, 247250, 246000, 0, 253250, 527250, 527250, 0, 0, 527250, 527250}},
+{"29", {561250, 253250, 252000, 0, 259250, 535250, 535250, 0, 0, 534250, 535250}},
+{"30", {567250, 259250, 258000, 0, 265250, 543250, 543250, 0, 0, 541250, 543250}},
+{"31", {573250, 265250, 264000, 0, 271250, 551250, 551250, 0, 0, 548250, 551250}},
+{"32", {579250, 271250, 270000, 0, 277250, 559250, 559250, 0, 0, 555250, 559250}},
+{"33", {585250, 277250, 276000, 0, 283250, 567250, 567250, 0, 0, 562250, 567250}},
+{"34", {591250, 283250, 282000, 0, 289250, 575250, 575250, 0, 0, 569250, 575250}},
+{"35", {597250, 289250, 288000, 0, 295250, 583250, 583250, 0, 0, 576250, 583250}},
+{"36", {603250, 295250, 294000, 0, 301250, 591250, 591250, 0, 0, 0, 591250}},
+{"37", {609250, 301250, 300000, 0, 307250, 599250, 599250, 0, 0, 0, 599250}},
+{"38", {615250, 307250, 306000, 0, 313250, 607250, 607250, 0, 0, 0, 607250}},
+{"39", {621250, 313250, 312000, 0, 319250, 615250, 615250, 0, 0, 604250, 615250}},
+{"40", {627250, 319250, 318000, 0, 325250, 623250, 623250, 0, 0, 611250, 623250}},
+{"41", {633250, 325250, 324000, 0, 331250, 631250, 631250, 0, 0, 618250, 631250}},
+{"42", {639250, 331250, 330000, 0, 337250, 639250, 639250, 0, 0, 625250, 639250}},
+{"43", {645250, 337250, 336000, 0, 343250, 647250, 647250, 0, 0, 632250, 647250}},
+{"44", {651250, 343250, 342000, 0, 349250, 655250, 655250, 0, 0, 639250, 655250}},
+{"45", {657250, 349250, 348000, 663250, 355250, 663250, 663250, 0, 0, 646250, 663250}},
+{"46", {663250, 355250, 354000, 669250, 361250, 671250, 671250, 0, 0, 653250, 671250}},
+{"47", {669250, 361250, 360000, 675250, 367250, 679250, 679250, 0, 0, 660250, 679250}},
+{"48", {675250, 367250, 366000, 681250, 373250, 687250, 687250, 0, 0, 667250, 687250}},
+{"49", {681250, 373250, 372000, 687250, 379250, 695250, 695250, 0, 0, 674250, 695250}},
+{"50", {687250, 379250, 378000, 693250, 385250, 703250, 703250, 0, 0, 681250, 703250}},
+{"51", {693250, 385250, 384000, 699250, 391250, 711250, 711250, 0, 0, 688250, 711250}},
+{"52", {699250, 391250, 390000, 705250, 397250, 719250, 719250, 0, 0, 695250, 719250}},
+{"53", {705250, 397250, 396000, 711250, 403250, 727250, 727250, 0, 0, 702250, 727250}},
+{"54", {711250, 403250, 402000, 717250, 409250, 735250, 735250, 0, 0, 709250, 735250}},
+{"55", {717250, 409250, 408000, 723250, 415250, 743250, 743250, 0, 0, 716250, 743250}},
+{"56", {723250, 415250, 414000, 729250, 421250, 751250, 751250, 0, 0, 723250, 751250}},
+{"57", {729250, 421250, 420000, 735250, 427250, 759250, 759250, 0, 0, 730250, 759250}},
+{"58", {735250, 427250, 426000, 741250, 433250, 767250, 767250, 0, 0, 737250, 767250}},
+{"59", {741250, 433250, 432000, 747250, 439250, 775250, 775250, 0, 0, 744250, 775250}},
+{"60", {747250, 439250, 438000, 753250, 445250, 783250, 783250, 0, 0, 751250, 783250}},
+{"61", {753250, 445250, 444000, 759250, 451250, 791250, 791250, 0, 0, 758250, 791250}},
+{"62", {759250, 451250, 450000, 765250, 457250, 799250, 799250, 0, 0, 765250, 799250}},
+{"63", {765250, 457250, 456000, 0, 463250, 807250, 807250, 0, 0, 772250, 807250}},
+{"64", {771250, 463250, 462000, 0, 0, 815250, 815250, 0, 0, 779250, 815250}},
+{"65", {777250, 469250, 468000, 0, 0, 823250, 823250, 0, 0, 786250, 823250}},
+{"66", {783250, 475250, 474000, 0, 0, 831250, 831250, 0, 0, 793250, 831250}},
+{"67", {789250, 481250, 480000, 0, 0, 839250, 839250, 0, 0, 800250, 839250}},
+{"68", {795250, 487250, 486000, 0, 0, 847250, 847250, 0, 0, 807250, 847250}},
+{"69", {801250, 493250, 492000, 0, 0, 855250, 855250, 0, 0, 814250, 855250}},
+
+{"70", {807250, 499250, 498000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"71", {813250, 505250, 504000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"72", {819250, 511250, 510000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"73", {825250, 517250, 516000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"74", {831250, 523250, 522000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"75", {837250, 529250, 528000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"76", {843250, 535250, 534000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"77", {849250, 541250, 540000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"78", {855250, 547250, 546000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"79", {861250, 553250, 552000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"80", {867250, 559250, 558000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"81", {873250, 565250, 564000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"82", {879250, 571250, 570000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"83", {885250, 577250, 576000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"84", { 0, 583250, 582000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"85", { 0, 589250, 588000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"86", { 0, 595250, 594000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"87", { 0, 601250, 600000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"88", { 0, 607250, 606000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"89", { 0, 613250, 612000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"90", { 0, 619250, 618000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"91", { 0, 625250, 624000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"92", { 0, 631250, 630000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"93", { 0, 637250, 636000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"94", { 0, 643250, 642000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"95", { 0, 91250, 900000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"96", { 0, 97250, 960000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"97", { 0, 103250, 102000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"98", { 0, 109250, 108000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"99", { 0, 115250, 114000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"100", { 0, 649250, 648000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"101", { 0, 655250, 654000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"102", { 0, 661250, 660000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"103", { 0, 667250, 666000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"104", { 0, 673250, 672000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"105", { 0, 679250, 678000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"106", { 0, 685250, 684000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"107", { 0, 691250, 690000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"108", { 0, 697250, 696000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"109", { 0, 703250, 702000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"110", { 0, 709250, 708000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"111", { 0, 715250, 714000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"112", { 0, 721250, 720000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"113", { 0, 727250, 726000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"114", { 0, 733250, 732000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"115", { 0, 739250, 738000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"116", { 0, 745250, 744000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"117", { 0, 751250, 750000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"118", { 0, 757250, 756000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"119", { 0, 763250, 762000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"120", { 0, 769250, 768000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"121", { 0, 775250, 774000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"122", { 0, 781250, 780000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"123", { 0, 787250, 786000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"124", { 0, 793250, 792000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"125", { 0, 799250, 798000, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+{"T7", { 0, 8250, 7000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"T8", { 0, 14250, 13000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"T9", { 0, 20250, 19000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"T10", { 0, 26250, 25000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"T11", { 0, 32250, 31000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"T12", { 0, 38250, 37000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"T13", { 0, 44250, 43000, 0, 0, 0, 0, 0, 0, 0, 0}},
+{"T14", { 0, 50250, 49000, 0, 0, 0, 0, 0, 0, 0, 0}}
+};
+
+int CHAN_ENTRIES = sizeof(tvtuner)/sizeof(struct freqlist);
+int CHAN_NAMES = 11;
+
+struct gentab chan_names[] = {
+ { 0, "ntsc-bcast" },
+ { 1, "ntsc-cable" },
+ { 2, "ntsc-cable-hrc" },
+ { 3, "ntsc-bcast-jp" },
+ { 4, "ntsc-cable-jp" },
+ { 5, "pal-europe" },
+ { 6, "pal-europe-east" },
+ { 7, "pal-italy" },
+ { 8, "pal-newzealand" },
+ { 9, "pal-australia" },
+ { 10, "pal-ireland" },
+ { -1, NULL }
+};
diff --git a/src/wmgeneral/list.c b/src/wmgeneral/list.c
new file mode 100644
index 0000000..f804b2c
--- /dev/null
+++ b/src/wmgeneral/list.c
@@ -0,0 +1,169 @@
+/* Generic single linked list to keep various information
+ Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+
+
+Author: Kresten Krab Thorup
+
+Many modifications by Alfredo K. Kojima
+
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with files compiled with
+ GCC to produce an executable, this does not cause the resulting executable
+ to be covered by the GNU General Public License. This exception does not
+ however invalidate any other reasons why the executable file might be
+ covered by the GNU General Public License. */
+
+#include "list.h"
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#include <stdlib.h>
+
+/* Return a cons cell produced from (head . tail) */
+
+INLINE LinkedList*
+list_cons(void* head, LinkedList* tail)
+{
+ LinkedList* cell;
+
+ cell = (LinkedList*)malloc(sizeof(LinkedList));
+ cell->head = head;
+ cell->tail = tail;
+ return cell;
+}
+
+/* Return the length of a list, list_length(NULL) returns zero */
+
+INLINE int
+list_length(LinkedList* list)
+{
+ int i = 0;
+ while(list)
+ {
+ i += 1;
+ list = list->tail;
+ }
+ return i;
+}
+
+/* Return the Nth element of LIST, where N count from zero. If N
+ larger than the list length, NULL is returned */
+
+INLINE void*
+list_nth(int index, LinkedList* list)
+{
+ while(index-- != 0)
+ {
+ if(list->tail)
+ list = list->tail;
+ else
+ return 0;
+ }
+ return list->head;
+}
+
+/* Remove the element at the head by replacing it by its successor */
+
+INLINE void
+list_remove_head(LinkedList** list)
+{
+ if (!*list) return;
+ if ((*list)->tail)
+ {
+ LinkedList* tail = (*list)->tail; /* fetch next */
+ *(*list) = *tail; /* copy next to list head */
+ free(tail); /* free next */
+ }
+ else /* only one element in list */
+ {
+ free(*list);
+ (*list) = 0;
+ }
+}
+
+
+/* Remove the element with `car' set to ELEMENT */
+/*
+INLINE void
+list_remove_elem(LinkedList** list, void* elem)
+{
+ while (*list)
+ {
+ if ((*list)->head == elem)
+ list_remove_head(list);
+ *list = (*list ? (*list)->tail : NULL);
+ }
+}*/
+
+INLINE LinkedList *
+list_remove_elem(LinkedList* list, void* elem)
+{
+ LinkedList *tmp;
+
+ if (list) {
+ if (list->head == elem) {
+ tmp = list->tail;
+ free(list);
+ return tmp;
+ }
+ list->tail = list_remove_elem(list->tail, elem);
+ return list;
+ }
+ return NULL;
+}
+
+
+/* Return element that has ELEM as car */
+
+INLINE LinkedList*
+list_find(LinkedList* list, void* elem)
+{
+ while(list)
+ {
+ if (list->head == elem)
+ return list;
+ list = list->tail;
+ }
+ return NULL;
+}
+
+/* Free list (backwards recursive) */
+
+INLINE void
+list_free(LinkedList* list)
+{
+ if(list)
+ {
+ list_free(list->tail);
+ free(list);
+ }
+}
+
+/* Map FUNCTION over all elements in LIST */
+
+INLINE void
+list_mapcar(LinkedList* list, void(*function)(void*))
+{
+ while(list)
+ {
+ (*function)(list->head);
+ list = list->tail;
+ }
+}
diff --git a/src/wmgeneral/list.h b/src/wmgeneral/list.h
new file mode 100644
index 0000000..af0f22c
--- /dev/null
+++ b/src/wmgeneral/list.h
@@ -0,0 +1,59 @@
+/* Generic single linked list to keep various information
+ Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+
+Author: Kresten Krab Thorup
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with files compiled with
+ GCC to produce an executable, this does not cause the resulting executable
+ to be covered by the GNU General Public License. This exception does not
+ however invalidate any other reasons why the executable file might be
+ covered by the GNU General Public License. */
+
+#ifndef __LIST_H_
+#define __LIST_H_
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+# define INLINE inline
+#else
+# define INLINE
+#endif
+
+typedef struct LinkedList {
+ void *head;
+ struct LinkedList *tail;
+} LinkedList;
+
+INLINE LinkedList* list_cons(void* head, LinkedList* tail);
+
+INLINE int list_length(LinkedList* list);
+
+INLINE void* list_nth(int index, LinkedList* list);
+
+INLINE void list_remove_head(LinkedList** list);
+
+INLINE LinkedList *list_remove_elem(LinkedList* list, void* elem);
+
+INLINE void list_mapcar(LinkedList* list, void(*function)(void*));
+
+INLINE LinkedList*list_find(LinkedList* list, void* elem);
+
+INLINE void list_free(LinkedList* list);
+
+#endif
diff --git a/src/wmgeneral/misc.c b/src/wmgeneral/misc.c
new file mode 100644
index 0000000..34281e2
--- /dev/null
+++ b/src/wmgeneral/misc.c
@@ -0,0 +1,164 @@
+/* dock.c- built-in Dock module for WindowMaker
+ *
+ * WindowMaker window manager
+ *
+ * Copyright (c) 1997 Alfredo K. Kojima
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "list.h"
+#include "misc.h"
+
+/*
+ *----------------------------------------------------------------------
+ * parse_command--
+ * Divides a command line into a argv/argc pair.
+ *----------------------------------------------------------------------
+ */
+#define PRC_ALPHA 0
+#define PRC_BLANK 1
+#define PRC_ESCAPE 2
+#define PRC_DQUOTE 3
+#define PRC_EOS 4
+#define PRC_SQUOTE 5
+
+typedef struct {
+ short nstate;
+ short output;
+} DFA;
+
+
+static DFA mtable[9][6] = {
+ {{3,1},{0,0},{4,0},{1,0},{8,0},{6,0}},
+ {{1,1},{1,1},{2,0},{3,0},{5,0},{1,1}},
+ {{1,1},{1,1},{1,1},{1,1},{5,0},{1,1}},
+ {{3,1},{5,0},{4,0},{1,0},{5,0},{6,0}},
+ {{3,1},{3,1},{3,1},{3,1},{5,0},{3,1}},
+ {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
+ {{6,1},{6,1},{7,0},{6,1},{5,0},{3,0}},
+ {{6,1},{6,1},{6,1},{6,1},{5,0},{6,1}},
+ {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
+};
+
+char*
+next_token(char *word, char **next)
+{
+ char *ptr;
+ char *ret, *t;
+ int state, ctype;
+
+ t = ret = malloc(strlen(word)+1);
+ ptr = word;
+
+ state = 0;
+ *t = 0;
+ while (1) {
+ if (*ptr==0)
+ ctype = PRC_EOS;
+ else if (*ptr=='\\')
+ ctype = PRC_ESCAPE;
+ else if (*ptr=='"')
+ ctype = PRC_DQUOTE;
+ else if (*ptr=='\'')
+ ctype = PRC_SQUOTE;
+ else if (*ptr==' ' || *ptr=='\t')
+ ctype = PRC_BLANK;
+ else
+ ctype = PRC_ALPHA;
+
+ if (mtable[state][ctype].output) {
+ *t = *ptr; t++;
+ *t = 0;
+ }
+ state = mtable[state][ctype].nstate;
+ ptr++;
+ if (mtable[state][0].output<0) {
+ break;
+ }
+ }
+
+ if (*ret==0)
+ t = NULL;
+ else
+ t = strdup(ret);
+
+ free(ret);
+
+ if (ctype==PRC_EOS)
+ *next = NULL;
+ else
+ *next = ptr;
+
+ return t;
+}
+
+
+extern void
+parse_command(char *command, char ***argv, int *argc)
+{
+ LinkedList *list = NULL;
+ char *token, *line;
+ int count, i;
+
+ line = command;
+ do {
+ token = next_token(line, &line);
+ if (token) {
+ list = list_cons(token, list);
+ }
+ } while (token!=NULL && line!=NULL);
+
+ count = list_length(list);
+ *argv = malloc(sizeof(char*)*count);
+ i = count;
+ while (list!=NULL) {
+ (*argv)[--i] = list->head;
+ list_remove_head(&list);
+ }
+ *argc = count;
+}
+
+extern pid_t
+execCommand(char *command)
+{
+ pid_t pid;
+ char **argv;
+ int argc;
+
+ parse_command(command, &argv, &argc);
+
+ if (argv==NULL) {
+ return 0;
+ }
+
+ if ((pid=fork())==0) {
+ char **args;
+ int i;
+
+ args = malloc(sizeof(char*)*(argc+1));
+ if (!args)
+ exit(10);
+ for (i=0; i<argc; i++) {
+ args[i] = argv[i];
+ }
+ args[argc] = NULL;
+ execvp(argv[0], args);
+ exit(10);
+ }
+ return pid;
+}
diff --git a/src/wmgeneral/misc.h b/src/wmgeneral/misc.h
new file mode 100644
index 0000000..602e1b7
--- /dev/null
+++ b/src/wmgeneral/misc.h
@@ -0,0 +1,9 @@
+#ifndef __MISC_H
+#define __MISC_H
+
+#include <unistd.h>
+
+extern void parse_command(char *, char ***, int *);
+
+extern pid_t execCommand(char *);
+#endif /* __MISC_H */
diff --git a/src/wmgeneral/wmgeneral.c b/src/wmgeneral/wmgeneral.c
new file mode 100644
index 0000000..4877acd
--- /dev/null
+++ b/src/wmgeneral/wmgeneral.c
@@ -0,0 +1,419 @@
+/*
+ Best viewed with vim5, using ts=4
+
+ wmgeneral was taken from wmppp.
+
+ It has a lot of routines which most of the wm* programs use.
+
+ ------------------------------------------------------------
+
+ Author: Martijn Pieterse (pieterse at xs4all.nl)
+
+ ---
+ CHANGES:
+ ---
+ 12/03/1999 (Wee Liang, wliang at tartarus.uwa.edu.au)
+ * Removed argument parsing from openXwindow
+ 12/02/1999 (Wee Liang, wliang at tartarus.uwa.edu.au)
+ * Removed parse_rcfile and parse_rcfile2.
+ * Change RedrawWindowXY to RedrawWindowXYWH
+ * Minor modifications to openXwindow. Added execute
+ file support.
+ 11/09/1998 (Martijn Pieterse, pieterse at xs4all.nl)
+ * Removed a bug from parse_rcfile. You could
+ not use "start" in a command if a label was
+ also start.
+ * Changed the needed geometry string.
+ We don't use window size, and don't support
+ negative positions.
+ 03/09/1998 (Martijn Pieterse, pieterse at xs4all.nl)
+ * Added parse_rcfile2
+ 02/09/1998 (Martijn Pieterse, pieterse at xs4all.nl)
+ * Added -geometry support (untested)
+ 28/08/1998 (Martijn Pieterse, pieterse at xs4all.nl)
+ * Added createXBMfromXPM routine
+ * Saves a lot of work with changing xpm's.
+ 02/05/1998 (Martijn Pieterse, pieterse at xs4all.nl)
+ * changed the read_rc_file to parse_rcfile, as suggested by Marcelo E. Magallon
+ * debugged the parse_rc file.
+ 30/04/1998 (Martijn Pieterse, pieterse at xs4all.nl)
+ * Ripped similar code from all the wm* programs,
+ and put them in a single file.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include <X11/Xlib.h>
+#include <X11/xpm.h>
+#include <X11/extensions/shape.h>
+
+#include "wmgeneral.h"
+
+ /*****************/
+ /* X11 Variables */
+/*****************/
+
+Window Root;
+int screen;
+int x_fd;
+int d_depth;
+XSizeHints mysizehints;
+XWMHints mywmhints;
+Pixel back_pix, fore_pix;
+char *Geometry = "";
+Window iconwin, win;
+GC NormalGC;
+XpmIcon wmgen;
+Pixmap pixmask;
+char *exef = NULL;
+char *display_name = NULL;
+char *geometry = NULL;
+char *exe = NULL;
+
+ /*****************/
+ /* Mouse Regions */
+/*****************/
+
+typedef struct {
+ int enable;
+ int top;
+ int bottom;
+ int left;
+ int right;
+} MOUSE_REGION;
+
+MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
+
+ /***********************/
+ /* Function Prototypes */
+/***********************/
+
+static void GetXPM(XpmIcon *, char **);
+static Pixel GetColor(char *);
+void RedrawWindow(void);
+void AddMouseRegion(int, int, int, int, int);
+int CheckMouseRegion(int, int);
+
+/*******************************************************************************\
+|* GetXPM *|
+\*******************************************************************************/
+
+static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
+
+ XWindowAttributes attributes;
+ int err;
+
+ /* For the colormap */
+ XGetWindowAttributes(display, Root, &attributes);
+
+ wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
+
+ err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
+ &(wmgen->mask), &(wmgen->attributes));
+
+ if (err != XpmSuccess) {
+ fprintf(stderr, "Not enough free colorcells.\n");
+ exit(1);
+ }
+}
+
+/*******************************************************************************\
+|* GetColor *|
+\*******************************************************************************/
+
+static Pixel GetColor(char *name) {
+
+ XColor color;
+ XWindowAttributes attributes;
+
+ XGetWindowAttributes(display, Root, &attributes);
+
+ color.pixel = 0;
+ if (!XParseColor(display, attributes.colormap, name, &color)) {
+ fprintf(stderr, "wm.app: can't parse %s.\n", name);
+ } else if (!XAllocColor(display, attributes.colormap, &color)) {
+ fprintf(stderr, "wm.app: can't allocate %s.\n", name);
+ }
+ return color.pixel;
+}
+
+/*******************************************************************************\
+|* flush_expose *|
+\*******************************************************************************/
+
+static int flush_expose(Window w) {
+
+ XEvent dummy;
+ int i=0;
+
+ while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
+ i++;
+
+ return i;
+}
+
+/*******************************************************************************\
+|* RedrawWindow *|
+\*******************************************************************************/
+
+void RedrawWindow(void) {
+
+ flush_expose(iconwin);
+ XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
+ 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
+ flush_expose(win);
+ XCopyArea(display, wmgen.pixmap, win, NormalGC,
+ 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
+}
+
+/*******************************************************************************\
+|* RedrawWindowXYWH *|
+\*******************************************************************************/
+
+void RedrawWindowXYWH(int x, int y, int w, int h) {
+
+ flush_expose(iconwin);
+ XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
+ x,y, w, h, 0,0);
+ flush_expose(win);
+ XCopyArea(display, wmgen.pixmap, win, NormalGC,
+ x,y, w, h, 0,0);
+}
+
+/*******************************************************************************\
+|* AddMouseRegion *|
+\*******************************************************************************/
+
+void AddMouseRegion(int index, int left, int top, int right, int bottom) {
+
+ if (index < MAX_MOUSE_REGION) {
+ mouse_region[index].enable = 1;
+ mouse_region[index].top = top;
+ mouse_region[index].left = left;
+ mouse_region[index].bottom = bottom;
+ mouse_region[index].right = right;
+ }
+}
+
+/*******************************************************************************\
+|* CheckMouseRegion *|
+\*******************************************************************************/
+
+int CheckMouseRegion(int x, int y) {
+
+ int i;
+ int found;
+
+ found = 0;
+
+ for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
+ if (mouse_region[i].enable &&
+ x <= mouse_region[i].right &&
+ x >= mouse_region[i].left &&
+ y <= mouse_region[i].bottom &&
+ y >= mouse_region[i].top)
+ found = 1;
+ }
+ if (!found) return -1;
+ return (i-1);
+}
+
+/*******************************************************************************\
+|* createXBMfromXPM *|
+\*******************************************************************************/
+void createXBMfromXPM(char *xbm, char **xpm, int sx, int sy) {
+
+ int i,j;
+ int width, height, numcol;
+ char zero;
+ unsigned char bwrite;
+ int bcount;
+
+
+ sscanf(*xpm, "%d %d %d", &width, &height, &numcol);
+
+ zero = xpm[1][0];
+ for (i=numcol+1; i < numcol+sy+1; i++) {
+ bcount = 0;
+ bwrite = 0;
+ for (j=0; j<sx; j++) {
+ bwrite >>= 1;
+ if (xpm[i][j] != zero) {
+ bwrite += 128;
+ }
+ bcount++;
+ if (bcount == 8) {
+ *xbm = bwrite;
+ xbm++;
+ bcount = 0;
+ bwrite = 0;
+ }
+ }
+ }
+}
+
+/*******************************************************************************\
+|* copyXPMArea *|
+\*******************************************************************************/
+
+void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
+
+ XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
+
+}
+
+/*******************************************************************************\
+|* copyXBMArea *|
+\*******************************************************************************/
+
+void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
+
+ XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
+}
+
+
+/*******************************************************************************\
+|* setMaskXY *|
+\*******************************************************************************/
+
+void setMaskXY(int x, int y) {
+
+ XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
+ XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
+}
+
+/*******************************************************************************\
+|* openXwindow *|
+\*******************************************************************************/
+void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
+
+ unsigned int borderwidth = 1;
+ XClassHint classHint;
+ char *wname = argv[0];
+ XTextProperty name;
+
+ XGCValues gcv;
+ unsigned long gcm;
+
+ int dummy=0;
+ int wx, wy;
+ //Window junkwin;
+ //int rx, ry;
+ //XWindowAttributes winatr;
+
+ /*
+ for (i=1; argv[i]; i++) {
+ if (!strcmp(argv[i], "-display")) {
+ display_name = argv[i+1];
+ i++;
+ }
+ if (!strcmp(argv[i], "-geometry")) {
+ geometry = argv[i+1];
+ i++;
+ }
+ if (!strcmp(argv[i], "-exe")) {
+ exe = argv[i+1];
+ strcat (exe, " &");
+ exef = exe;
+ i++;
+ }
+ }
+ */
+
+ if (!(display = XOpenDisplay(display_name))) {
+ fprintf(stderr, "%s: can't open display %s\n",
+ wname, XDisplayName(display_name));
+ exit(1);
+ }
+
+ screen = DefaultScreen(display);
+ Root = RootWindow(display, screen);
+ d_depth = DefaultDepth(display, screen);
+ x_fd = XConnectionNumber(display);
+
+ /* Convert XPM to XImage */
+ GetXPM(&wmgen, pixmap_bytes);
+
+ /* Create a window to hold the stuff */
+ mysizehints.flags = USSize | USPosition;
+ mysizehints.x = 0;
+ mysizehints.y = 0;
+
+ back_pix = GetColor("white");
+ fore_pix = GetColor("black");
+
+ XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
+ &mysizehints.x, &mysizehints.y, &mysizehints.width, &mysizehints.height, &dummy);
+
+ mysizehints.width = 64;
+ mysizehints.height = 64;
+
+ win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
+ mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
+
+ iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
+ mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
+
+ /* Activate hints */
+ XSetWMNormalHints(display, win, &mysizehints);
+ classHint.res_name = wname;
+ classHint.res_class = wname;
+ XSetClassHint(display, win, &classHint);
+
+ XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | VisibilityChangeMask);
+ XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | VisibilityChangeMask);
+
+ if (XStringListToTextProperty(&wname, 1, &name) == 0) {
+ fprintf(stderr, "%s: can't allocate window name\n", wname);
+ exit(1);
+ }
+
+ XSetWMName(display, win, &name);
+
+ /* Create GC for drawing */
+
+ gcm = GCForeground | GCBackground | GCGraphicsExposures;
+ gcv.foreground = fore_pix;
+ gcv.background = back_pix;
+ gcv.graphics_exposures = 0;
+ NormalGC = XCreateGC(display, Root, gcm, &gcv);
+
+ /* ONLYSHAPE ON */
+
+ pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
+
+ XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
+ XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
+
+ /* ONLYSHAPE OFF */
+
+ mywmhints.initial_state = WithdrawnState;
+ mywmhints.icon_window = iconwin;
+ mywmhints.icon_x = mysizehints.x;
+ mywmhints.icon_y = mysizehints.y;
+ mywmhints.window_group = win;
+ mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
+ XSetWMHints(display, win, &mywmhints);
+
+ XSetCommand(display, win, argv, argc);
+ XMapWindow(display, win);
+
+// XGetWindowAttributes(display, iconwin, &winatr);
+// XTranslateCoordinates(display, iconwin, winatr.root, -winatr.border_width, - winatr.border_width,
+// &rx, &ry, &junkwin);
+
+ if (geometry) {
+ if (sscanf(geometry, "+%d+%d", &wx, &wy) != 2) {
+ fprintf(stderr, "Bad geometry string.\n");
+ exit(1);
+ }
+ XMoveWindow(display, win, wx, wy);
+ }
+}
diff --git a/src/wmgeneral/wmgeneral.h b/src/wmgeneral/wmgeneral.h
new file mode 100644
index 0000000..e26ca58
--- /dev/null
+++ b/src/wmgeneral/wmgeneral.h
@@ -0,0 +1,62 @@
+#ifndef WMGENERAL_H_INCLUDED
+#define WMGENERAL_H_INCLUDED
+
+ /***********/
+ /* Defines */
+/***********/
+
+#define MAX_MOUSE_REGION (16)
+
+ /************/
+ /* Typedefs */
+/************/
+
+typedef struct _rckeys rckeys;
+
+struct _rckeys {
+ const char *label;
+ char **var;
+};
+
+typedef struct _rckeys2 rckeys2;
+
+struct _rckeys2 {
+ const char *family;
+ const char *label;
+ char **var;
+};
+
+typedef struct {
+ Pixmap pixmap;
+ Pixmap mask;
+ XpmAttributes attributes;
+} XpmIcon;
+
+ /*******************/
+ /* Global variable */
+/*******************/
+
+Display *display;
+
+ /***********************/
+ /* Function Prototypes */
+/***********************/
+
+void AddMouseRegion(int index, int left, int top, int right, int bottom);
+int CheckMouseRegion(int x, int y);
+
+void openXwindow(int argc, char *argv[], char **, char *, int, int);
+void RedrawWindow(void);
+void RedrawWindowXYWH(int x, int y, int w, int h);
+
+void createXBMfromXPM(char *, char **, int, int);
+void copyXPMArea(int, int, int, int, int, int);
+void copyXBMArea(int, int, int, int, int, int);
+void setMaskXY(int, int);
+
+extern Window win, iconwin;
+extern char *exef;
+extern char *display_name;
+extern char *geometry;
+extern char *exe;
+#endif
diff --git a/src/wmtv-master.xpm b/src/wmtv-master.xpm
new file mode 100644
index 0000000..748996b
--- /dev/null
+++ b/src/wmtv-master.xpm
@@ -0,0 +1,143 @@
+/* XPM */
+static char * wmtv_master_xpm[] = {
+"128 128 12 1",
+" c #00000000FFFF",
+". c #000000000000",
+"X c #C71BC71BC71B",
+"o c #208120812081",
+"O c #FFFFFFFFFFFF",
+"+ c #861782078E38",
+"@ c #AEBAAAAAAEBA",
+"# c #000049244103",
+"$ c #2081B2CAAEBA",
+"% c #10407DF779E7",
+"& c #18618A288617",
+"* c #F7DEF3CEFFFF",
+" ",
+" ",
+" ",
+" ",
+" ........................................................ ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" .......................................................X ",
+" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
+" ",
+" ",
+" ................ ...................................... ",
+" .ooooooooooooooX .OOOOOOOOOOO+OOOOOOOOOOO+OOOOOOOOOOO+X ",
+" .ooooooooooooooX .O@@@@@@@@@@.O@@@@@@@@@@.O@@@@@@@@@@.X ",
+" .oo###ooo###oooX .O@@@@@@.@@@.O@@@.@@@@@@.O@@@@..@@@@.X ",
+" .o#ooo#o#ooo#ooX .O@@@@@..@@@.O@@@..@@@@@.O@@. at ..@.@@.X ",
+" .o#ooo#o#ooo#ooX .O@@@@...@@@.O@@@...@@@@.O at .@@..@@. at .X ",
+" .oo###ooo###oooX .O@@@....@@@.O@@@....@@@.O at .@.... at .@.X ",
+" .o#ooo#o#ooo#ooX .O@@@@...@@@.O@@@...@@@@.O at .@@..@@. at .X ",
+" .o#ooo#o#ooo#ooX .O@@@@@..@@@.O@@@..@@@@@.O@@.@@@@.@@.X ",
+" .oo###ooo###oooX .O@@@@@@.@@@.O@@@.@@@@@@.O@@@....@@@.X ",
+" .ooooooooooooooX .O@@@@@@@@@@.O@@@@@@@@@@.O@@@@@@@@@@.X ",
+" .ooooooooooooooX .+...........+...........+...........X ",
+" XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
+" ",
+" ",
+" ",
+" ",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ",
+"oo$$$$ooo####%o%$$$$&o%$$$$%o%####%o%$$$$%o%$$$$&o%$$$$%o%$$$$&o%$$$$&oooo ",
+"o$oooo$o#oooo$o#oooo$o#oooo$o$oooo$o$oooo#o$oooo#o#oooo$o$oooo$o$oooo$oooo ",
+"o$oooo$o#oooo$o#oooo$o#oooo$o$oooo$o$oooo#o$oooo#o#oooo$o$oooo$o$oooo$oooo ",
+"o$oooo$o#oooo$o#oooo$o#oooo$o$oooo$o$oooo#o$oooo#o#oooo$o$oooo$o$oooo$oooo ",
+"o%####%oo####%o%$$$$%o%$$$$%o%$$$$%o%$$$$%o%$$$$%oo####%o%$$$$%o%$$$$%oooo ",
+"o$oooo$o#oooo$o$oooo#o#oooo$o#oooo$o#oooo$o$oooo$o#oooo$o$oooo$o#oooo$oooo ",
+"o$oooo$o#oooo$o$oooo#o#oooo$o#oooo$o#oooo$o$oooo$o#oooo$o$oooo$o#oooo$oooo ",
+"o$oooo$o#oooo$o$oooo#o#oooo$o#oooo$o#oooo$o$oooo$o#oooo$o$oooo$o#oooo$o$oo ",
+"oo$$$$ooo####%o%$$$$%o%$$$$%oo####%o%$$$$%o%$$$$%oo####%o%$$$$%o%$$$$%o$oo ",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ",
+" ",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+"oo$$$ooo###&o&$$$&o&$$$&o&###&o&$$$&o&$$$&o&$$$&o&$$$&o&$$$&ooooooo###ooo###ooooooo###ooo###ooooo###&o&###ooo&$$$ooo&$$$&o&###&o",
+"o$ooo$o#ooo$o#ooo$o#ooo$o$ooo$o$ooo#o$ooo#o#ooo$o$ooo$o$ooo$oooooo#ooo#o#ooo#ooooo#ooo#o#ooo#ooo#ooo$o$ooo#oo$ooo#oo$ooo#o$ooo$o",
+"o$ooo$o#ooo$o#ooo$o#ooo$o$ooo$o$ooo#o$ooo#o#ooo$o$ooo$o$ooo$oo$ooo#ooo#o#ooo#oo#oo#ooo#o#ooo#ooo#ooo$o$ooo#oo$ooo#oo$ooo#o$ooo$o",
+"o&###&oo###&o&$$$&oo$$$&o&$$$&o&$$$&o&$$$&oo###&o&$$$&o&$$$&oo&oooo###ooo###ooo#ooo###ooo###ooooo$$$&o&$$$ooo&###ooo&$$$&o&###&o",
+"o$ooo$o#ooo$o$ooo#o#ooo$o#ooo$o#ooo$o$ooo$o#ooo$o$ooo$o#ooo$oooooo#ooo#o#ooo#ooooo#ooo#o#ooo#ooo#ooo$o$ooo#oo$ooo#oo#ooo$o$ooo$o",
+"o$ooo$o#ooo$o$ooo#o#ooo$o#ooo$o#ooo$o$ooo$o#ooo$o$ooo$o#ooo$oo$ooo#ooo#o#ooo#oo#oo#ooo#o#ooo#ooo#ooo$o$ooo#oo$ooo#oo#ooo$o$ooo$o",
+"oo$$$ooo###&o&$$$&o&$$$&oo###&o&$$$&o&$$$&oo###&o&$$$&o&$$$&oo&oooo###ooo###ooo#ooo###ooo###ooooo###&o&###ooo&$$$ooo&$$$&oo#$#oo",
+"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
+" ",
+" OOOOOOOOOOO+OOOOOOOOOOO+OOOOOOOOOOO+ ",
+" O@@@@@@@@@@.O@@@@@@@@@@.O@@@@@@@@@@. ",
+" O@@@@@@.@@@.O@@@.@@@@@@.O@@@@..@@@@. ",
+" O@@@@@..@@@.O@@@..@@@@@.O@@. at ..@.@@. ",
+" O@@@@...@@@.O@@@...@@@@.O at .@@..@@. at . ",
+" O@@@....@@@.O@@@....@@@.O at .@.... at .@. ",
+" O@@@@...@@@.O@@@...@@@@.O at .@@..@@. at . ",
+" O@@@@@..@@@.O@@@..@@@@@.O@@.@@@@.@@. ",
+" O@@@@@@.@@@.O@@@.@@@@@@.O@@@....@@@. ",
+" O@@@@@@@@@@.O@@@@@@@@@@.O@@@@@@@@@@. ",
+" +...........+...........+........... ",
+" ",
+" ...........+...........+...........+ ",
+" .@@@@@@@@@@*.@@@@@@@@@@*.@@@@@@@@@@* ",
+" .@@@@@@.@@@*.@@@.@@@@@@*.@@@@..@@@@* ",
+" .@@@@@..@@@*.@@@..@@@@@*.@@. at ..@.@@* ",
+" .@@@@...@@@*.@@@...@@@@*. at .@@..@@.@* ",
+" .@@@....@@@*.@@@....@@@*. at .@.... at .@* ",
+" .@@@@...@@@*.@@@...@@@@*. at .@@..@@.@* ",
+" .@@@@@..@@@*.@@@..@@@@@*.@@.@@@@.@@* ",
+" .@@@@@@.@@@*.@@@.@@@@@@*.@@@....@@@* ",
+" .@@@@@@@@@@*.@@@@@@@@@@*.@@@@@@@@@@* ",
+" +***********+***********+*********** ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/src/wmtv.c b/src/wmtv.c
new file mode 100644
index 0000000..c552346
--- /dev/null
+++ b/src/wmtv.c
@@ -0,0 +1,1580 @@
+/* Copyright (c) 1999 Wee Liang (wliang at tartarus.uwa.edu.au)
+ *
+ * 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, 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 (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+
+/* Includes */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <linux/videodev.h>
+#include <linux/soundcard.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xmd.h>
+#include <X11/StringDefs.h>
+#include <X11/keysym.h>
+#include <X11/xpm.h>
+#include <X11/extensions/shape.h>
+#include <X11/extensions/xf86dga.h>
+#include <X11/extensions/xf86vmode.h>
+
+#include "wmgeneral/wmgeneral.h"
+#include "wmgeneral/misc.h"
+#include "wmtv-master.xpm"
+#include "channels.h"
+
+
+/* Defines */
+#define VERSION "0.6.5"
+
+#define ON 1
+#define OFF 0
+
+#define NTFB 0 /* On/SetTune/Off Button */
+#define SCANLB 1 /* Scan Left Button */
+#define SCANRB 2 /* Scan Right Button */
+#define FULLSB 3 /* Full Screen Toggle Button */
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define SETON 0
+#define SETOFF 1
+#define SETUNE 2
+#define SETSPD 3
+
+#define MAXCHAN 100
+#define OPTIONS "hvd:g:e:b:"
+
+#define TELEVISION 0
+#define COMPOSITE 1
+#define SVIDEO 2
+
+
+/* Global Variables */
+int tfd;
+int card_present = FALSE;
+int ntfb_status = SETOFF;
+char *maxpreset = NULL;
+char **chan = NULL;
+int mode_present = FALSE;
+
+int chn = 0;
+int aud = 0;
+int tpst = 0;
+int cchannel = 0;
+int timebutton = 0;
+int tvsource = 0;
+int ccapt;
+int norcfile = 0;
+int ic = 0;
+int cnotune = 0;
+int vsource = 0;
+int isource = 0;
+int compchannel = 0;
+int vidmode = 0;
+int fmode = 0;
+int mute = 0;
+int dcret;
+int tml;
+int fswidth = 0;
+int fsheight = 0;
+
+unsigned long ccrfreq;
+unsigned long rfreq;
+unsigned long st;
+unsigned long offset;
+
+char *norm = NULL;
+char *source;
+char *mode = NULL;
+char *fullscreen = NULL;
+int freqnorm = -1;
+char *cname[MAXCHAN];
+char *wcname[MAXCHAN];
+int ftune[MAXCHAN];
+char *progname;
+char *dev = "/dev/video";
+
+int wmtv_mask_width = 64;
+int wmtv_mask_height = 64;
+char wmtv_mask_bits[64*64];
+
+int btime = 0;
+int but_pressed = FALSE;
+int but_clicked = FALSE;
+int maxpst;
+int x_lc;
+int y_lc;
+Time t_lc;
+
+rckeys wmtv_keys[] = {
+ { "freqnorm", &norm },
+ { "source", &source },
+ { "maxpreset", &maxpreset },
+ { "mode", &mode },
+ { "fullscreen", &fullscreen },
+ { NULL, NULL }
+};
+
+XEvent Event;
+XWindowAttributes Winattr;
+Window fmwin;
+GC fmGC;
+XF86VidModeModeInfo **modelines, *fullscreenmode = NULL;
+XF86VidModeModeLine scmode;
+
+struct video_capability vcap;
+struct video_buffer vfb;
+struct video_window vwin;
+struct video_window vswin;
+struct video_channel vchn, vchns;
+struct video_picture vpic;
+struct video_tuner vtun;
+struct video_audio vaud;
+struct video_mbuf vmbuf;
+struct video_mmap vmmap;
+struct video_clip vclip[2];
+struct video_clip vclip2[2];
+
+
+/* Function prototypes */
+void TVOn(void);
+void TVOff(void);
+void TuneTV(void);
+void ChanUp(void);
+void ChanDown(void);
+void FineTuneUp(void);
+void FineTuneDown(void);
+void ScanUp(void);
+void ScanDown(void);
+
+void ButtonUp(int);
+void ButtonDown(int);
+void Capture(void);
+void MuteAudio(void);
+void UnMuteAudio(void);
+void VolumeUp(void);
+void VolumeDown(void);
+void DrawPresetChan(int);
+void DoFullScreen(void);
+void GetFrameBuffer(void);
+void RetScreen(void);
+void GrabImage(void);
+
+void ParseRCFile(const char *, rckeys *);
+void ParseRCFile2(const char *);
+void WriteRCFile(const char *);
+void InitConfig(void);
+void InitPalette(void);
+
+void Usage(void);
+void Version(void);
+
+
+/* main function */
+int
+main(int argc, char *argv[])
+{
+ int i, c, opind;
+ // pid_t pid;
+ char cfile[128];
+ static struct option long_options[] = {
+ {"display", 1, 0, 'd'},
+ {"geometry", 1, 0, 'g'},
+ {"bpp", 1, 0, 'b'},
+ {"exe", 1, 0, 'e'},
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 'v'},
+ {0, 0, 0, 0}
+ };
+
+ progname = strdup(argv[0]);
+
+ strncpy(cfile, (char *)getenv("HOME"), sizeof(char)*128);
+ strcat(cfile, "/.wmtvrc");
+
+ while (1) {
+ opind = 0;
+ c = getopt_long (argc, argv, OPTIONS, long_options, &opind);
+ if (c == -1)
+ break;
+
+ switch(c)
+ {
+ case 0:
+ /*
+ fprintf(stderr, "wmtv: option - %s", long_options[opind].name);
+ if (optarg)
+ fprintf(stderr, " with arg %s", optarg);
+ printf("\n");
+ */
+ break;
+ case 'd':
+ display_name = strdup(optarg);
+ break;
+ case 'g':
+ geometry = strdup(optarg);
+ break;
+ case 'e':
+ exe = strdup(optarg);
+ strcat(exe, " &");
+ break;
+ case 'b':
+ fprintf(stderr, "wmtv: option not implemented yet\n");
+ Usage();
+ exit(1);
+ break;
+ case 'v':
+ Version();
+ exit(0);
+ break;
+ default:
+ Usage();
+ exit(1);
+ }
+ }
+
+ /* creat windows */
+ createXBMfromXPM (wmtv_mask_bits, wmtv_master_xpm,
+ wmtv_mask_width, wmtv_mask_height);
+ openXwindow (argc, argv, wmtv_master_xpm, wmtv_mask_bits,
+ wmtv_mask_width, wmtv_mask_height);
+
+ AddMouseRegion (NTFB, 47, 48, 59, 59); /* On/SetTune/Off Button */
+ AddMouseRegion (SCANLB, 23, 48, 35, 59); /* Left Preset/Scan Button */
+ AddMouseRegion (SCANRB, 35, 48, 47, 59); /* Right Preset/Scan Button */
+ AddMouseRegion (FULLSB, 5, 5, 59, 44); /* Toggle FullScreen */
+
+ /* wmtv main loop */
+ while (1)
+ {
+ while (XPending(display))
+ {
+ XNextEvent(display, &Event);
+ switch (Event.type) {
+ case Expose:
+ RedrawWindow();
+ break;
+ case DestroyNotify:
+ XCloseDisplay(display);
+ ccapt = 0;
+ if (ioctl(tfd, VIDIOCCAPTURE, &ccapt) < 0) {
+ perror("ioctl VIDIOCCAPTURE");
+ }
+ close(tfd);
+ usleep(50000L);
+ exit(0);
+ break;
+ case ButtonPress:
+ if ((Event.xany.window == fmwin) && fmode) {
+ RetScreen();
+ }
+ else {
+ i = CheckMouseRegion (Event.xbutton.x, Event.xbutton.y);
+ switch (i) {
+ case NTFB:
+ ButtonDown(NTFB);
+ t_lc = Event.xbutton.time;
+ but_pressed = TRUE;
+ break;
+ case SCANLB:
+ ButtonDown(SCANLB);
+ if (ntfb_status == SETUNE) {
+ switch (Event.xbutton.button) {
+ case 1:
+ timebutton = 1;
+ while (timebutton == 1)
+ if (isource == TELEVISION)
+ ScanDown();
+ break;
+ case 3:
+ if (isource == TELEVISION)
+ FineTuneDown();
+ break;
+ }
+ }
+ else
+ ChanDown();
+ break;
+ case SCANRB:
+ ButtonDown(SCANRB);
+ if (ntfb_status == SETUNE) {
+ switch (Event.xbutton.button) {
+ case 1:
+ timebutton = 1;
+ while (timebutton)
+ if (isource == TELEVISION)
+ ScanUp();
+ break;
+ case 3:
+ if (isource == TELEVISION)
+ FineTuneUp();
+ break;
+ }
+ }
+ else
+ ChanUp();
+ break;
+ case FULLSB:
+ ButtonDown(FULLSB);
+ switch (Event.xbutton.button) {
+ case 1:
+ but_pressed = TRUE;
+ break;
+ case 2:
+ but_pressed = TRUE;
+ break;
+ case 3:
+ if (!mute) {
+ MuteAudio();
+ }
+ else {
+ UnMuteAudio();
+ }
+ break;
+ }
+ break;
+ }
+ RedrawWindow();
+ }
+ break;
+ case ButtonRelease:
+ i = CheckMouseRegion (Event.xbutton.x, Event.xbutton.y);
+ switch (i) {
+ case NTFB:
+ ButtonUp(NTFB);
+ if (but_pressed) {
+ if (Event.xbutton.time - t_lc >= 900) {
+ btime = TRUE;
+ but_pressed = FALSE;
+ }
+ }
+
+ if (ntfb_status == SETOFF) {
+ ntfb_status = SETON;
+ TVOn();
+ }
+ else if (ntfb_status == SETON) {
+ if (!btime) {
+ ntfb_status = SETUNE;
+ copyXPMArea(96, 79, 11, 7, 6, 50);
+ RedrawWindowXYWH(6, 50, 11, 7);
+ }
+ else if (btime) {
+ ntfb_status = SETOFF;
+ btime = FALSE;
+ ic = TRUE;
+ TVOff();
+ }
+ }
+ else if (ntfb_status == SETUNE) {
+ if (!btime) {
+ offset = (rfreq - ccrfreq);
+ // fprintf(stderr, "wmtv: finetune offset = %ld\n", offset);
+ WriteRCFile(cfile);
+ ntfb_status = SETON;
+ DrawPresetChan(cchannel);
+ }
+ else if (btime) {
+ ntfb_status = SETOFF;
+ btime = FALSE;
+ ic = TRUE;
+ TVOff();
+ }
+ }
+ break;
+ case SCANLB:
+ ButtonUp(SCANLB);
+ if (ntfb_status == SETUNE)
+ timebutton = 0;
+ break;
+ case SCANRB:
+ ButtonUp(SCANRB);
+ if (ntfb_status == SETUNE)
+ timebutton = 0;
+ break;
+ case FULLSB:
+ ButtonUp(FULLSB);
+ switch (Event.xbutton.button) {
+ case 1: {
+ if (but_clicked) {
+ but_pressed = FALSE;
+ but_clicked = FALSE;
+
+ if (((Event.xbutton.time - t_lc) <= 500) && (abs(Event.xbutton.x - x_lc) <= 10) && (abs(Event.xbutton.y - y_lc) <= 10) )
+ {
+ if ((ntfb_status == SETON) || (ntfb_status == SETUNE)) {
+ if (exe) {
+ ntfb_status = SETOFF;
+ TVOff();
+ system(exe);
+ /*
+ pid = fork();
+
+ // child
+ if (pid == (pid_t) 0) {
+ execlp("xawtv", "xawtv", "&", (char *) 0);
+ }
+
+ else if (pid < (pid_t) 0) {
+ perror("fork");
+ }
+
+ // parent
+ else {
+ if (waitpid(pid, NULL, 0) < 0) {
+ perror("waitpid");
+ */
+ }
+ else {
+ DoFullScreen();
+ }
+ }
+ }
+ }
+
+ if (but_pressed) {
+ t_lc = Event.xbutton.time;
+ x_lc = Event.xbutton.x;
+ y_lc = Event.xbutton.y;
+ but_clicked = TRUE;
+ but_pressed = FALSE;
+ }
+ }
+ break;
+ case 2: {
+ if (but_clicked) {
+ but_pressed = FALSE;
+ but_clicked = FALSE;
+
+ if (((Event.xbutton.time - t_lc) <= 500) && (abs(Event.xbutton.x - x_lc) <= 10) && (abs(Event.xbutton.y - y_lc) <= 10) )
+ {
+ if ((ntfb_status == SETON) || (ntfb_status == SETUNE)) {
+ DoFullScreen();
+ }
+ }
+ }
+
+ if (but_pressed) {
+ t_lc = Event.xbutton.time;
+ x_lc = Event.xbutton.x;
+ y_lc = Event.xbutton.y;
+ but_clicked = TRUE;
+ but_pressed = FALSE;
+ }
+ }
+ break;
+ case 3:
+ break;
+ }
+ break;
+ }
+ RedrawWindow();
+ break;
+ case VisibilityNotify:
+ switch(Event.xvisibility.state) {
+ case VisibilityFullyObscured:
+ ccapt = 0;
+ if (tfd && (ntfb_status != SETOFF) && !fmode) {
+ if (ioctl(tfd, VIDIOCCAPTURE, &ccapt) < 0) {
+ perror("ioctl VIDIOCCAPTURE");
+ }
+ }
+ break;
+ case VisibilityPartiallyObscured:
+ ccapt = 0;
+ if (tfd && (ntfb_status != SETOFF) && !fmode) {
+ if (ioctl(tfd, VIDIOCCAPTURE, &ccapt) < 0) {
+ perror("ioctl VIDIOCCAPTURE");
+ }
+ }
+ break;
+ case VisibilityUnobscured:
+ ccapt = 1;
+ if (tfd && (ntfb_status != SETOFF) && !fmode) {
+ if (ioctl(tfd, VIDIOCCAPTURE, &ccapt) < 0) {
+ perror("ioctl VIDIOCCAPTURE");
+ }
+ }
+ break;
+ }
+ RedrawWindow();
+ break;
+ case KeyPress:
+ if ((Event.xany.window == fmwin) && fmode) {
+ switch(XKeycodeToKeysym(display, Event.xkey.keycode, 0)) {
+ case XK_Up:
+ if (isource == TELEVISION)
+ ChanUp();
+ break;
+ case XK_Down:
+ if (isource == TELEVISION)
+ ChanDown();
+ break;
+ case XK_Right:
+ if (isource == TELEVISION)
+ FineTuneUp();
+ break;
+ case XK_Left:
+ if (isource == TELEVISION)
+ FineTuneDown();
+ break;
+ case XK_m:
+ if (!mute) {
+ MuteAudio();
+ }
+ else {
+ UnMuteAudio();
+ }
+ break;
+ case XK_Escape:
+ RetScreen();
+ break;
+ default:
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ XFlush(display);
+ }
+ usleep(50000L);
+ }
+ return(0);
+}
+
+
+/* ButtonDown function */
+void
+ButtonDown(int button)
+{
+ switch (button) {
+ case NTFB:
+ copyXPMArea(79, 100, 12, 11, 47, 48);
+ RedrawWindowXYWH (47, 48, 12, 11);
+ break;
+ case SCANLB:
+ copyXPMArea(55, 100, 12, 11, 23, 48);
+ RedrawWindowXYWH(35, 48, 12, 11);
+ break;
+ case SCANRB:
+ copyXPMArea(67, 100, 12, 11, 35, 48);
+ RedrawWindowXYWH(35, 48, 12, 11);
+ break;
+ case FULLSB:
+ break;
+ }
+}
+
+
+/* ButtonUp function */
+void
+ButtonUp(int button)
+{
+ switch (button) {
+ case NTFB:
+ copyXPMArea(79, 88, 12, 11, 47, 48);
+ RedrawWindowXYWH(47, 48, 12, 11);
+ break;
+ case SCANLB:
+ copyXPMArea(55, 88, 12, 11, 23, 48);
+ RedrawWindowXYWH(23, 48, 12, 11);
+ break;
+ case SCANRB:
+ copyXPMArea(67, 88, 12, 11, 35, 48);
+ RedrawWindowXYWH(35, 48, 12, 11);
+ break;
+ case FULLSB:
+ break;
+ }
+}
+
+
+/* TVOn function */
+void
+TVOn(void)
+{
+ int i;
+ Window junkwin;
+ int rx, ry;
+ char *p;
+
+
+ XWindowAttributes winattr;
+
+ if (!XGetWindowAttributes (display, iconwin, &winattr)) {
+ fprintf(stderr, "wmtv: error getting winattr of iconwin\n");
+ }
+
+ if (!XTranslateCoordinates(display, iconwin, winattr.root,
+ -winattr.border_width,
+ -winattr.border_width,
+ &rx, &ry, &junkwin)) {
+ fprintf(stderr, "wmtv: error translating coordinates\n");
+ }
+
+ InitConfig();
+ GetFrameBuffer();
+ InitPalette();
+
+ ccapt = 1;
+
+ vwin.x = rx;
+ vwin.y = ry + 5;
+
+ vwin.width = 64;
+ vwin.height = 39;
+
+ vclip[0].x = 0; /* Clipping Rect 1 */
+ vclip[0].y = 0;
+ vclip[0].width = 5;
+ vclip[0].height = 39;
+ vclip[1].x = 59; /* Clipping Rect 2 */
+ vclip[1].y = 0;
+ vclip[1].width = 5;
+ vclip[1].height = 39;
+
+ vwin.clips = vclip;
+ vwin.clipcount = 2;
+
+ vchn.channel = tvsource;
+ vaud.audio = tvsource;
+
+ if (source) {
+ p = source;
+ if (*p == 'T')
+ isource = TELEVISION;
+ else if (*p == 'C') {
+ isource = COMPOSITE;
+ while (isalpha(*p))
+ ++p;
+ compchannel = atoi(p);
+ }
+ else if (*p == 'S')
+ isource = SVIDEO;
+ }
+
+ if (!cnotune) {
+ if (ioctl(tfd, VIDIOCGTUNER, &vtun) < 0)
+ perror("ioctl VIDIOCGTUNER");
+ if (vtun.flags & VIDEO_TUNER_LOW)
+ st = 16000;
+ else
+ st = 16;
+ }
+
+ if (ioctl(tfd, VIDIOCGCHAN, &vchn) < 0)
+ perror("ioctl VIDIOCGCHAN");
+
+ if (vchn.flags & VIDEO_VC_AUDIO) {
+ if (ioctl(tfd, VIDIOCGAUDIO, &vaud) < 0)
+ perror("ioctl VIDIOCGAUDIO");
+ }
+
+ if (vaud.flags & VIDEO_AUDIO_MUTE) {
+ vaud.flags &= ~VIDEO_AUDIO_MUTE; /* Unmute */
+ vaud.volume = (0xFFFF/2)+1;
+ }
+
+ if (isource == TELEVISION) {
+ for (i=0; i < CHAN_ENTRIES; i++) {
+ if (!strcmp(cname[cchannel], tvtuner[i].name)) {
+ rfreq = ((tvtuner[i].freq[freqnorm] / 1000) * st) + ftune[cchannel];
+ ccrfreq = rfreq - ftune[cchannel];
+ break;
+ }
+ }
+ DrawPresetChan(cchannel);
+ }
+ else if (isource == COMPOSITE) {
+ DrawPresetChan(compchannel);
+ }
+ else if (isource == SVIDEO) {
+ DrawPresetChan(-1);
+ }
+
+ if (vchn.flags & VIDEO_VC_AUDIO) {
+ if (ioctl(tfd, VIDIOCSAUDIO, &vaud) < 0)
+ perror("ioctl VIDIOCSAUDIO");
+
+ }
+
+ if (ioctl(tfd, VIDIOCSCHAN, &vchn) < 0)
+ perror("ioctl VIDIOCSCHAN");
+
+ if (!cnotune) {
+ if (ioctl(tfd, VIDIOCSFREQ, &rfreq) < 0)
+ perror("ioctl VIDIOCSFREQ");
+ }
+
+ if (ioctl(tfd, VIDIOCSWIN, &vwin) < 0)
+ perror("ioctl VIDIOCSWIN");
+
+ if (ioctl(tfd, VIDIOCCAPTURE, &ccapt) < 0)
+ perror("ioctl VIDIOCCAPTURE");
+}
+
+
+/* TVOff function */
+void
+TVOff(void)
+{
+ ccapt = 0;
+
+ if (ioctl(tfd, VIDIOCCAPTURE, &ccapt) < 0)
+ perror("ioctl VIDIOCCAPTURE");
+
+ vaud.audio = tvsource;
+ vaud.volume = 0;
+ vaud.flags |= VIDEO_AUDIO_MUTE;
+
+ if (vchn.flags & VIDEO_VC_AUDIO) {
+ if (ioctl(tfd, VIDIOCSAUDIO, &vaud) < 0)
+ perror("ioctl VIDIOCSAUDIO");
+ }
+
+ close(tfd);
+ copyXPMArea(66, 79, 11, 7, 6, 50);
+ RedrawWindowXYWH(6, 50, 11, 7);
+}
+
+
+/* VolumeUp function */
+void
+VolumeUp(void)
+{
+ if(vchn.flags & VIDEO_VC_AUDIO) {
+ if (vaud.volume <= 0xFFFF) {
+ vaud.audio = tvsource;
+ vaud.volume += (0xFFFF/10);
+ if (ioctl(tfd, VIDIOCSAUDIO, &vaud) < 0)
+ perror("ioctl VIDIOCSAUDIO");
+ }
+ }
+
+}
+
+/* VoumeDown function */
+void
+VolumeDown(void)
+{
+ if (vchn.flags & VIDEO_VC_AUDIO) {
+ if (vaud.volume > 0) {
+ vaud.audio = tvsource;
+ vaud.volume -= (0xFFFF/10);
+ if (ioctl(tfd, VIDIOCSAUDIO, &vaud) < 0)
+ perror("ioctl VIDIOCSAUDIO");
+ }
+ }
+}
+
+/* MuteAudio function */
+void
+MuteAudio(void)
+{
+ if (vchn.flags & VIDEO_VC_AUDIO) {
+ vaud.audio = tvsource;
+ // vaud.volume = 0;
+ vaud.flags |= VIDEO_AUDIO_MUTE;
+ if (ioctl(tfd, VIDIOCSAUDIO, &vaud) < 0)
+ perror("ioctl VIDIOCSAUDIO");
+ }
+ mute = TRUE;
+}
+
+
+/* UnMuteAudio function */
+void
+UnMuteAudio(void)
+{
+ if ((vchn.flags & VIDEO_VC_AUDIO) && (vaud.flags & VIDEO_AUDIO_MUTE)) {
+ vaud.audio = tvsource;
+ // vaud.volume = (0xFFFF/2)+1;
+ vaud.flags &= ~VIDEO_AUDIO_MUTE;
+ if (ioctl(tfd, VIDIOCSAUDIO, &vaud) < 0)
+ perror("ioctl VIDIOCSAUDIO");
+ }
+ mute = FALSE;
+}
+
+
+/* ScanUp function */
+void
+ScanUp(void)
+{
+ rfreq += 2;
+ usleep(50000L);
+ if (ioctl(tfd, VIDIOCSFREQ, &rfreq) < 0) {
+ perror("ioctl VIDIOCSFREQ");
+ }
+ usleep(10000L);
+ vtun.tuner = 0;
+ if (ioctl(tfd, VIDIOCGTUNER, &vtun) < 0) {
+ perror("ioctl VIDIOCGTUNER");
+ }
+ if (vtun.signal == 0xFFFF) {
+ timebutton = 0;
+ }
+
+}
+
+
+/* ScanDown function */
+void
+ScanDown(void)
+{
+ rfreq -= 2;
+ usleep(50000L);
+ if (ioctl(tfd, VIDIOCSFREQ, &rfreq) < 0) {
+ perror("ioctl VIDIOCSFREQ");
+ }
+ usleep(10000L);
+ vtun.tuner = 0;
+ if (ioctl(tfd, VIDIOCGTUNER, &vtun) < 0) {
+ perror("ioctl VIDIOCGTUNER");
+ }
+ if (vtun.signal == 0xFFFF) {
+ timebutton = 0;
+ }
+}
+
+
+/* FineTuneUp function */
+void
+FineTuneUp(void)
+{
+ rfreq += 1;
+ if (ioctl(tfd, VIDIOCSFREQ, &rfreq) < 0) {
+ perror("ioctl VIDIOCSFREQ");
+ }
+}
+
+
+/* FineTuneDown function */
+void
+FineTuneDown(void)
+{
+ rfreq -= 1;
+ if (ioctl(tfd, VIDIOCSFREQ, &rfreq) < 0) {
+ perror("ioctl VIDIOCSFREQ");
+ }
+}
+
+
+/* ChanUp function */
+void
+ChanUp(void)
+{
+ int i;
+ if (cchannel != maxpst)
+ ++cchannel;
+ for (i=0; i < CHAN_ENTRIES; i++) {
+ if (!strcmp(cname[cchannel], tvtuner[i].name)) {
+ rfreq = ((tvtuner[i].freq[freqnorm] / 1000) * st) + ftune[cchannel];
+ ccrfreq = rfreq - ftune[cchannel];
+ break;
+ }
+ }
+
+ DrawPresetChan(cchannel);
+ if (ioctl(tfd, VIDIOCSFREQ, &rfreq) < 0)
+ perror("ioctl VIDIOCSFREQ");
+}
+
+
+/* ChanDown function */
+void
+ChanDown(void)
+{
+ int i;
+ if (cchannel != 0)
+ --cchannel;
+ for (i=0; i < CHAN_ENTRIES; i++) {
+ if (!strcmp(cname[cchannel], tvtuner[i].name)) {
+ rfreq = ((tvtuner[i].freq[freqnorm] / 1000) * st) + ftune[cchannel];
+ ccrfreq = rfreq - ftune[cchannel];
+ break;
+ }
+ }
+
+ DrawPresetChan(cchannel);
+ if (ioctl(tfd, VIDIOCSFREQ, &rfreq) < 0)
+ perror("ioctl VIDIOCSFREQ");
+}
+
+
+/* DrawPresetChan function */
+void
+DrawPresetChan(int cchannel)
+{
+ char temp[10];
+ char *p = temp;
+ int j=0;
+ int k=6;
+
+ if (isource == TELEVISION) {
+ sprintf(temp, "%02d", cchannel);
+
+ if (*p == '0') {
+ copyXPMArea(66, 79, 5, 7, k, 50);
+ k += 6;
+ j++;
+ p++;
+ }
+ while (j < 2) {
+ copyXPMArea((*p-'0')*6 + 1, 79, 5, 7, k, 50);
+ k += 6;
+ p++;
+ j++;
+ }
+ }
+
+ else if (isource == COMPOSITE) {
+ copyXPMArea (109, 79, 5, 7, 6, 50);
+ copyXPMArea ((compchannel*6) + 1, 79, 5, 7, 12, 50);
+ }
+
+ else if (isource == SVIDEO) {
+ copyXPMArea(116, 79, 11, 7, 6, 50);
+ }
+
+ RedrawWindowXYWH(6, 50, 11, 7);
+}
+
+
+/* ParseRCFile function */
+void
+ParseRCFile(const char *filename, rckeys *keys)
+{
+ char *p,*q;
+ char temp[128];
+ char *tokens = " =\t\n";
+ FILE *fp;
+ int key = 0;
+
+ if ((fp = fopen(filename, "r")) == NULL) {
+ fprintf(stderr, "wmtv: %s\n", strerror(errno));
+ norcfile = 1;
+ return;
+ }
+ norcfile = 0;
+ while (fgets(temp, 128, fp)) {
+ key = 0;
+ q = strdup(temp);
+ if (*q != '\n') {
+ q = strtok(q, tokens);
+ while (key >= 0 && keys[key].label) {
+ if ((!strcmp(q, keys[key].label))) {
+ p = strtok(NULL, tokens);
+ free(*keys[key].var);
+ *keys[key].var = strdup(p);
+ key = -1;
+ } else key++;
+ }
+ }
+ free(q);
+ }
+ fclose(fp);
+}
+
+
+/* ParseRCFile2 function */
+void
+ParseRCFile2(const char *filename)
+{
+ int menu = FALSE;
+ char temp[128];
+ char tp[10];
+ char *tokens = " \t\n()";
+ char *q, *p;
+ FILE *fp;
+ int i = 0;
+
+ if ((fp = fopen(filename, "r")) == NULL) {
+ fprintf(stderr, "wmtv: %s\n", strerror(errno));
+ norcfile = 1;
+ return;
+ }
+ norcfile = 0;
+ while (fgets(temp, 128, fp)) {
+ q = strdup(temp);
+ if (*q != '\n') {
+ q = strtok(q, tokens);
+ if (menu) {
+ cname[i] = (char *)malloc(sizeof(q));
+ strncpy(cname[i], q, sizeof(q));
+ p = q;
+ p = strtok(NULL, tokens);
+ if (p != NULL) {
+ if (*p == '-') {
+ p++;
+ ftune[i] = -1*atoi(p);
+ }
+ else if (*p == '+') {
+ p++;
+ ftune[i] = atoi(p);
+ }
+ else {
+ ftune[i] = atoi(p);
+ }
+ }
+ else {
+ ftune[i] = 0;
+ }
+ wcname[i] = (char *)malloc(sizeof(cname[i])+sizeof(p));
+ wcname[i] = strdup(cname[i]);
+ sprintf(tp, " (%d) ", ftune[i]);
+ strcat(wcname[i], tp);
+ i++;
+ tpst = i;
+ }
+ if ((q = strchr(q, '[')) != NULL) {
+ menu = TRUE;
+ }
+ }
+ }
+ fclose(fp);
+}
+
+
+/* WriteRCFile function */
+void
+WriteRCFile(const char *filename)
+{
+ int i;
+ char temp[128];
+ char tp[10];
+ char *tokens = " \t\n()";
+ char *q;
+ FILE *fp;
+
+ if ((fp = fopen(filename, "r+")) == NULL) {
+ fprintf(stderr, "wmtv: %s\n", strerror(errno));
+ return;
+ }
+
+
+ while (fgets(temp, 128, fp)) {
+ q = strdup(temp);
+ if (*q != '\n') {
+ q = strtok(temp, tokens);
+ if ((q = strchr(q, '[')) != NULL) {
+ for (i = 0; i <= maxpst; i++) {
+ // fprintf(stderr, "offset is %ld\n", offset);
+ sprintf(tp, " (%ld) ", offset);
+ strtok(wcname[cchannel], tokens);
+ strcat(wcname[cchannel], tp);
+ fputs(wcname[i], fp);
+ fputs("\n", fp);
+ }
+ }
+ }
+ }
+ fclose(fp);
+}
+
+
+/* InitPalette function */
+void
+InitPalette(void)
+{
+ if (ioctl(tfd, VIDIOCGFBUF, &vfb) < 0) {
+ perror ("ioctl VIDIOCGFBUF");
+ exit(-1);
+ }
+ if (vfb.base == NULL) {
+ fprintf(stderr, "wmtv: no physical frame buffer access\n");
+ exit(1);
+ }
+
+
+ if (ioctl(tfd, VIDIOCGPICT, &vpic) < 0) {
+ perror("ioctl VIDIOCGPICT");
+ }
+ vpic.depth = vfb.depth;
+ switch(vpic.depth) {
+ case 8:
+ vpic.palette = VIDEO_PALETTE_HI240;
+ break;
+ case 15:
+ vpic.palette = VIDEO_PALETTE_RGB555;
+ break;
+ case 16:
+ vpic.palette = VIDEO_PALETTE_RGB565;
+ break;
+ case 24:
+ vpic.palette = VIDEO_PALETTE_RGB24;
+ break;
+ case 32:
+ vpic.palette = VIDEO_PALETTE_RGB32;
+ break;
+ default:
+ fprintf(stderr, "wmtv: unsupported depth %d\n", vpic.depth);
+ exit(-1);
+ }
+ if (ioctl(tfd, VIDIOCSPICT, &vpic) < 0) {
+ perror("ioctl VIDIOCSPICT");
+ }
+}
+/* InitConfig function */
+void
+InitConfig(void)
+{
+ int i;
+ char temp[128];
+
+ strcpy(temp, "/etc/wmtvrc");
+ ParseRCFile(temp, wmtv_keys);
+ ParseRCFile2(temp);
+
+ strncpy(temp, (char *)getenv("HOME"), (sizeof(char)*128));
+ strcat(temp, "/.wmtvrc");
+ ParseRCFile(temp, wmtv_keys);
+ ParseRCFile2(temp);
+
+ if (norcfile) {
+ fprintf(stderr, "wmtv: error - config file not found\n");
+ exit(1);
+ }
+
+ if (maxpreset != NULL)
+ maxpst = atoi(maxpreset) - 1;
+ else
+ maxpst = 1;
+
+ if ((tpst) != atoi(maxpreset)) {
+ fprintf(stderr, "wmtv: error - maxpreset value does not match total channel value\n");
+ exit(1);
+ }
+ if ((tfd = open(dev, O_RDWR)) < 0) {
+ perror("open failed");
+ }
+ card_present = TRUE;
+
+ if (norm)
+ for (i=0; i < CHAN_NAMES; i++) {
+ if (!strcmp(chan_names[i].cname, norm)) {
+ freqnorm = chan_names[i].cind;
+ }
+ }
+
+ if (freqnorm == -1) {
+ fprintf(stderr, "wmtv: error - set freqnorm in config file\n");
+ exit(1);
+ }
+
+ if (ioctl(tfd, VIDIOCGCAP, &vcap) < 0) {
+ perror("ioctl VIDIOCGCAP");
+ }
+
+ if (!(vcap.type & VID_TYPE_SCALES)) {
+ fprintf(stderr, "%s: video device does not support scalling\n", progname);
+ exit(1);
+ }
+ if (!(vcap.type & VID_TYPE_CLIPPING)) {
+ fprintf(stderr, "%s: video device does not support clipping\n", progname);
+ }
+
+ if (fullscreen) {
+ fswidth = atoi(strtok(fullscreen, "x\n"));
+ fsheight = atoi(strtok(NULL, "x\n"));
+ }
+ else {
+ fswidth = 640;
+ fsheight = 480;
+ }
+
+ if (source) {
+ for (i=0; i < vcap.channels; i++) {
+ vchn.channel = i;
+ if (ioctl(tfd, VIDIOCGCHAN, &vchn) < 0) {
+ perror("ioctl VIDIOCGCHAN");
+ }
+ if (!strcmp(vchn.name, source)) {
+ if (vchn.tuners)
+ cnotune = 0;
+ else
+ cnotune = 1;
+
+ vsource = 1;
+ tvsource = vchn.channel;
+
+ if ((ioctl(tfd, VIDIOCSCHAN, &vchn)) < 0)
+ perror("ioctl VIDIOCSCHAN");
+ }
+ }
+ if (!vsource)
+ fprintf(stderr, "wmtv: invalid source in config file\n");
+ }
+
+ if (mode) {
+ if (!cnotune) {
+ vtun.tuner = 0;
+ if (ioctl(tfd, VIDIOCGTUNER, &vtun) < 0) {
+ perror("ioctl VIDIOCGTUNER");
+ }
+
+ if (!strcmp(mode, "pal")) {
+ if (vtun.flags & VIDEO_TUNER_PAL) {
+ vtun.mode = VIDEO_MODE_PAL;
+ if (ioctl(tfd, VIDIOCSTUNER, &vtun) < 0) {
+ perror("ioctl VIDIOCSTUNER");
+ }
+ }
+ }
+ if (!strcmp(mode, "ntsc")) {
+ if (vtun.flags & VIDEO_TUNER_NTSC) {
+ vtun.mode = VIDEO_MODE_NTSC;
+ if (ioctl(tfd, VIDIOCSTUNER, &vtun) < 0) {
+ perror("ioctl VIDIOCSTUNER");
+ }
+ }
+ }
+ if (!strcmp(mode, "secam")) {
+ if (vtun.flags & VIDEO_TUNER_SECAM) {
+ vtun.mode = VIDEO_MODE_SECAM;
+ if (ioctl(tfd, VIDIOCSTUNER, &vtun) < 0) {
+ perror("ioctl VIDIOCSTUNER");
+ }
+ }
+ }
+ }
+ }
+
+ for (i=0; i < vcap.audios; i++) {
+ vaud.audio = i;
+ if (ioctl(tfd, VIDIOCGAUDIO, &vaud) < 0) {
+ perror("ioctl VIDIOCGAUDIO");
+ }
+ if (!(vaud.flags & VIDEO_AUDIO_MUTE)) {
+ vaud.flags |= VIDEO_AUDIO_MUTE;
+ if (ioctl(tfd, VIDIOCSAUDIO, &vaud) < 0) {
+ perror("ioctl VIDIOCSAUDIO");
+ }
+ }
+ }
+
+ if (ioctl(tfd, VIDIOCGFBUF, &vfb) < 0) {
+ perror("ioctl VIDIOCGFBUF");
+ }
+}
+
+/* GetFrameBuffer function */
+void
+GetFrameBuffer(void)
+{
+ void *baseaddr = NULL;
+ int evbr, erbr, flr = 0;
+ int bankr, memr, depth;
+ int i, n;
+ int bytesperline, bitsperpixel;
+ XPixmapFormatValues *pf;
+
+ if (!XGetWindowAttributes(display, DefaultRootWindow(display), &Winattr)) {
+ fprintf(stderr, "wmtv: error getting winattr of root\n");
+ }
+
+ depth = Winattr.depth;
+
+ if (XF86DGAQueryExtension(display, &evbr, &erbr)) {
+ XF86DGAQueryDirectVideo(display, XDefaultScreen(display), &flr);
+ if (flr & XF86DGADirectPresent) {
+ XF86DGAGetVideoLL(display, XDefaultScreen(display),
+ (int *) &baseaddr, &bytesperline, &bankr, &memr);
+ }
+ }
+ else {
+ fprintf(stderr, "wmtv: error - XF86DGA Extensions not available\n");
+ exit(1);
+ }
+
+
+ pf = XListPixmapFormats(display, &n);
+ for (i=0; i < n; i++) {
+ if (pf[i].depth == depth) {
+ depth = pf[i].bits_per_pixel;
+ break;
+ }
+ }
+
+ bitsperpixel = (depth+7) & 0xf8; /* Taken from */
+ bytesperline = Winattr.width * bitsperpixel / 8; /* Gerd Knorr's xawtv */
+
+ vfb.base = baseaddr;
+ vfb.height = Winattr.height;
+ vfb.width = Winattr.width;
+ vfb.depth = bitsperpixel;
+ vfb.bytesperline = bytesperline;
+
+ if (Winattr.depth == 15)
+ vfb.depth = 15;
+
+ if (ioctl(tfd, VIDIOCSFBUF, &vfb) < 0) {
+ perror("ioctl VIDIOCSFBUF");
+ }
+}
+
+
+/* DoFullScreen function */
+void
+DoFullScreen(void)
+{
+ int i;
+ int evbr, erbr = 0;
+ int rx, ry;
+ unsigned long back_pix, fore_pix;
+ unsigned int borderwidth = 0;
+
+ Window junkwin;
+ XSizeHints fmsizehints;
+ XWMHints fmxwmhints;
+ XGCValues gcv;
+ unsigned long gcm;
+ unsigned long valuemask;
+
+ XSetWindowAttributes fmWinattr;
+ XWindowAttributes fmwinattr;
+
+
+ ccapt = 0;
+ if (ioctl (tfd, VIDIOCCAPTURE, &ccapt) < 0) {
+ perror("ioctl VIDIOCCAPTURE");
+ }
+
+ fmsizehints.x = 0;
+ fmsizehints.y = 0;
+ fmsizehints.width = fswidth;
+ fmsizehints.height = fsheight;
+ fmsizehints.max_width = vcap.maxwidth;
+ fmsizehints.max_height = vcap.maxheight;
+ fmsizehints.min_width = fswidth;
+ fmsizehints.min_height = fsheight;
+ fmsizehints.flags = (USPosition | USSize | PSize | PMinSize | PMaxSize);
+
+ valuemask = 0;
+
+ back_pix = WhitePixel(display, DefaultScreen(display));
+ fore_pix = BlackPixel(display, DefaultScreen(display));
+
+ fmwin = XCreateWindow(display, DefaultRootWindow(display), fmsizehints.x,
+ fmsizehints.y, fmsizehints.width, fmsizehints.height,
+ borderwidth, CopyFromParent, InputOutput,
+ CopyFromParent, valuemask, &fmWinattr);
+
+
+ XSetWMNormalHints(display, fmwin, &fmsizehints);
+
+ gcm = (GCForeground | GCBackground | GCGraphicsExposures);
+ gcv.foreground = fore_pix;
+ gcv.background = back_pix;
+ gcv.graphics_exposures = 0;
+
+ fmGC = XCreateGC(display, DefaultRootWindow(display), gcm, &gcv);
+
+ XSelectInput(display, fmwin, ButtonPressMask | ExposureMask |
+ ButtonReleaseMask | PointerMotionMask |
+ StructureNotifyMask | VisibilityChangeMask | KeyPressMask );
+
+ fmxwmhints.flags = StateHint;
+ fmxwmhints.initial_state = NormalState;
+
+ XSetWMHints(display, fmwin, &fmxwmhints);
+
+
+ if (XF86VidModeQueryExtension(display, &evbr, &erbr)) {
+ vidmode = TRUE;
+ }
+ else {
+ fprintf(stderr, "wmtv: xf86mode extension not present\n");
+ fprintf(stderr, " switch disabled\n");
+ }
+
+
+ XMapWindow(display, fmwin);
+
+ usleep(50000L);
+ if (!XGetWindowAttributes(display, fmwin, &fmwinattr)) {
+ fprintf(stderr, "wmtv: error getting winattr of fmwin\n");
+ }
+
+ usleep(50000L);
+ if (!XTranslateCoordinates(display, fmwin, DefaultRootWindow(display),
+ -fmwinattr.border_width,
+ -fmwinattr.border_width,
+ &rx, &ry, &junkwin)) {
+ fprintf(stderr, "wmtv: error translating coordinates for fmwin");
+ }
+
+ vswin.width = fswidth;
+ vswin.height = fsheight;
+ vswin.x = fmsizehints.x + rx;
+ vswin.y = fmsizehints.y + ry;
+ vswin.clipcount = 0;
+
+ if (ioctl(tfd, VIDIOCSWIN, &vswin) < 0) {
+ perror("ioctl VIDIOCSWIN");
+ }
+
+ ccapt = 1;
+ if (ioctl(tfd, VIDIOCCAPTURE, &ccapt) < 0) {
+ perror("ioctl VIDIOCCAPTURE");
+ }
+ fmode = TRUE;
+
+ if (vidmode) {
+ XF86VidModeGetModeLine(display, XDefaultScreen(display), &dcret, &scmode);
+ XF86VidModeGetAllModeLines(display, XDefaultScreen(display), &tml, &modelines);
+
+ for (i=0; i < tml; i++) {
+ if ((modelines[i]->hdisplay == fswidth) &&
+ (modelines[i]->vdisplay == fsheight)) {
+ fullscreenmode = modelines[i];
+ mode_present = TRUE;
+ break;
+ }
+ }
+
+ if (!mode_present) {
+ fprintf(stderr, "wmtv: mode line for resolution %d x %d not found\n", vcap.maxwidth, vcap.maxheight);
+ }
+
+ XRaiseWindow(display, fmwin);
+ if (mode_present) {
+
+ XF86VidModeSwitchToMode(display, XDefaultScreen(display), fullscreenmode);
+ XF86VidModeSetViewPort(display, XDefaultScreen(display), vswin.x, vswin.y);
+ XGrabPointer(display, fmwin, True, 0, GrabModeAsync, GrabModeAsync,
+ fmwin, None, CurrentTime);
+ }
+ }
+}
+
+
+/* RetScreen function */
+void
+RetScreen()
+{
+ int i;
+ XF86VidModeModeInfo *scm = NULL;
+
+ ccapt = 0;
+ if (ioctl(tfd, VIDIOCCAPTURE, &ccapt)) {
+ perror("ioctl VIDIOCCAPTURE");
+ }
+
+ if (mode_present) {
+ for (i = 0; i < tml; i++) {
+ if ((modelines[i]->hdisplay == Winattr.width) &&
+ (modelines[i]->vdisplay==Winattr.height))
+ scm = modelines[i];
+ }
+
+ scm->dotclock = dcret;
+ scm->hdisplay = scmode.hdisplay;
+ scm->hsyncstart = scmode.hsyncstart;
+ scm->hsyncend = scmode.hsyncend;
+ scm->htotal = scmode.htotal;
+ scm->vdisplay = scmode.vdisplay;
+ scm->vsyncstart = scmode.vsyncstart;
+ scm->vsyncend = scmode.vsyncend;
+ scm->vtotal = scmode.vtotal;
+ scm->flags = scmode.flags;
+ /*
+ scm->privsize = scmode.privsize;
+ scm->private = scmode.private;
+ */
+
+ XClearWindow(display, fmwin);
+ XFreeGC(display, fmGC);
+ XMapRaised(display, fmwin);
+ XUnmapWindow(display, fmwin);
+ XUngrabPointer(display, CurrentTime);
+ }
+ else {
+ XClearWindow(display, fmwin);
+ XFreeGC(display, fmGC);
+ XMapRaised(display, fmwin);
+ XUnmapWindow(display, fmwin);
+ }
+
+ if (vidmode && mode_present) {
+ XF86VidModeSwitchToMode(display, XDefaultScreen(display), scm);
+ vidmode = FALSE;
+ }
+ fmode = FALSE;
+ mode_present = FALSE;
+
+ ccapt = 1;
+ if (ioctl(tfd, VIDIOCSWIN, &vwin) < 0) {
+ perror("ioctl VIDIOCSWIN");
+ }
+
+ if (ioctl(tfd, VIDIOCCAPTURE, &ccapt) < 0) {
+ perror("ioctl VIDIOCCAPTURE");
+ }
+ RedrawWindow();
+}
+
+/* GrabImage function */
+void
+GrabImage(void)
+{
+}
+
+/* Usage function */
+void
+Usage(void)
+{
+ fprintf(stderr, "\n");
+ fprintf(stderr, "wmtv v%s, Copyright (c) 1999 Wee Liang <wliang at tartarus.uwa.edu.au>\n", VERSION);
+ fprintf(stderr, "usage: wmtv [%s]\n", OPTIONS);
+ fprintf(stderr, " -d, --display <host:vs>\tsets display name\n");
+ fprintf(stderr, " -g, --geometry <{+-}XP{+-}YP>\tsets geometry\n");
+ fprintf(stderr, " -b, --bpp\t\t\tdisplay color depth\n");
+ fprintf(stderr, " -e, --exe <filename>\t\tprogram to execute\n");
+ fprintf(stderr, " -v, --version\t\t\tprints version information\n");
+ fprintf(stderr, " -h, --help\t\t\tprints this message\n");
+ fprintf(stderr, "\n");
+}
+
+
+/* Version function */
+void
+Version(void)
+{
+ fprintf(stderr, "wmtv version %s\n", VERSION);
+}
diff --git a/wmtvrc.sample b/wmtvrc.sample
new file mode 100644
index 0000000..ab1d582
--- /dev/null
+++ b/wmtvrc.sample
@@ -0,0 +1,13 @@
+source = Television
+freqnorm = pal-australia
+maxpreset = 7
+mode = pal
+
+[channel]
+2
+7
+9
+10
+32
+S21
+SE11
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-wmaker/wmtv.git
More information about the Pkg-wmaker-commits
mailing list